pipane 0.1.2 → 0.1.4
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.
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { spawn } from "node:child_process";
|
|
16
16
|
import * as readline from "node:readline";
|
|
17
|
+
import { existsSync } from "node:fs";
|
|
17
18
|
export class ProcessPool {
|
|
18
19
|
/** All live processes, keyed by cwd */
|
|
19
20
|
pools = new Map();
|
|
@@ -51,6 +52,9 @@ export class ProcessPool {
|
|
|
51
52
|
* Does not wait for readiness — call waitForReady() separately.
|
|
52
53
|
*/
|
|
53
54
|
spawn(cwd) {
|
|
55
|
+
if (!existsSync(cwd)) {
|
|
56
|
+
throw new Error(`Cannot spawn pi process: directory does not exist: ${cwd}`);
|
|
57
|
+
}
|
|
54
58
|
const procId = ++this.nextProcId;
|
|
55
59
|
console.log(`[pool] Spawning pi process #${procId} (cwd: ${cwd})...`);
|
|
56
60
|
// Strip NODE_ENV from the child environment so tools spawned by pi
|
|
@@ -96,6 +100,24 @@ export class ProcessPool {
|
|
|
96
100
|
pending.resolve(data);
|
|
97
101
|
}
|
|
98
102
|
});
|
|
103
|
+
child.on("error", (err) => {
|
|
104
|
+
console.error(`[pool] pi#${proc.id} spawn error: ${err.message}`);
|
|
105
|
+
// Remove from pool
|
|
106
|
+
const poolForCwd = this.pools.get(cwd);
|
|
107
|
+
if (poolForCwd) {
|
|
108
|
+
const idx = poolForCwd.indexOf(proc);
|
|
109
|
+
if (idx !== -1)
|
|
110
|
+
poolForCwd.splice(idx, 1);
|
|
111
|
+
if (poolForCwd.length === 0)
|
|
112
|
+
this.pools.delete(cwd);
|
|
113
|
+
}
|
|
114
|
+
// Reject any pending requests
|
|
115
|
+
for (const [, pending] of proc.pendingRequests) {
|
|
116
|
+
pending.reject(new Error(`pi process #${proc.id} failed to spawn: ${err.message}`));
|
|
117
|
+
}
|
|
118
|
+
proc.pendingRequests.clear();
|
|
119
|
+
this.onProcessExit?.(proc);
|
|
120
|
+
});
|
|
99
121
|
child.on("exit", (code) => {
|
|
100
122
|
console.log(`[pool] pi#${proc.id} exited (code ${code})`);
|
|
101
123
|
// Remove from pool
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { WebSocket } from "ws";
|
|
13
13
|
import { copyFile } from "node:fs/promises";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
14
15
|
import path from "node:path";
|
|
15
16
|
import { URL } from "node:url";
|
|
16
17
|
import { getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
@@ -559,7 +560,8 @@ export class WsHandler {
|
|
|
559
560
|
const newFilename = `${timestamp}_${newId}.jsonl`;
|
|
560
561
|
const newSessionPath = path.join(sessionsDir, newFilename);
|
|
561
562
|
await copyFile(sessionPath, newSessionPath);
|
|
562
|
-
const
|
|
563
|
+
const forkCwd = getSessionCwd(sessionPath);
|
|
564
|
+
const cwd = (forkCwd && existsSync(forkCwd)) ? forkCwd : this.defaultCwd;
|
|
563
565
|
const proc = await this.acquireProcess(cwd);
|
|
564
566
|
await this.pool.waitForReady(proc);
|
|
565
567
|
this.busyProcesses.add(proc);
|
|
@@ -632,7 +634,8 @@ export class WsHandler {
|
|
|
632
634
|
const existing = this.lifecycle.getAttachedProcess(sessionPath);
|
|
633
635
|
if (existing)
|
|
634
636
|
return existing;
|
|
635
|
-
const
|
|
637
|
+
const sessionCwd = getSessionCwd(sessionPath);
|
|
638
|
+
const cwd = (sessionCwd && existsSync(sessionCwd)) ? sessionCwd : this.defaultCwd;
|
|
636
639
|
const proc = await this.acquireProcess(cwd);
|
|
637
640
|
this.busyProcesses.add(proc);
|
|
638
641
|
this.lifecycle.attach(sessionPath, proc);
|
package/package.json
CHANGED