chatroom-cli 1.97.4 → 1.97.5

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/index.js CHANGED
@@ -31426,6 +31426,7 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31426
31426
  init_native_stream_adapter_base();
31427
31427
  CursorSdkStreamAdapter = class CursorSdkStreamAdapter extends NativeStreamAdapterBase {
31428
31428
  textBuffer = "";
31429
+ sawTextDelta = false;
31429
31430
  handleMessage(message) {
31430
31431
  this.notifyOutput();
31431
31432
  switch (message.type) {
@@ -31477,6 +31478,7 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31477
31478
  this.notifyOutput();
31478
31479
  switch (update5.type) {
31479
31480
  case "text-delta":
31481
+ this.sawTextDelta = true;
31480
31482
  this.appendAssistantText(update5.text);
31481
31483
  break;
31482
31484
  case "thinking-delta":
@@ -31514,10 +31516,11 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31514
31516
  finish() {
31515
31517
  this.flushText();
31516
31518
  this.emitAgentEnd();
31519
+ this.sawTextDelta = false;
31517
31520
  }
31518
31521
  handleAssistant(message) {
31519
31522
  for (const block of message.message.content) {
31520
- if (block.type === "text") {
31523
+ if (block.type === "text" && !this.sawTextDelta) {
31521
31524
  this.appendAssistantText(block.text);
31522
31525
  }
31523
31526
  }
@@ -31533,6 +31536,7 @@ var init_cursor_sdk_stream_adapter = __esm(() => {
31533
31536
  const nested2 = update5.taskUpdate;
31534
31537
  switch (nested2.type) {
31535
31538
  case "text-delta":
31539
+ this.sawTextDelta = true;
31536
31540
  this.appendAssistantText(nested2.text);
31537
31541
  break;
31538
31542
  case "tool-call-started":
@@ -99899,9 +99903,126 @@ var init_state_recovery = __esm(() => {
99899
99903
  });
99900
99904
  });
99901
99905
 
99906
+ // src/commands/machine/daemon-process-scan.ts
99907
+ import { execFileSync } from "node:child_process";
99908
+ import { existsSync as existsSync7, readFileSync as readFileSync9 } from "node:fs";
99909
+ function commandLooksLikeDaemonStart(command) {
99910
+ return command.includes(DAEMON_START_ARGV);
99911
+ }
99912
+ function envBlobMatchesConvexUrl(envBlob, convexUrl) {
99913
+ const assigned = envBlob.split(/\0|\s+/).find((token) => token.startsWith("CHATROOM_CONVEX_URL="));
99914
+ if (assigned !== undefined) {
99915
+ return assigned.slice("CHATROOM_CONVEX_URL=".length) === convexUrl;
99916
+ }
99917
+ return convexUrl === CONVEX_URL;
99918
+ }
99919
+ function parsePidCommandLine(line) {
99920
+ const trimmed = line.trim();
99921
+ if (!trimmed)
99922
+ return null;
99923
+ const splitAt2 = trimmed.search(/\s+/);
99924
+ if (splitAt2 <= 0)
99925
+ return null;
99926
+ const pid = Number.parseInt(trimmed.slice(0, splitAt2), 10);
99927
+ if (!Number.isFinite(pid) || pid <= 0)
99928
+ return null;
99929
+ return { pid, command: trimmed.slice(splitAt2).trim() };
99930
+ }
99931
+ function parsePsPidCommandLines(stdout) {
99932
+ const result = [];
99933
+ for (const line of stdout.split(`
99934
+ `)) {
99935
+ const parsed = parsePidCommandLine(line);
99936
+ if (parsed)
99937
+ result.push(parsed);
99938
+ }
99939
+ return result;
99940
+ }
99941
+ function readPpid(pid) {
99942
+ if (process.platform === "linux") {
99943
+ try {
99944
+ const stat2 = readFileSync9(`/proc/${pid}/stat`, "utf-8");
99945
+ const closeParen = stat2.lastIndexOf(")");
99946
+ const rest = closeParen >= 0 ? stat2.slice(closeParen + 2).split(" ") : stat2.split(" ");
99947
+ const ppid = Number.parseInt(rest[1] ?? "", 10);
99948
+ return Number.isFinite(ppid) && ppid >= 0 ? ppid : null;
99949
+ } catch {
99950
+ return null;
99951
+ }
99952
+ }
99953
+ try {
99954
+ const stdout = execFileSync("ps", ["-p", String(pid), "-o", "ppid="], {
99955
+ encoding: "utf-8",
99956
+ timeout: 2000
99957
+ });
99958
+ const ppid = Number.parseInt(stdout.trim(), 10);
99959
+ return Number.isFinite(ppid) && ppid >= 0 ? ppid : null;
99960
+ } catch {
99961
+ return null;
99962
+ }
99963
+ }
99964
+ function collectAncestorPids(pid = process.pid, ppid = process.ppid) {
99965
+ const skip = new Set([pid, ppid, 0, 1]);
99966
+ let current = ppid;
99967
+ for (let i2 = 0;i2 < 20 && current > 1; i2++) {
99968
+ const parent = readPpid(current);
99969
+ if (parent === null || skip.has(parent))
99970
+ break;
99971
+ skip.add(parent);
99972
+ current = parent;
99973
+ }
99974
+ return skip;
99975
+ }
99976
+ function readProcessEnvBlob(pid) {
99977
+ if (process.platform === "linux" && existsSync7(`/proc/${pid}/environ`)) {
99978
+ try {
99979
+ return readFileSync9(`/proc/${pid}/environ`, "utf-8");
99980
+ } catch {
99981
+ return "";
99982
+ }
99983
+ }
99984
+ try {
99985
+ return execFileSync("ps", ["eww", "-p", String(pid), "-ww", "-o", "command="], {
99986
+ encoding: "utf-8",
99987
+ timeout: 2000
99988
+ });
99989
+ } catch {
99990
+ return "";
99991
+ }
99992
+ }
99993
+ function listDaemonStartProcesses() {
99994
+ if (process.platform === "win32")
99995
+ return [];
99996
+ try {
99997
+ const stdout = execFileSync("ps", ["-axo", "pid=,command="], {
99998
+ encoding: "utf-8",
99999
+ timeout: 5000
100000
+ });
100001
+ return parsePsPidCommandLines(stdout).filter((row) => commandLooksLikeDaemonStart(row.command));
100002
+ } catch {
100003
+ return [];
100004
+ }
100005
+ }
100006
+ function listMatchingDaemonPids(convexUrl = getConvexUrl()) {
100007
+ const protectedPids = collectAncestorPids();
100008
+ const matches = [];
100009
+ for (const row of listDaemonStartProcesses()) {
100010
+ if (protectedPids.has(row.pid))
100011
+ continue;
100012
+ if (!envBlobMatchesConvexUrl(readProcessEnvBlob(row.pid), convexUrl))
100013
+ continue;
100014
+ matches.push(row.pid);
100015
+ }
100016
+ return matches;
100017
+ }
100018
+ var DAEMON_START_ARGV = "machine daemon start";
100019
+ var init_daemon_process_scan = __esm(() => {
100020
+ init_client2();
100021
+ });
100022
+
99902
100023
  // src/commands/machine/pid.ts
99903
100024
  import { createHash as createHash3 } from "node:crypto";
99904
- import { existsSync as existsSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
100025
+ import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
99905
100026
  import { homedir as homedir6 } from "node:os";
99906
100027
  import { join as join19 } from "node:path";
99907
100028
  function getUrlHash2() {
@@ -99912,7 +100033,7 @@ function getPidFileName() {
99912
100033
  return `daemon-${getUrlHash2()}.pid`;
99913
100034
  }
99914
100035
  function ensureChatroomDir3() {
99915
- if (!existsSync7(CHATROOM_DIR4)) {
100036
+ if (!existsSync8(CHATROOM_DIR4)) {
99916
100037
  mkdirSync5(CHATROOM_DIR4, { recursive: true, mode: 448 });
99917
100038
  }
99918
100039
  }
@@ -99929,11 +100050,11 @@ function isProcessRunning(pid) {
99929
100050
  }
99930
100051
  function readPid() {
99931
100052
  const pidPath = getPidFilePath();
99932
- if (!existsSync7(pidPath)) {
100053
+ if (!existsSync8(pidPath)) {
99933
100054
  return null;
99934
100055
  }
99935
100056
  try {
99936
- const content = readFileSync9(pidPath, "utf-8").trim();
100057
+ const content = readFileSync10(pidPath, "utf-8").trim();
99937
100058
  const pid = parseInt(content, 10);
99938
100059
  if (isNaN(pid) || pid <= 0) {
99939
100060
  return null;
@@ -99951,7 +100072,7 @@ function writePid() {
99951
100072
  function removePid() {
99952
100073
  const pidPath = getPidFilePath();
99953
100074
  try {
99954
- if (existsSync7(pidPath)) {
100075
+ if (existsSync8(pidPath)) {
99955
100076
  unlinkSync2(pidPath);
99956
100077
  }
99957
100078
  } catch {}
@@ -99967,6 +100088,47 @@ function isDaemonRunning() {
99967
100088
  removePid();
99968
100089
  return { running: false, pid: null };
99969
100090
  }
100091
+ function defaultSignal(pid, signal) {
100092
+ process.kill(pid, signal);
100093
+ }
100094
+ function uniquePositivePids(pids) {
100095
+ return [...new Set(pids)].filter((pid) => Number.isFinite(pid) && pid > 0);
100096
+ }
100097
+ function signalBestEffort(pid, signal, send) {
100098
+ try {
100099
+ send(pid, signal);
100100
+ } catch {}
100101
+ }
100102
+ async function stopExistingDaemons(options) {
100103
+ const isRunning3 = options?.isRunning ?? isProcessRunning;
100104
+ const send = options?.signal ?? defaultSignal;
100105
+ const sleep7 = options?.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
100106
+ const log4 = options?.log ?? ((message) => console.error(message));
100107
+ const waitMs = options?.waitMs ?? STOP_EXISTING_WAIT_MS;
100108
+ const listPids = options?.listMatchingDaemonPids ?? listMatchingDaemonPids;
100109
+ const pidFilePid = readPid();
100110
+ const targets = uniquePositivePids([
100111
+ ...pidFilePid !== null && isRunning3(pidFilePid) ? [pidFilePid] : [],
100112
+ ...listPids()
100113
+ ]).filter((pid) => pid !== process.pid && pid !== process.ppid);
100114
+ if (targets.length === 0)
100115
+ return [];
100116
+ for (const pid of targets) {
100117
+ log4(`Stopping previous daemon (PID: ${pid})...`);
100118
+ signalBestEffort(pid, "SIGTERM", send);
100119
+ }
100120
+ const deadline = Date.now() + waitMs;
100121
+ let remaining = targets.filter((pid) => isRunning3(pid));
100122
+ while (remaining.length > 0 && Date.now() < deadline) {
100123
+ await sleep7(STOP_EXISTING_POLL_MS);
100124
+ remaining = remaining.filter((pid) => isRunning3(pid));
100125
+ }
100126
+ for (const pid of remaining) {
100127
+ log4(`Process did not exit gracefully, forcing PID ${pid}...`);
100128
+ signalBestEffort(pid, "SIGKILL", send);
100129
+ }
100130
+ return targets;
100131
+ }
99970
100132
  function tryAcquireLock() {
99971
100133
  const { running: running3 } = isDaemonRunning();
99972
100134
  if (running3) {
@@ -100000,6 +100162,13 @@ async function acquireLockWithRetry(options) {
100000
100162
  const intervalMs = options?.intervalMs ?? LOCK_RETRY_INTERVAL_MS;
100001
100163
  const maxWaitMs = options?.maxWaitMs ?? LOCK_RETRY_MAX_WAIT_MS;
100002
100164
  const sleep7 = options?.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
100165
+ await stopExistingDaemons({
100166
+ listMatchingDaemonPids: options?.listMatchingDaemonPids,
100167
+ isRunning: options?.isRunning,
100168
+ signal: options?.signal,
100169
+ sleep: sleep7,
100170
+ waitMs: maxWaitMs
100171
+ });
100003
100172
  const deadline = Date.now() + maxWaitMs;
100004
100173
  if (await waitForLockOrTimeout(deadline, intervalMs, sleep7)) {
100005
100174
  return true;
@@ -100011,8 +100180,9 @@ async function acquireLockWithRetry(options) {
100011
100180
  function releaseLock() {
100012
100181
  removePid();
100013
100182
  }
100014
- var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000;
100183
+ var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000, STOP_EXISTING_WAIT_MS = 8000, STOP_EXISTING_POLL_MS = 100;
100015
100184
  var init_pid = __esm(() => {
100185
+ init_daemon_process_scan();
100016
100186
  init_client2();
100017
100187
  CHATROOM_DIR4 = join19(homedir6(), ".chatroom");
100018
100188
  });
@@ -105777,10 +105947,10 @@ var init_local_actions = __esm(() => {
105777
105947
  });
105778
105948
 
105779
105949
  // src/infrastructure/local-actions/pick-folder.ts
105780
- import { execFileSync } from "node:child_process";
105950
+ import { execFileSync as execFileSync2 } from "node:child_process";
105781
105951
  function runPicker(command, args2) {
105782
105952
  try {
105783
- const path3 = execFileSync(command, args2, { encoding: "utf8", timeout: 300000 }).trim();
105953
+ const path3 = execFileSync2(command, args2, { encoding: "utf8", timeout: 300000 }).trim();
105784
105954
  if (!path3)
105785
105955
  return { success: false, error: "No folder selected" };
105786
105956
  return { success: true, path: path3 };
@@ -109360,10 +109530,12 @@ var init_workspace_visibility_policy = __esm(() => {
109360
109530
  "coverage",
109361
109531
  "__pycache__",
109362
109532
  ".turbo",
109533
+ ".nx",
109363
109534
  ".cache",
109364
109535
  ".tmp",
109365
109536
  "tmp",
109366
109537
  "_generated",
109538
+ ".convex",
109367
109539
  ".vercel"
109368
109540
  ]);
109369
109541
  ALWAYS_EXCLUDE_DIR_NAMES = new Set([...HIDDEN_DIR_NAMES, ...SHALLOW_SYNC_DIR_NAMES]);
@@ -110250,7 +110422,7 @@ var init_file_tree_scanner = __esm(() => {
110250
110422
  });
110251
110423
 
110252
110424
  // src/infrastructure/services/workspace/git-workspace-porcelain.ts
110253
- import { existsSync as existsSync8 } from "node:fs";
110425
+ import { existsSync as existsSync9 } from "node:fs";
110254
110426
  import path4 from "node:path";
110255
110427
  function isEmptyRepoHeadError(error51) {
110256
110428
  const message = error51.message.toLowerCase();
@@ -110426,7 +110598,7 @@ function porcelainPathsLeftSnapshot(args2) {
110426
110598
  return left3.sort((a, b) => a.localeCompare(b));
110427
110599
  }
110428
110600
  function porcelainUntrackedDeletedEvents(args2) {
110429
- const exists3 = args2.pathExists ?? ((p) => existsSync8(p));
110601
+ const exists3 = args2.pathExists ?? ((p) => existsSync9(p));
110430
110602
  const left3 = porcelainPathsLeftSnapshot({
110431
110603
  workspaceRoot: args2.workspaceRoot,
110432
110604
  node: args2.node,
@@ -112940,6 +113112,74 @@ var init_workspace_file_tree_coordinator = __esm(() => {
112940
113112
  DEFAULT_RECONCILE_INTERVAL_MS = 10 * 60 * 1000;
112941
113113
  });
112942
113114
 
113115
+ // src/infrastructure/services/workspace/workspace-sync-config.ts
113116
+ var FILE_TREE_SYNC_DEBOUNCE_MS = 5000;
113117
+
113118
+ // src/infrastructure/services/workspace/workspace-sync-queue.ts
113119
+ function queueKey(machineId, workingDir) {
113120
+ return `${machineId}\x00${workingDir}`;
113121
+ }
113122
+ function getOrCreateState(key) {
113123
+ let state = queues.get(key);
113124
+ if (!state) {
113125
+ state = { drainPromise: null, pendingTask: null, scheduled: false };
113126
+ queues.set(key, state);
113127
+ }
113128
+ return state;
113129
+ }
113130
+ function sleep7(ms) {
113131
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
113132
+ }
113133
+ async function drainQueue(state, key, debounceMs) {
113134
+ try {
113135
+ while (state.pendingTask) {
113136
+ const lastCompletedAt = lastCompletedAtByKey.get(key) ?? 0;
113137
+ const elapsed3 = Date.now() - lastCompletedAt;
113138
+ const waitMs = lastCompletedAt === 0 ? 0 : Math.max(0, debounceMs - elapsed3);
113139
+ if (waitMs > 0) {
113140
+ await sleep7(waitMs);
113141
+ }
113142
+ const task = state.pendingTask;
113143
+ if (!task)
113144
+ break;
113145
+ state.pendingTask = null;
113146
+ await task();
113147
+ lastCompletedAtByKey.set(key, Date.now());
113148
+ }
113149
+ } finally {
113150
+ state.drainPromise = null;
113151
+ state.scheduled = false;
113152
+ if (state.pendingTask) {
113153
+ kickDrain(state, key, debounceMs);
113154
+ } else {
113155
+ queues.delete(key);
113156
+ }
113157
+ }
113158
+ }
113159
+ function kickDrain(state, key, debounceMs) {
113160
+ if (state.scheduled || state.drainPromise)
113161
+ return;
113162
+ state.scheduled = true;
113163
+ state.drainPromise = new Promise((resolve8, reject) => {
113164
+ queueMicrotask(() => {
113165
+ drainQueue(state, key, debounceMs).then(resolve8, reject);
113166
+ });
113167
+ });
113168
+ }
113169
+ async function enqueueFileTreeSync(machineId, workingDir, task, options) {
113170
+ const debounceMs = options?.debounceMs ?? FILE_TREE_SYNC_DEBOUNCE_MS;
113171
+ const key = queueKey(machineId, workingDir);
113172
+ const state = getOrCreateState(key);
113173
+ state.pendingTask = task;
113174
+ kickDrain(state, key, debounceMs);
113175
+ return state.drainPromise ?? Promise.resolve();
113176
+ }
113177
+ var queues, lastCompletedAtByKey;
113178
+ var init_workspace_sync_queue = __esm(() => {
113179
+ queues = new Map;
113180
+ lastCompletedAtByKey = new Map;
113181
+ });
113182
+
112943
113183
  // src/daemon/entry/files/file-tree-subscription.ts
112944
113184
  import { randomUUID as randomUUID11 } from "node:crypto";
112945
113185
  function logSubscriptionWarn(label, err) {
@@ -112986,15 +113226,17 @@ async function processPendingFileTreeRequests(session2, coordinators, ensureCoor
112986
113226
  requestsByDir.set(normalized, requestsByDir.get(normalized) === true || request2.force === true);
112987
113227
  }
112988
113228
  for (const [normalized, force] of requestsByDir) {
112989
- const start3 = Date.now();
112990
- await ensureCoordinator(normalized, force).then(() => session2.backend.mutation(api.workspaceFiles.fulfillFileTreeRequest, {
112991
- sessionId: session2.sessionId,
112992
- machineId: session2.machineId,
112993
- workingDir: normalized
112994
- })).then(() => {
112995
- console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree ready: ${normalized} (${Date.now() - start3}ms${force ? ", reconciled" : ", cached"})`);
112996
- }).catch((err) => {
112997
- logSubscriptionWarn(`File tree failed for ${normalized}`, err);
113229
+ await enqueueFileTreeSync(session2.machineId, normalized, async () => {
113230
+ const start3 = Date.now();
113231
+ await ensureCoordinator(normalized, force).then(() => session2.backend.mutation(api.workspaceFiles.fulfillFileTreeRequest, {
113232
+ sessionId: session2.sessionId,
113233
+ machineId: session2.machineId,
113234
+ workingDir: normalized
113235
+ })).then(() => {
113236
+ console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree ready: ${normalized} (${Date.now() - start3}ms${force ? ", reconciled" : ", cached"})`);
113237
+ }).catch((err) => {
113238
+ logSubscriptionWarn(`File tree failed for ${normalized}`, err);
113239
+ });
112998
113240
  });
112999
113241
  }
113000
113242
  }
@@ -113128,6 +113370,7 @@ var init_file_tree_subscription = __esm(() => {
113128
113370
  init_blob_snapshot_publish();
113129
113371
  init_sharded_snapshot_publish();
113130
113372
  init_workspace_file_tree_coordinator();
113373
+ init_workspace_sync_queue();
113131
113374
  init_convex_error();
113132
113375
  init_daemon_services();
113133
113376
  });
@@ -127757,7 +128000,7 @@ function routeRequest(req, res, deps) {
127757
128000
  }
127758
128001
 
127759
128002
  // src/daemon/local-web/server/serve-static.ts
127760
- import { existsSync as existsSync9, readFileSync as readFileSync10 } from "node:fs";
128003
+ import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
127761
128004
  import { dirname as dirname15, join as join27 } from "node:path";
127762
128005
  import { fileURLToPath as fileURLToPath7 } from "node:url";
127763
128006
  function clientDistCandidates(here) {
@@ -127770,7 +128013,7 @@ function clientDistCandidates(here) {
127770
128013
  function resolveClientDistDir(here = dirname15(fileURLToPath7(import.meta.url))) {
127771
128014
  const candidates = clientDistCandidates(here);
127772
128015
  for (const dir of candidates) {
127773
- if (existsSync9(join27(dir, "index.html")))
128016
+ if (existsSync10(join27(dir, "index.html")))
127774
128017
  return dir;
127775
128018
  }
127776
128019
  return candidates[0];
@@ -127789,24 +128032,24 @@ function tryServeStatic(req, res, distDir) {
127789
128032
  res.end();
127790
128033
  return true;
127791
128034
  }
127792
- if (existsSync9(filePath)) {
128035
+ if (existsSync10(filePath)) {
127793
128036
  const ext = safePath.slice(safePath.lastIndexOf("."));
127794
128037
  const type = MIME[ext] ?? "application/octet-stream";
127795
128038
  res.writeHead(200, { "Content-Type": type });
127796
128039
  if (req.method === "HEAD") {
127797
128040
  res.end();
127798
128041
  } else {
127799
- res.end(readFileSync10(filePath));
128042
+ res.end(readFileSync11(filePath));
127800
128043
  }
127801
128044
  return true;
127802
128045
  }
127803
128046
  const indexPath = join27(distDir, "index.html");
127804
- if (existsSync9(indexPath)) {
128047
+ if (existsSync10(indexPath)) {
127805
128048
  res.writeHead(200, { "Content-Type": "text/html" });
127806
128049
  if (req.method === "HEAD") {
127807
128050
  res.end();
127808
128051
  } else {
127809
- res.end(readFileSync10(indexPath));
128052
+ res.end(readFileSync11(indexPath));
127810
128053
  }
127811
128054
  return true;
127812
128055
  }
@@ -128195,29 +128438,19 @@ var init_daemon_start = __esm(() => {
128195
128438
  // src/commands/machine/daemon-stop.ts
128196
128439
  async function daemonStop() {
128197
128440
  const { running: running3, pid } = isDaemonRunning();
128198
- if (!running3) {
128441
+ const stopped = await stopExistingDaemons();
128442
+ removePid();
128443
+ if (!running3 && stopped.length === 0) {
128199
128444
  console.log(`⚪ Daemon is not running`);
128200
128445
  return;
128201
128446
  }
128202
- console.log(`Stopping daemon (PID: ${pid})...`);
128203
- try {
128204
- process.kill(pid, "SIGTERM");
128205
- await new Promise((resolve8) => setTimeout(resolve8, 8000));
128206
- try {
128207
- process.kill(pid, 0);
128208
- console.log(`Process did not exit gracefully, forcing...`);
128209
- process.kill(pid, "SIGKILL");
128210
- } catch {}
128211
- removePid();
128212
- console.log(`✅ Daemon stopped`);
128213
- } catch (error51) {
128214
- console.error(`❌ Failed to stop daemon: ${getErrorMessage(error51)}`);
128215
- removePid();
128447
+ if (stopped.length === 0 && pid !== null) {
128448
+ console.log(`Stopping daemon (PID: ${pid})...`);
128216
128449
  }
128450
+ console.log(`✅ Daemon stopped`);
128217
128451
  }
128218
128452
  var init_daemon_stop = __esm(() => {
128219
128453
  init_pid();
128220
- init_convex_error();
128221
128454
  });
128222
128455
 
128223
128456
  // src/commands/machine/daemon-status.ts
@@ -129409,4 +129642,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
129409
129642
  });
129410
129643
  program2.parse();
129411
129644
 
129412
- //# debugId=104EE59D5601863F64756E2164756E21
129645
+ //# debugId=2F868299E7BFEA7764756E2164756E21