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 +276 -43
- package/dist/index.js.map +11 -8
- package/package.json +1 -1
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
|
|
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 (!
|
|
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 (!
|
|
100053
|
+
if (!existsSync8(pidPath)) {
|
|
99933
100054
|
return null;
|
|
99934
100055
|
}
|
|
99935
100056
|
try {
|
|
99936
|
-
const content =
|
|
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 (
|
|
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 =
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
112990
|
-
|
|
112991
|
-
|
|
112992
|
-
|
|
112993
|
-
|
|
112994
|
-
|
|
112995
|
-
|
|
112996
|
-
|
|
112997
|
-
|
|
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
|
|
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 (
|
|
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 (
|
|
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(
|
|
128042
|
+
res.end(readFileSync11(filePath));
|
|
127800
128043
|
}
|
|
127801
128044
|
return true;
|
|
127802
128045
|
}
|
|
127803
128046
|
const indexPath = join27(distDir, "index.html");
|
|
127804
|
-
if (
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
128203
|
-
|
|
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=
|
|
129645
|
+
//# debugId=2F868299E7BFEA7764756E2164756E21
|