@episoda/cli 0.2.218 → 0.2.220
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/daemon/daemon-process.js +202 -96
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -39,8 +39,9 @@ var require_command_protocol = __commonJS({
|
|
|
39
39
|
exports2.WORKTREE_STATUS_VALUES = void 0;
|
|
40
40
|
exports2.WORKTREE_STATUS_VALUES = [
|
|
41
41
|
"pending",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"provisioning",
|
|
43
|
+
"verified",
|
|
44
|
+
"missing",
|
|
44
45
|
"error",
|
|
45
46
|
"removing"
|
|
46
47
|
];
|
|
@@ -2241,7 +2242,7 @@ var require_websocket_client = __commonJS({
|
|
|
2241
2242
|
clearTimeout(this.reconnectTimeout);
|
|
2242
2243
|
this.reconnectTimeout = void 0;
|
|
2243
2244
|
}
|
|
2244
|
-
return new Promise((
|
|
2245
|
+
return new Promise((resolve10, reject) => {
|
|
2245
2246
|
const connectionTimeout = setTimeout(() => {
|
|
2246
2247
|
if (this.ws) {
|
|
2247
2248
|
this.ws.terminate();
|
|
@@ -2272,7 +2273,7 @@ var require_websocket_client = __commonJS({
|
|
|
2272
2273
|
daemonPid: this.daemonPid
|
|
2273
2274
|
});
|
|
2274
2275
|
this.startHeartbeat();
|
|
2275
|
-
|
|
2276
|
+
resolve10();
|
|
2276
2277
|
});
|
|
2277
2278
|
this.ws.on("pong", () => {
|
|
2278
2279
|
if (this.heartbeatTimeoutTimer) {
|
|
@@ -2416,13 +2417,13 @@ var require_websocket_client = __commonJS({
|
|
|
2416
2417
|
console.warn("[EpisodaClient] Cannot send - WebSocket not connected");
|
|
2417
2418
|
return false;
|
|
2418
2419
|
}
|
|
2419
|
-
return new Promise((
|
|
2420
|
+
return new Promise((resolve10) => {
|
|
2420
2421
|
this.ws.send(JSON.stringify(message), (error) => {
|
|
2421
2422
|
if (error) {
|
|
2422
2423
|
console.error("[EpisodaClient] Failed to send message:", error);
|
|
2423
|
-
|
|
2424
|
+
resolve10(false);
|
|
2424
2425
|
} else {
|
|
2425
|
-
|
|
2426
|
+
resolve10(true);
|
|
2426
2427
|
}
|
|
2427
2428
|
});
|
|
2428
2429
|
});
|
|
@@ -3051,7 +3052,7 @@ var require_package = __commonJS({
|
|
|
3051
3052
|
"package.json"(exports2, module2) {
|
|
3052
3053
|
module2.exports = {
|
|
3053
3054
|
name: "@episoda/cli",
|
|
3054
|
-
version: "0.2.
|
|
3055
|
+
version: "0.2.220",
|
|
3055
3056
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
3056
3057
|
main: "dist/index.js",
|
|
3057
3058
|
types: "dist/index.d.ts",
|
|
@@ -3468,10 +3469,10 @@ var IPCServer = class {
|
|
|
3468
3469
|
this.server = net.createServer((socket) => {
|
|
3469
3470
|
this.handleConnection(socket);
|
|
3470
3471
|
});
|
|
3471
|
-
return new Promise((
|
|
3472
|
+
return new Promise((resolve10, reject) => {
|
|
3472
3473
|
this.server.listen(socketPath, () => {
|
|
3473
3474
|
fs4.chmodSync(socketPath, 384);
|
|
3474
|
-
|
|
3475
|
+
resolve10();
|
|
3475
3476
|
});
|
|
3476
3477
|
this.server.on("error", reject);
|
|
3477
3478
|
});
|
|
@@ -3482,12 +3483,12 @@ var IPCServer = class {
|
|
|
3482
3483
|
async stop() {
|
|
3483
3484
|
if (!this.server) return;
|
|
3484
3485
|
const socketPath = getSocketPath();
|
|
3485
|
-
return new Promise((
|
|
3486
|
+
return new Promise((resolve10) => {
|
|
3486
3487
|
this.server.close(() => {
|
|
3487
3488
|
if (fs4.existsSync(socketPath)) {
|
|
3488
3489
|
fs4.unlinkSync(socketPath);
|
|
3489
3490
|
}
|
|
3490
|
-
|
|
3491
|
+
resolve10();
|
|
3491
3492
|
});
|
|
3492
3493
|
});
|
|
3493
3494
|
}
|
|
@@ -3732,7 +3733,7 @@ function getDownloadUrl() {
|
|
|
3732
3733
|
return platformUrls[arch4] || null;
|
|
3733
3734
|
}
|
|
3734
3735
|
async function downloadFile(url, destPath) {
|
|
3735
|
-
return new Promise((
|
|
3736
|
+
return new Promise((resolve10, reject) => {
|
|
3736
3737
|
const followRedirect = (currentUrl, redirectCount = 0) => {
|
|
3737
3738
|
if (redirectCount > 5) {
|
|
3738
3739
|
reject(new Error("Too many redirects"));
|
|
@@ -3762,7 +3763,7 @@ async function downloadFile(url, destPath) {
|
|
|
3762
3763
|
response.pipe(file);
|
|
3763
3764
|
file.on("finish", () => {
|
|
3764
3765
|
file.close();
|
|
3765
|
-
|
|
3766
|
+
resolve10();
|
|
3766
3767
|
});
|
|
3767
3768
|
file.on("error", (err) => {
|
|
3768
3769
|
fs5.unlinkSync(destPath);
|
|
@@ -4176,10 +4177,10 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4176
4177
|
const isTracked = Array.from(this.tunnelStates.values()).some((s) => s.info.pid === pid);
|
|
4177
4178
|
console.log(`[Tunnel] EP904: Found cloudflared PID ${pid} on port ${port} (tracked: ${isTracked})`);
|
|
4178
4179
|
this.killByPid(pid, "SIGTERM");
|
|
4179
|
-
await new Promise((
|
|
4180
|
+
await new Promise((resolve10) => setTimeout(resolve10, 500));
|
|
4180
4181
|
if (this.isProcessRunning(pid)) {
|
|
4181
4182
|
this.killByPid(pid, "SIGKILL");
|
|
4182
|
-
await new Promise((
|
|
4183
|
+
await new Promise((resolve10) => setTimeout(resolve10, 200));
|
|
4183
4184
|
}
|
|
4184
4185
|
killed.push(pid);
|
|
4185
4186
|
}
|
|
@@ -4213,7 +4214,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4213
4214
|
if (!this.tunnelStates.has(moduleUid)) {
|
|
4214
4215
|
console.log(`[Tunnel] EP877: Found orphaned process PID ${pid} for ${moduleUid}, killing...`);
|
|
4215
4216
|
this.killByPid(pid, "SIGTERM");
|
|
4216
|
-
await new Promise((
|
|
4217
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
4217
4218
|
if (this.isProcessRunning(pid)) {
|
|
4218
4219
|
this.killByPid(pid, "SIGKILL");
|
|
4219
4220
|
}
|
|
@@ -4228,7 +4229,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4228
4229
|
if (!trackedPids.includes(pid) && !cleaned.includes(pid)) {
|
|
4229
4230
|
console.log(`[Tunnel] EP877: Found untracked cloudflared process PID ${pid}, killing...`);
|
|
4230
4231
|
this.killByPid(pid, "SIGTERM");
|
|
4231
|
-
await new Promise((
|
|
4232
|
+
await new Promise((resolve10) => setTimeout(resolve10, 500));
|
|
4232
4233
|
if (this.isProcessRunning(pid)) {
|
|
4233
4234
|
this.killByPid(pid, "SIGKILL");
|
|
4234
4235
|
}
|
|
@@ -4318,7 +4319,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4318
4319
|
return { success: false, error: `Failed to get cloudflared: ${errorMessage}` };
|
|
4319
4320
|
}
|
|
4320
4321
|
}
|
|
4321
|
-
return new Promise((
|
|
4322
|
+
return new Promise((resolve10) => {
|
|
4322
4323
|
const tunnelInfo = {
|
|
4323
4324
|
moduleUid,
|
|
4324
4325
|
url: previewUrl || "",
|
|
@@ -4384,7 +4385,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4384
4385
|
moduleUid,
|
|
4385
4386
|
url: tunnelInfo.url
|
|
4386
4387
|
});
|
|
4387
|
-
|
|
4388
|
+
resolve10({ success: true, url: tunnelInfo.url });
|
|
4388
4389
|
}
|
|
4389
4390
|
};
|
|
4390
4391
|
process2.stderr?.on("data", (data) => {
|
|
@@ -4411,7 +4412,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4411
4412
|
onStatusChange?.("error", errorMsg);
|
|
4412
4413
|
this.emitEvent({ type: "error", moduleUid, error: errorMsg });
|
|
4413
4414
|
}
|
|
4414
|
-
|
|
4415
|
+
resolve10({ success: false, error: errorMsg });
|
|
4415
4416
|
} else if (wasConnected) {
|
|
4416
4417
|
if (currentState && !currentState.intentionallyStopped) {
|
|
4417
4418
|
console.log(`[Tunnel] EP948: Named tunnel ${moduleUid} crashed unexpectedly, attempting reconnect...`);
|
|
@@ -4442,7 +4443,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4442
4443
|
this.emitEvent({ type: "error", moduleUid, error: error.message });
|
|
4443
4444
|
}
|
|
4444
4445
|
if (!connected) {
|
|
4445
|
-
|
|
4446
|
+
resolve10({ success: false, error: error.message });
|
|
4446
4447
|
}
|
|
4447
4448
|
});
|
|
4448
4449
|
setTimeout(() => {
|
|
@@ -4465,7 +4466,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4465
4466
|
onStatusChange?.("error", errorMsg);
|
|
4466
4467
|
this.emitEvent({ type: "error", moduleUid, error: errorMsg });
|
|
4467
4468
|
}
|
|
4468
|
-
|
|
4469
|
+
resolve10({ success: false, error: errorMsg });
|
|
4469
4470
|
}
|
|
4470
4471
|
}, TUNNEL_TIMEOUTS.NAMED_TUNNEL_CONNECT);
|
|
4471
4472
|
});
|
|
@@ -4526,7 +4527,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4526
4527
|
if (orphanPid && this.isProcessRunning(orphanPid)) {
|
|
4527
4528
|
console.log(`[Tunnel] EP877: Killing orphaned process ${orphanPid} for ${moduleUid} before starting new tunnel`);
|
|
4528
4529
|
this.killByPid(orphanPid, "SIGTERM");
|
|
4529
|
-
await new Promise((
|
|
4530
|
+
await new Promise((resolve10) => setTimeout(resolve10, 500));
|
|
4530
4531
|
if (this.isProcessRunning(orphanPid)) {
|
|
4531
4532
|
this.killByPid(orphanPid, "SIGKILL");
|
|
4532
4533
|
}
|
|
@@ -4535,7 +4536,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4535
4536
|
const killedOnPort = await this.killCloudflaredOnPort(port);
|
|
4536
4537
|
if (killedOnPort.length > 0) {
|
|
4537
4538
|
console.log(`[Tunnel] EP904: Pre-start port cleanup killed ${killedOnPort.length} process(es) on port ${port}`);
|
|
4538
|
-
await new Promise((
|
|
4539
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
4539
4540
|
}
|
|
4540
4541
|
const cleanup = await this.cleanupOrphanedProcesses();
|
|
4541
4542
|
if (cleanup.cleaned > 0) {
|
|
@@ -4575,7 +4576,7 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4575
4576
|
if (orphanPid && this.isProcessRunning(orphanPid)) {
|
|
4576
4577
|
console.log(`[Tunnel] EP877: Stopping orphaned process ${orphanPid} for ${moduleUid} via PID file`);
|
|
4577
4578
|
this.killByPid(orphanPid, "SIGTERM");
|
|
4578
|
-
await new Promise((
|
|
4579
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
4579
4580
|
if (this.isProcessRunning(orphanPid)) {
|
|
4580
4581
|
this.killByPid(orphanPid, "SIGKILL");
|
|
4581
4582
|
}
|
|
@@ -4591,16 +4592,16 @@ var TunnelManager = class extends import_events.EventEmitter {
|
|
|
4591
4592
|
const tunnel = state.info;
|
|
4592
4593
|
if (tunnel.process && !tunnel.process.killed) {
|
|
4593
4594
|
tunnel.process.kill("SIGTERM");
|
|
4594
|
-
await new Promise((
|
|
4595
|
+
await new Promise((resolve10) => {
|
|
4595
4596
|
const timeout = setTimeout(() => {
|
|
4596
4597
|
if (tunnel.process && !tunnel.process.killed) {
|
|
4597
4598
|
tunnel.process.kill("SIGKILL");
|
|
4598
4599
|
}
|
|
4599
|
-
|
|
4600
|
+
resolve10();
|
|
4600
4601
|
}, 3e3);
|
|
4601
4602
|
tunnel.process.once("exit", () => {
|
|
4602
4603
|
clearTimeout(timeout);
|
|
4603
|
-
|
|
4604
|
+
resolve10();
|
|
4604
4605
|
});
|
|
4605
4606
|
});
|
|
4606
4607
|
}
|
|
@@ -4972,15 +4973,15 @@ async function writeToStdinWithBackpressure(process2, data, drainTimeoutMs, labe
|
|
|
4972
4973
|
if (!stdin || stdin.destroyed) {
|
|
4973
4974
|
throw new Error(`[${label}] stdin not available. session=${sessionId}`);
|
|
4974
4975
|
}
|
|
4975
|
-
await new Promise((
|
|
4976
|
+
await new Promise((resolve10, reject) => {
|
|
4976
4977
|
const ok = stdin.write(data);
|
|
4977
4978
|
if (ok) {
|
|
4978
|
-
|
|
4979
|
+
resolve10();
|
|
4979
4980
|
return;
|
|
4980
4981
|
}
|
|
4981
4982
|
const onDrain = () => {
|
|
4982
4983
|
cleanup();
|
|
4983
|
-
|
|
4984
|
+
resolve10();
|
|
4984
4985
|
};
|
|
4985
4986
|
const onError = (err) => {
|
|
4986
4987
|
cleanup();
|
|
@@ -5001,18 +5002,18 @@ async function writeToStdinWithBackpressure(process2, data, drainTimeoutMs, labe
|
|
|
5001
5002
|
});
|
|
5002
5003
|
}
|
|
5003
5004
|
function waitForProcessExit(process2, alive, timeoutMs) {
|
|
5004
|
-
return new Promise((
|
|
5005
|
+
return new Promise((resolve10) => {
|
|
5005
5006
|
if (!process2 || !alive) {
|
|
5006
|
-
|
|
5007
|
+
resolve10(true);
|
|
5007
5008
|
return;
|
|
5008
5009
|
}
|
|
5009
5010
|
const onExit = () => {
|
|
5010
5011
|
clearTimeout(timer);
|
|
5011
|
-
|
|
5012
|
+
resolve10(true);
|
|
5012
5013
|
};
|
|
5013
5014
|
const timer = setTimeout(() => {
|
|
5014
5015
|
process2.removeListener("exit", onExit);
|
|
5015
|
-
|
|
5016
|
+
resolve10(false);
|
|
5016
5017
|
}, timeoutMs);
|
|
5017
5018
|
process2.once("exit", onExit);
|
|
5018
5019
|
});
|
|
@@ -6008,10 +6009,10 @@ var CodexPersistentRuntime = class {
|
|
|
6008
6009
|
}
|
|
6009
6010
|
waitForThreadId(timeoutMs) {
|
|
6010
6011
|
if (this._agentSessionId) return Promise.resolve(this._agentSessionId);
|
|
6011
|
-
return new Promise((
|
|
6012
|
+
return new Promise((resolve10, reject) => {
|
|
6012
6013
|
const onId = (id) => {
|
|
6013
6014
|
clearTimeout(timer);
|
|
6014
|
-
|
|
6015
|
+
resolve10(id);
|
|
6015
6016
|
};
|
|
6016
6017
|
const timer = setTimeout(() => {
|
|
6017
6018
|
this.threadIdWaiters = this.threadIdWaiters.filter((w) => w !== onId);
|
|
@@ -6042,12 +6043,12 @@ var CodexPersistentRuntime = class {
|
|
|
6042
6043
|
sendRequest(method, params, timeoutMs = INIT_TIMEOUT_MS) {
|
|
6043
6044
|
const id = this.nextId++;
|
|
6044
6045
|
const msg = { jsonrpc: "2.0", id, method, params };
|
|
6045
|
-
return new Promise(async (
|
|
6046
|
+
return new Promise(async (resolve10, reject) => {
|
|
6046
6047
|
const timeout = setTimeout(() => {
|
|
6047
6048
|
this.pending.delete(id);
|
|
6048
6049
|
reject(new Error(`JSON-RPC timeout: ${method}`));
|
|
6049
6050
|
}, timeoutMs);
|
|
6050
|
-
this.pending.set(id, { resolve:
|
|
6051
|
+
this.pending.set(id, { resolve: resolve10, reject, timeout });
|
|
6051
6052
|
try {
|
|
6052
6053
|
await this.writeToStdin(JSON.stringify(msg) + "\n");
|
|
6053
6054
|
} catch (err) {
|
|
@@ -6197,11 +6198,11 @@ var UnifiedAgentRuntime = class {
|
|
|
6197
6198
|
if (!this.currentTurn && this.impl.turnState === "idle") {
|
|
6198
6199
|
return this.dispatchTurn(message, callbacks);
|
|
6199
6200
|
}
|
|
6200
|
-
return new Promise((
|
|
6201
|
+
return new Promise((resolve10, reject) => {
|
|
6201
6202
|
this.queuedTurns.push({
|
|
6202
6203
|
message,
|
|
6203
6204
|
callbacks,
|
|
6204
|
-
resolve:
|
|
6205
|
+
resolve: resolve10,
|
|
6205
6206
|
reject
|
|
6206
6207
|
});
|
|
6207
6208
|
});
|
|
@@ -7719,13 +7720,13 @@ async function getChildProcessRssMb(pid) {
|
|
|
7719
7720
|
if (!pid || pid <= 0) return null;
|
|
7720
7721
|
try {
|
|
7721
7722
|
if (typeof import_child_process10.execFile !== "function") return null;
|
|
7722
|
-
const stdout = await new Promise((
|
|
7723
|
+
const stdout = await new Promise((resolve10, reject) => {
|
|
7723
7724
|
(0, import_child_process10.execFile)("ps", ["-o", "rss=", "-p", String(pid)], { timeout: 1e3 }, (err, out) => {
|
|
7724
7725
|
if (err) {
|
|
7725
7726
|
reject(err);
|
|
7726
7727
|
return;
|
|
7727
7728
|
}
|
|
7728
|
-
|
|
7729
|
+
resolve10(String(out));
|
|
7729
7730
|
});
|
|
7730
7731
|
});
|
|
7731
7732
|
const kb = Number(String(stdout).trim());
|
|
@@ -7828,8 +7829,8 @@ var AgentControlPlane = class {
|
|
|
7828
7829
|
async withConfigLock(fn) {
|
|
7829
7830
|
const previousLock = this.configWriteLock;
|
|
7830
7831
|
let releaseLock;
|
|
7831
|
-
this.configWriteLock = new Promise((
|
|
7832
|
-
releaseLock =
|
|
7832
|
+
this.configWriteLock = new Promise((resolve10) => {
|
|
7833
|
+
releaseLock = resolve10;
|
|
7833
7834
|
});
|
|
7834
7835
|
try {
|
|
7835
7836
|
await previousLock;
|
|
@@ -9058,7 +9059,7 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
9058
9059
|
const lockContent = fs15.readFileSync(lockPath, "utf-8").trim();
|
|
9059
9060
|
const lockPid = parseInt(lockContent, 10);
|
|
9060
9061
|
if (!isNaN(lockPid) && this.isProcessRunning(lockPid)) {
|
|
9061
|
-
await new Promise((
|
|
9062
|
+
await new Promise((resolve10) => setTimeout(resolve10, retryInterval));
|
|
9062
9063
|
continue;
|
|
9063
9064
|
}
|
|
9064
9065
|
} catch {
|
|
@@ -9072,7 +9073,7 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
9072
9073
|
} catch {
|
|
9073
9074
|
continue;
|
|
9074
9075
|
}
|
|
9075
|
-
await new Promise((
|
|
9076
|
+
await new Promise((resolve10) => setTimeout(resolve10, retryInterval));
|
|
9076
9077
|
continue;
|
|
9077
9078
|
}
|
|
9078
9079
|
throw err;
|
|
@@ -9180,9 +9181,9 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
9180
9181
|
const worktree = config.worktrees.find((w) => w.moduleUid === moduleUid);
|
|
9181
9182
|
if (worktree) {
|
|
9182
9183
|
worktree.setupStatus = status;
|
|
9183
|
-
if (status === "
|
|
9184
|
+
if (status === "provisioning") {
|
|
9184
9185
|
worktree.setupStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9185
|
-
} else if (status === "
|
|
9186
|
+
} else if (status === "verified" || status === "error") {
|
|
9186
9187
|
worktree.setupCompletedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9187
9188
|
}
|
|
9188
9189
|
if (error) {
|
|
@@ -9392,7 +9393,7 @@ async function resolveAgentWorkingDirectory(options) {
|
|
|
9392
9393
|
command,
|
|
9393
9394
|
projectPath,
|
|
9394
9395
|
getWorktreeInfoForModule: getWorktreeInfoForModule2,
|
|
9395
|
-
pathExists = async (candidatePath) => {
|
|
9396
|
+
pathExists: pathExists2 = async (candidatePath) => {
|
|
9396
9397
|
try {
|
|
9397
9398
|
await fs16.promises.access(candidatePath);
|
|
9398
9399
|
return true;
|
|
@@ -9412,7 +9413,7 @@ async function resolveAgentWorkingDirectory(options) {
|
|
|
9412
9413
|
if (command.sessionContext === "project_root") {
|
|
9413
9414
|
if (command.workspaceSlug && command.projectSlug) {
|
|
9414
9415
|
const resolvedProjectPath = getProjectPath(command.workspaceSlug, command.projectSlug);
|
|
9415
|
-
if (resolvedProjectPath !== projectPath && await
|
|
9416
|
+
if (resolvedProjectPath !== projectPath && await pathExists2(resolvedProjectPath)) {
|
|
9416
9417
|
return resolvedProjectPath;
|
|
9417
9418
|
}
|
|
9418
9419
|
}
|
|
@@ -10597,7 +10598,7 @@ async function handleExec(command, projectPath) {
|
|
|
10597
10598
|
env = {}
|
|
10598
10599
|
} = command;
|
|
10599
10600
|
const effectiveTimeout = Math.min(Math.max(timeout, 1e3), MAX_TIMEOUT);
|
|
10600
|
-
return new Promise((
|
|
10601
|
+
return new Promise((resolve10) => {
|
|
10601
10602
|
let stdout = "";
|
|
10602
10603
|
let stderr = "";
|
|
10603
10604
|
let timedOut = false;
|
|
@@ -10605,7 +10606,7 @@ async function handleExec(command, projectPath) {
|
|
|
10605
10606
|
const done = (result) => {
|
|
10606
10607
|
if (resolved) return;
|
|
10607
10608
|
resolved = true;
|
|
10608
|
-
|
|
10609
|
+
resolve10(result);
|
|
10609
10610
|
};
|
|
10610
10611
|
try {
|
|
10611
10612
|
const proc = (0, import_child_process12.spawn)(cmd, {
|
|
@@ -10709,18 +10710,18 @@ var import_core14 = __toESM(require_dist());
|
|
|
10709
10710
|
// src/utils/port-check.ts
|
|
10710
10711
|
var net2 = __toESM(require("net"));
|
|
10711
10712
|
async function isPortInUse(port) {
|
|
10712
|
-
return new Promise((
|
|
10713
|
+
return new Promise((resolve10) => {
|
|
10713
10714
|
const server = net2.createServer();
|
|
10714
10715
|
server.once("error", (err) => {
|
|
10715
10716
|
if (err.code === "EADDRINUSE") {
|
|
10716
|
-
|
|
10717
|
+
resolve10(true);
|
|
10717
10718
|
} else {
|
|
10718
|
-
|
|
10719
|
+
resolve10(false);
|
|
10719
10720
|
}
|
|
10720
10721
|
});
|
|
10721
10722
|
server.once("listening", () => {
|
|
10722
10723
|
server.close();
|
|
10723
|
-
|
|
10724
|
+
resolve10(false);
|
|
10724
10725
|
});
|
|
10725
10726
|
server.listen(port);
|
|
10726
10727
|
});
|
|
@@ -11123,7 +11124,7 @@ var DevServerRegistry = class {
|
|
|
11123
11124
|
return killed;
|
|
11124
11125
|
}
|
|
11125
11126
|
wait(ms) {
|
|
11126
|
-
return new Promise((
|
|
11127
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
11127
11128
|
}
|
|
11128
11129
|
killWsServerOnPort(wsPort, worktreePath) {
|
|
11129
11130
|
const killed = [];
|
|
@@ -11697,7 +11698,7 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
11697
11698
|
return Math.min(delay, DEV_SERVER_CONSTANTS.MAX_RESTART_DELAY_MS);
|
|
11698
11699
|
}
|
|
11699
11700
|
async checkHealth(port) {
|
|
11700
|
-
return new Promise((
|
|
11701
|
+
return new Promise((resolve10) => {
|
|
11701
11702
|
const req = http.request(
|
|
11702
11703
|
{
|
|
11703
11704
|
hostname: "localhost",
|
|
@@ -11706,18 +11707,18 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
11706
11707
|
method: "HEAD",
|
|
11707
11708
|
timeout: DEV_SERVER_CONSTANTS.HEALTH_CHECK_TIMEOUT_MS
|
|
11708
11709
|
},
|
|
11709
|
-
() =>
|
|
11710
|
+
() => resolve10(true)
|
|
11710
11711
|
);
|
|
11711
|
-
req.on("error", () =>
|
|
11712
|
+
req.on("error", () => resolve10(false));
|
|
11712
11713
|
req.on("timeout", () => {
|
|
11713
11714
|
req.destroy();
|
|
11714
|
-
|
|
11715
|
+
resolve10(false);
|
|
11715
11716
|
});
|
|
11716
11717
|
req.end();
|
|
11717
11718
|
});
|
|
11718
11719
|
}
|
|
11719
11720
|
async checkWsHealth(wsPort) {
|
|
11720
|
-
return new Promise((
|
|
11721
|
+
return new Promise((resolve10) => {
|
|
11721
11722
|
const req = http.request(
|
|
11722
11723
|
{
|
|
11723
11724
|
hostname: "127.0.0.1",
|
|
@@ -11727,14 +11728,14 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
11727
11728
|
timeout: DEV_SERVER_CONSTANTS.HEALTH_CHECK_TIMEOUT_MS
|
|
11728
11729
|
},
|
|
11729
11730
|
(res) => {
|
|
11730
|
-
|
|
11731
|
+
resolve10(res.statusCode === 200);
|
|
11731
11732
|
res.resume();
|
|
11732
11733
|
}
|
|
11733
11734
|
);
|
|
11734
|
-
req.on("error", () =>
|
|
11735
|
+
req.on("error", () => resolve10(false));
|
|
11735
11736
|
req.on("timeout", () => {
|
|
11736
11737
|
req.destroy();
|
|
11737
|
-
|
|
11738
|
+
resolve10(false);
|
|
11738
11739
|
});
|
|
11739
11740
|
req.end();
|
|
11740
11741
|
});
|
|
@@ -11762,7 +11763,7 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
11762
11763
|
return false;
|
|
11763
11764
|
}
|
|
11764
11765
|
wait(ms) {
|
|
11765
|
-
return new Promise((
|
|
11766
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
11766
11767
|
}
|
|
11767
11768
|
getLogsDir() {
|
|
11768
11769
|
const logsDir = path26.join((0, import_core14.getConfigDir)(), "logs");
|
|
@@ -11961,7 +11962,7 @@ var PreviewManager = class extends import_events3.EventEmitter {
|
|
|
11961
11962
|
for (let attempt = 1; attempt <= MAX_TUNNEL_RETRIES; attempt++) {
|
|
11962
11963
|
if (attempt > 1) {
|
|
11963
11964
|
console.log(`[PreviewManager] Retrying tunnel for ${moduleUid} (attempt ${attempt}/${MAX_TUNNEL_RETRIES})...`);
|
|
11964
|
-
await new Promise((
|
|
11965
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
11965
11966
|
}
|
|
11966
11967
|
tunnelResult = await this.tunnel.startTunnel({
|
|
11967
11968
|
moduleUid,
|
|
@@ -12093,7 +12094,7 @@ var PreviewManager = class extends import_events3.EventEmitter {
|
|
|
12093
12094
|
}
|
|
12094
12095
|
console.log(`[PreviewManager] Restarting preview for ${moduleUid}`);
|
|
12095
12096
|
await this.stopPreview(moduleUid);
|
|
12096
|
-
await new Promise((
|
|
12097
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
12097
12098
|
return this.startPreview({
|
|
12098
12099
|
moduleUid,
|
|
12099
12100
|
worktreePath: state.worktreePath,
|
|
@@ -12628,6 +12629,92 @@ async function autoDetectSetupScript(worktreePath) {
|
|
|
12628
12629
|
console.log(`[Worktree] EP1222: Detected ${name} (${language}) via ${detection.matchedFile}`);
|
|
12629
12630
|
return installCmd;
|
|
12630
12631
|
}
|
|
12632
|
+
function isPathWithinRoot(candidatePath, rootPath) {
|
|
12633
|
+
const relative5 = path29.relative(rootPath, candidatePath);
|
|
12634
|
+
return relative5 === "" || !relative5.startsWith("..") && !path29.isAbsolute(relative5);
|
|
12635
|
+
}
|
|
12636
|
+
async function pathExists(candidatePath) {
|
|
12637
|
+
try {
|
|
12638
|
+
await fs29.promises.access(candidatePath, fs29.constants.F_OK);
|
|
12639
|
+
return true;
|
|
12640
|
+
} catch {
|
|
12641
|
+
return false;
|
|
12642
|
+
}
|
|
12643
|
+
}
|
|
12644
|
+
async function resolveGitPath(worktreePath, gitPathName) {
|
|
12645
|
+
try {
|
|
12646
|
+
const { stdout } = await execAsync2(`git -C "${worktreePath}" rev-parse --git-path ${gitPathName}`);
|
|
12647
|
+
return stdout.trim() || null;
|
|
12648
|
+
} catch {
|
|
12649
|
+
return null;
|
|
12650
|
+
}
|
|
12651
|
+
}
|
|
12652
|
+
async function handleWorktreeVerify(command, projectPath) {
|
|
12653
|
+
const projectRoot = path29.resolve(projectPath);
|
|
12654
|
+
const candidatePath = path29.resolve(command.worktreePath);
|
|
12655
|
+
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12656
|
+
const issues = [];
|
|
12657
|
+
const exists = await pathExists(candidatePath);
|
|
12658
|
+
const withinProjectRoot = exists && isPathWithinRoot(candidatePath, projectRoot);
|
|
12659
|
+
let gitWorktreeValid = false;
|
|
12660
|
+
let observedBranch = null;
|
|
12661
|
+
let structurallySound = true;
|
|
12662
|
+
if (!exists) {
|
|
12663
|
+
issues.push("PATH_MISSING");
|
|
12664
|
+
}
|
|
12665
|
+
if (exists && !withinProjectRoot) {
|
|
12666
|
+
issues.push("OUTSIDE_PROJECT_ROOT");
|
|
12667
|
+
}
|
|
12668
|
+
if (exists && withinProjectRoot) {
|
|
12669
|
+
try {
|
|
12670
|
+
await execAsync2(`git -C "${candidatePath}" rev-parse --is-inside-work-tree`);
|
|
12671
|
+
gitWorktreeValid = true;
|
|
12672
|
+
} catch {
|
|
12673
|
+
issues.push("INVALID_GIT_WORKTREE");
|
|
12674
|
+
}
|
|
12675
|
+
}
|
|
12676
|
+
if (gitWorktreeValid) {
|
|
12677
|
+
try {
|
|
12678
|
+
const { stdout } = await execAsync2(`git -C "${candidatePath}" rev-parse --abbrev-ref HEAD`);
|
|
12679
|
+
observedBranch = stdout.trim() || null;
|
|
12680
|
+
} catch {
|
|
12681
|
+
observedBranch = null;
|
|
12682
|
+
}
|
|
12683
|
+
const brokenMarkers = await Promise.all([
|
|
12684
|
+
resolveGitPath(candidatePath, "MERGE_HEAD"),
|
|
12685
|
+
resolveGitPath(candidatePath, "REBASE_HEAD"),
|
|
12686
|
+
resolveGitPath(candidatePath, "rebase-merge"),
|
|
12687
|
+
resolveGitPath(candidatePath, "rebase-apply")
|
|
12688
|
+
]);
|
|
12689
|
+
const markerExists = await Promise.all(
|
|
12690
|
+
brokenMarkers.filter((value) => Boolean(value)).map((value) => pathExists(value))
|
|
12691
|
+
);
|
|
12692
|
+
if (markerExists.some(Boolean)) {
|
|
12693
|
+
structurallySound = false;
|
|
12694
|
+
issues.push("BROKEN_STATE");
|
|
12695
|
+
}
|
|
12696
|
+
}
|
|
12697
|
+
const branchMatches = command.expectedBranch ? observedBranch === command.expectedBranch : true;
|
|
12698
|
+
if (command.expectedBranch && !branchMatches) {
|
|
12699
|
+
issues.push("BRANCH_MISMATCH");
|
|
12700
|
+
}
|
|
12701
|
+
const verification = {
|
|
12702
|
+
checkedAt,
|
|
12703
|
+
path: candidatePath,
|
|
12704
|
+
projectRoot,
|
|
12705
|
+
exists,
|
|
12706
|
+
withinProjectRoot,
|
|
12707
|
+
gitWorktreeValid,
|
|
12708
|
+
branchMatches,
|
|
12709
|
+
structurallySound,
|
|
12710
|
+
observedBranch,
|
|
12711
|
+
issues
|
|
12712
|
+
};
|
|
12713
|
+
return {
|
|
12714
|
+
success: true,
|
|
12715
|
+
verification
|
|
12716
|
+
};
|
|
12717
|
+
}
|
|
12631
12718
|
async function handleWorktreeCreate(request2) {
|
|
12632
12719
|
const {
|
|
12633
12720
|
workspaceSlug,
|
|
@@ -12741,11 +12828,11 @@ ${buildCmd}` : buildCmd;
|
|
|
12741
12828
|
setTimeout(() => {
|
|
12742
12829
|
void (async () => {
|
|
12743
12830
|
if (!effectiveSetupScript) {
|
|
12744
|
-
await manager.updateWorktreeStatus(moduleUid, "
|
|
12831
|
+
await manager.updateWorktreeStatus(moduleUid, "provisioning");
|
|
12745
12832
|
return;
|
|
12746
12833
|
}
|
|
12747
12834
|
const setupStartMs = Date.now();
|
|
12748
|
-
await manager.updateWorktreeStatus(moduleUid, "
|
|
12835
|
+
await manager.updateWorktreeStatus(moduleUid, "provisioning");
|
|
12749
12836
|
console.log(`[Worktree] EP1143: Running setup script asynchronously...`);
|
|
12750
12837
|
const scriptResult = await manager.runSetupScript(moduleUid, effectiveSetupScript);
|
|
12751
12838
|
console.log(`[Worktree] EP1373: setup_script phase=worktree_setup durationMs=${Date.now() - setupStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"} success=${scriptResult.success}`);
|
|
@@ -12754,7 +12841,7 @@ ${buildCmd}` : buildCmd;
|
|
|
12754
12841
|
await manager.updateWorktreeStatus(moduleUid, "error", scriptResult.error);
|
|
12755
12842
|
return;
|
|
12756
12843
|
}
|
|
12757
|
-
await manager.updateWorktreeStatus(moduleUid, "
|
|
12844
|
+
await manager.updateWorktreeStatus(moduleUid, "provisioning");
|
|
12758
12845
|
})().catch(async (setupError) => {
|
|
12759
12846
|
const errorMessage = setupError instanceof Error ? setupError.message : String(setupError);
|
|
12760
12847
|
console.error(`[Worktree] EP1458: Async setup failed for ${moduleUid}: ${errorMessage}`);
|
|
@@ -12767,7 +12854,7 @@ ${buildCmd}` : buildCmd;
|
|
|
12767
12854
|
}, 0);
|
|
12768
12855
|
let previewUrl;
|
|
12769
12856
|
let port;
|
|
12770
|
-
const finalStatus =
|
|
12857
|
+
const finalStatus = "provisioning";
|
|
12771
12858
|
if (moduleType === "ops") {
|
|
12772
12859
|
console.log(`[Worktree] EP1363: Skipping preview for ops module ${moduleUid}`);
|
|
12773
12860
|
} else {
|
|
@@ -13087,6 +13174,19 @@ var CODEX_BANNER_SIGNAL = /(openai codex|\bmodel:)/i;
|
|
|
13087
13174
|
var CODEX_PROMPT_SIGNAL = /(?:^|\n)\s*(?:>|❯)\s*$/m;
|
|
13088
13175
|
var MAX_CODEX_STARTUP_READY_TIMEOUT_MS = 3e4;
|
|
13089
13176
|
var sessions = /* @__PURE__ */ new Map();
|
|
13177
|
+
function bestEffortTerminateProcessGroup(session) {
|
|
13178
|
+
if (process.platform === "win32") {
|
|
13179
|
+
return;
|
|
13180
|
+
}
|
|
13181
|
+
const pid = session.pty.pid;
|
|
13182
|
+
if (!pid || pid <= 0) {
|
|
13183
|
+
return;
|
|
13184
|
+
}
|
|
13185
|
+
try {
|
|
13186
|
+
process.kill(-pid, "SIGTERM");
|
|
13187
|
+
} catch {
|
|
13188
|
+
}
|
|
13189
|
+
}
|
|
13090
13190
|
function killPtySessionsForModule(moduleUid) {
|
|
13091
13191
|
const killedRunIds = [];
|
|
13092
13192
|
for (const [id, session] of sessions.entries()) {
|
|
@@ -13095,6 +13195,7 @@ function killPtySessionsForModule(moduleUid) {
|
|
|
13095
13195
|
}
|
|
13096
13196
|
if (session.watchdogTimer) clearTimeout(session.watchdogTimer);
|
|
13097
13197
|
try {
|
|
13198
|
+
bestEffortTerminateProcessGroup(session);
|
|
13098
13199
|
session.pty.kill();
|
|
13099
13200
|
killedRunIds.push(id);
|
|
13100
13201
|
} catch {
|
|
@@ -13221,6 +13322,7 @@ async function handlePtySpawn(payload, client) {
|
|
|
13221
13322
|
if (session.watchdogTimer) clearTimeout(session.watchdogTimer);
|
|
13222
13323
|
console.log(`[PTY] Process exited for ${agent_run_id} with code ${exitCode} after ${durationMs}ms`);
|
|
13223
13324
|
sessions.delete(agent_run_id);
|
|
13325
|
+
bestEffortTerminateProcessGroup(session);
|
|
13224
13326
|
client.send({
|
|
13225
13327
|
type: "pty_exit",
|
|
13226
13328
|
moduleUid,
|
|
@@ -13277,6 +13379,7 @@ function handlePtyKill(payload) {
|
|
|
13277
13379
|
return;
|
|
13278
13380
|
}
|
|
13279
13381
|
try {
|
|
13382
|
+
bestEffortTerminateProcessGroup(session);
|
|
13280
13383
|
session.pty.kill();
|
|
13281
13384
|
console.log(`[PTY] Kill signal sent for session ${agent_run_id}`);
|
|
13282
13385
|
} catch {
|
|
@@ -13366,8 +13469,8 @@ function createStartupState(payload, resolvedArgs) {
|
|
|
13366
13469
|
const mode = payload.run_type === "persistent" ? trimmedStdin.length > 0 ? "seed_after_prompt" : "prompt_ready" : "first_output";
|
|
13367
13470
|
let resolveReady;
|
|
13368
13471
|
let rejectReady;
|
|
13369
|
-
const waitForReady = new Promise((
|
|
13370
|
-
resolveReady =
|
|
13472
|
+
const waitForReady = new Promise((resolve10, reject) => {
|
|
13473
|
+
resolveReady = resolve10;
|
|
13371
13474
|
rejectReady = reject;
|
|
13372
13475
|
});
|
|
13373
13476
|
const startup = {
|
|
@@ -13659,7 +13762,7 @@ async function killProcessOnPort(port) {
|
|
|
13659
13762
|
} catch {
|
|
13660
13763
|
}
|
|
13661
13764
|
}
|
|
13662
|
-
await new Promise((
|
|
13765
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
13663
13766
|
for (const pid of pids) {
|
|
13664
13767
|
try {
|
|
13665
13768
|
(0, import_child_process16.execSync)(`kill -0 ${pid} 2>/dev/null`, { encoding: "utf8" });
|
|
@@ -13668,7 +13771,7 @@ async function killProcessOnPort(port) {
|
|
|
13668
13771
|
} catch {
|
|
13669
13772
|
}
|
|
13670
13773
|
}
|
|
13671
|
-
await new Promise((
|
|
13774
|
+
await new Promise((resolve10) => setTimeout(resolve10, 500));
|
|
13672
13775
|
const stillInUse = await isPortInUse(port);
|
|
13673
13776
|
if (stillInUse) {
|
|
13674
13777
|
console.error(`[DevServer] EP929: Port ${port} still in use after kill attempts`);
|
|
@@ -13688,7 +13791,7 @@ async function waitForPort(port, timeoutMs = 3e4) {
|
|
|
13688
13791
|
if (await isPortInUse(port)) {
|
|
13689
13792
|
return true;
|
|
13690
13793
|
}
|
|
13691
|
-
await new Promise((
|
|
13794
|
+
await new Promise((resolve10) => setTimeout(resolve10, checkInterval));
|
|
13692
13795
|
}
|
|
13693
13796
|
return false;
|
|
13694
13797
|
}
|
|
@@ -13760,7 +13863,7 @@ async function handleProcessExit(moduleUid, code, signal) {
|
|
|
13760
13863
|
const delay = calculateRestartDelay(serverInfo.restartCount);
|
|
13761
13864
|
console.log(`[DevServer] EP932: Restarting ${moduleUid} in ${delay}ms (attempt ${serverInfo.restartCount + 1}/${MAX_RESTART_ATTEMPTS})`);
|
|
13762
13865
|
writeToLog(serverInfo.logFile || "", `Scheduling restart in ${delay}ms (attempt ${serverInfo.restartCount + 1})`, false);
|
|
13763
|
-
await new Promise((
|
|
13866
|
+
await new Promise((resolve10) => setTimeout(resolve10, delay));
|
|
13764
13867
|
if (!activeServers.has(moduleUid)) {
|
|
13765
13868
|
console.log(`[DevServer] EP932: Server ${moduleUid} was removed during restart delay, aborting restart`);
|
|
13766
13869
|
return;
|
|
@@ -13885,7 +13988,7 @@ async function stopDevServer(moduleUid) {
|
|
|
13885
13988
|
writeToLog(serverInfo.logFile, `Stopping server (manual stop)`, false);
|
|
13886
13989
|
}
|
|
13887
13990
|
serverInfo.process.kill("SIGTERM");
|
|
13888
|
-
await new Promise((
|
|
13991
|
+
await new Promise((resolve10) => setTimeout(resolve10, 2e3));
|
|
13889
13992
|
if (!serverInfo.process.killed) {
|
|
13890
13993
|
serverInfo.process.kill("SIGKILL");
|
|
13891
13994
|
}
|
|
@@ -13903,7 +14006,7 @@ async function restartDevServer(moduleUid) {
|
|
|
13903
14006
|
writeToLog(logFile, `Manual restart requested`, false);
|
|
13904
14007
|
}
|
|
13905
14008
|
await stopDevServer(moduleUid);
|
|
13906
|
-
await new Promise((
|
|
14009
|
+
await new Promise((resolve10) => setTimeout(resolve10, 1e3));
|
|
13907
14010
|
if (await isPortInUse(port)) {
|
|
13908
14011
|
await killProcessOnPort(port);
|
|
13909
14012
|
}
|
|
@@ -14024,7 +14127,7 @@ var IPCRouter = class {
|
|
|
14024
14127
|
if (attempt < MAX_RETRIES) {
|
|
14025
14128
|
const delay = INITIAL_DELAY * Math.pow(2, attempt - 1);
|
|
14026
14129
|
console.log(`[Daemon] Retrying in ${delay / 1e3}s...`);
|
|
14027
|
-
await new Promise((
|
|
14130
|
+
await new Promise((resolve10) => setTimeout(resolve10, delay));
|
|
14028
14131
|
await this.host.disconnectProject(projectPath);
|
|
14029
14132
|
}
|
|
14030
14133
|
}
|
|
@@ -14988,7 +15091,7 @@ var ConnectionManager = class {
|
|
|
14988
15091
|
* handlers are removed deterministically on every exit path.
|
|
14989
15092
|
*/
|
|
14990
15093
|
async waitForAuthentication(client, timeoutMs = 3e4) {
|
|
14991
|
-
await new Promise((
|
|
15094
|
+
await new Promise((resolve10, reject) => {
|
|
14992
15095
|
let settled = false;
|
|
14993
15096
|
const cleanup = () => {
|
|
14994
15097
|
clearTimeout(timeout);
|
|
@@ -15007,7 +15110,7 @@ var ConnectionManager = class {
|
|
|
15007
15110
|
if (settled) return;
|
|
15008
15111
|
settled = true;
|
|
15009
15112
|
cleanup();
|
|
15010
|
-
|
|
15113
|
+
resolve10();
|
|
15011
15114
|
};
|
|
15012
15115
|
const authErrorHandler = (message) => {
|
|
15013
15116
|
if (settled) return;
|
|
@@ -15222,6 +15325,9 @@ var ProjectMessageRouter = class {
|
|
|
15222
15325
|
case "worktree:release":
|
|
15223
15326
|
result = await handleWorktreeRelease(cmd);
|
|
15224
15327
|
break;
|
|
15328
|
+
case "worktree:verify":
|
|
15329
|
+
result = await handleWorktreeVerify(cmd, projectPath);
|
|
15330
|
+
break;
|
|
15225
15331
|
case "worktree:list":
|
|
15226
15332
|
result = await handleWorktreeList(
|
|
15227
15333
|
cmd.workspaceSlug,
|
|
@@ -15680,8 +15786,8 @@ async function cacheMachineUuid(machineUuid, machineId) {
|
|
|
15680
15786
|
// src/daemon/reconciliation-utils.ts
|
|
15681
15787
|
var path36 = __toESM(require("path"));
|
|
15682
15788
|
function isPathUnderRoot(candidatePath, projectRoot) {
|
|
15683
|
-
const
|
|
15684
|
-
return
|
|
15789
|
+
const relative5 = path36.relative(projectRoot, candidatePath);
|
|
15790
|
+
return relative5 !== "" && !relative5.startsWith("..") && !path36.isAbsolute(relative5);
|
|
15685
15791
|
}
|
|
15686
15792
|
function collectUnexpectedWorktrees(params) {
|
|
15687
15793
|
const projectRootResolved = path36.resolve(params.projectRoot);
|
|
@@ -16051,8 +16157,8 @@ var Daemon = class _Daemon {
|
|
|
16051
16157
|
}
|
|
16052
16158
|
}
|
|
16053
16159
|
let releaseLock;
|
|
16054
|
-
const lockPromise = new Promise((
|
|
16055
|
-
releaseLock =
|
|
16160
|
+
const lockPromise = new Promise((resolve10) => {
|
|
16161
|
+
releaseLock = resolve10;
|
|
16056
16162
|
});
|
|
16057
16163
|
this.tunnelOperationLocks.set(moduleUid, lockPromise);
|
|
16058
16164
|
try {
|
|
@@ -16098,7 +16204,7 @@ var Daemon = class _Daemon {
|
|
|
16098
16204
|
const maxWait = 35e3;
|
|
16099
16205
|
const startTime = Date.now();
|
|
16100
16206
|
while (this.connectionManager.hasPendingConnection(projectPath) && Date.now() - startTime < maxWait) {
|
|
16101
|
-
await new Promise((
|
|
16207
|
+
await new Promise((resolve10) => setTimeout(resolve10, 500));
|
|
16102
16208
|
}
|
|
16103
16209
|
if (this.connectionManager.hasLiveConnection(projectPath)) {
|
|
16104
16210
|
console.log(`[Daemon] Pending connection succeeded for ${projectPath}`);
|
|
@@ -17168,8 +17274,8 @@ var Daemon = class _Daemon {
|
|
|
17168
17274
|
*/
|
|
17169
17275
|
async runWorktreeSetupSync(moduleUid, worktreeManager, copyFiles, setupScript, worktreePath, envVars = {}) {
|
|
17170
17276
|
console.log(`[Daemon] EP1002: Running worktree setup for ${moduleUid}`);
|
|
17171
|
-
await worktreeManager.updateWorktreeStatus(moduleUid, "
|
|
17172
|
-
await this.updateModuleWorktreeStatus(moduleUid, "
|
|
17277
|
+
await worktreeManager.updateWorktreeStatus(moduleUid, "provisioning");
|
|
17278
|
+
await this.updateModuleWorktreeStatus(moduleUid, "provisioning", worktreePath);
|
|
17173
17279
|
if (Object.keys(envVars).length > 0) {
|
|
17174
17280
|
console.log(`[Daemon] EP1002: Writing .env with ${Object.keys(envVars).length} variables`);
|
|
17175
17281
|
writeEnvFile(worktreePath, envVars);
|
|
@@ -17223,12 +17329,12 @@ var Daemon = class _Daemon {
|
|
|
17223
17329
|
throw new Error(`Setup script failed: ${scriptResult.error}`);
|
|
17224
17330
|
}
|
|
17225
17331
|
}
|
|
17226
|
-
await worktreeManager.updateWorktreeStatus(moduleUid, "
|
|
17227
|
-
await this.updateModuleWorktreeStatus(moduleUid, "
|
|
17332
|
+
await worktreeManager.updateWorktreeStatus(moduleUid, "provisioning");
|
|
17333
|
+
await this.updateModuleWorktreeStatus(moduleUid, "provisioning", worktreePath);
|
|
17228
17334
|
console.log(`[Daemon] EP1002: Worktree setup complete for ${moduleUid}`);
|
|
17229
17335
|
}
|
|
17230
17336
|
async runForegroundCommand(command, args, cwd, env, timeoutMs) {
|
|
17231
|
-
await new Promise((
|
|
17337
|
+
await new Promise((resolve10, reject) => {
|
|
17232
17338
|
const commandLabel = `${command} ${args.join(" ")}`.trim();
|
|
17233
17339
|
const child = (0, import_child_process18.spawn)(command, args, {
|
|
17234
17340
|
cwd,
|
|
@@ -17251,7 +17357,7 @@ var Daemon = class _Daemon {
|
|
|
17251
17357
|
reject(error);
|
|
17252
17358
|
return;
|
|
17253
17359
|
}
|
|
17254
|
-
|
|
17360
|
+
resolve10();
|
|
17255
17361
|
};
|
|
17256
17362
|
termTimer = setTimeout(() => {
|
|
17257
17363
|
timedOut = true;
|