@rotriz/pi-web-ui 1.3.0 → 1.4.0
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/extension.mjs +16 -1
- package/package.json +1 -1
- package/server.mjs +54 -25
package/extension.mjs
CHANGED
|
@@ -20,11 +20,26 @@ export default function (pi) {
|
|
|
20
20
|
if (startPromise) return startPromise;
|
|
21
21
|
startPromise = (async () => {
|
|
22
22
|
try {
|
|
23
|
+
// Make @earendil-works/pi-coding-agent resolvable by the server module.
|
|
24
|
+
// Since we're in Pi's process, the module is already loaded — expose it globally.
|
|
25
|
+
try {
|
|
26
|
+
const piMod = await import("@earendil-works/pi-coding-agent");
|
|
27
|
+
globalThis.__PI_MODULE__ = piMod;
|
|
28
|
+
} catch {
|
|
29
|
+
// Fallback: resolve relative to Pi's entry script
|
|
30
|
+
const entry = process.argv[1] || "";
|
|
31
|
+
if (entry) {
|
|
32
|
+
const { dirname, join } = await import("node:path");
|
|
33
|
+
const dir = dirname(entry);
|
|
34
|
+
for (const c of [join(dir, "..", "dist", "index.js"), join(dir, "index.js")]) {
|
|
35
|
+
try { globalThis.__PI_MODULE__ = await import(c); break; } catch {}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
23
39
|
const { startServer } = await import("./server.mjs");
|
|
24
40
|
await startServer(PORT);
|
|
25
41
|
serverStarted = true;
|
|
26
42
|
} catch (err) {
|
|
27
|
-
// Server may already be listening (port in use = already running)
|
|
28
43
|
if (err?.code === "EADDRINUSE") {
|
|
29
44
|
serverStarted = true;
|
|
30
45
|
return;
|
package/package.json
CHANGED
package/server.mjs
CHANGED
|
@@ -19,8 +19,17 @@ const PORT = process.env.PORT || 3123;
|
|
|
19
19
|
const CWD = process.cwd();
|
|
20
20
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
21
21
|
|
|
22
|
-
//
|
|
22
|
+
// ─── Pi module resolution ─────────────────────────────────────────────────
|
|
23
|
+
let _piModule = null;
|
|
24
|
+
|
|
25
|
+
export function initPiModule(mod) {
|
|
26
|
+
_piModule = mod;
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
async function resolvePiModule() {
|
|
30
|
+
if (_piModule) return _piModule;
|
|
31
|
+
// Check if the extension pre-loaded the module via globalThis
|
|
32
|
+
if (globalThis.__PI_MODULE__) { _piModule = globalThis.__PI_MODULE__; return _piModule; }
|
|
24
33
|
const attempts = [];
|
|
25
34
|
if (process.env.PI_WEB_PI_MODULE) attempts.push(process.env.PI_WEB_PI_MODULE);
|
|
26
35
|
attempts.push("@earendil-works/pi-coding-agent");
|
|
@@ -30,35 +39,51 @@ async function resolvePiModule() {
|
|
|
30
39
|
attempts.push(join(dir, "..", "dist", "index.js"));
|
|
31
40
|
attempts.push(join(dir, "index.js"));
|
|
32
41
|
}
|
|
33
|
-
// Try NODE_PATH entries
|
|
34
42
|
if (process.env.NODE_PATH) {
|
|
35
43
|
for (const p of process.env.NODE_PATH.split(":")) {
|
|
36
44
|
attempts.push(join(p, "@earendil-works", "pi-coding-agent", "dist", "index.js"));
|
|
37
45
|
}
|
|
38
46
|
}
|
|
39
|
-
// Common global install locations
|
|
40
47
|
const nodeDir = dirname(dirname(process.execPath));
|
|
41
48
|
attempts.push(join(nodeDir, "lib", "node_modules", "@earendil-works", "pi-coding-agent", "dist", "index.js"));
|
|
42
|
-
// npm global prefix
|
|
43
49
|
attempts.push(join(homedir(), ".local", "lib", "node_modules", "@earendil-works", "pi-coding-agent", "dist", "index.js"));
|
|
44
50
|
for (const attempt of attempts) {
|
|
45
|
-
try {
|
|
51
|
+
try { _piModule = await import(attempt); return _piModule; } catch {}
|
|
46
52
|
}
|
|
47
53
|
throw new Error("Could not resolve @earendil-works/pi-coding-agent. Install it globally or set PI_WEB_PI_MODULE env var.");
|
|
48
54
|
}
|
|
49
|
-
const pi = await resolvePiModule();
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
// Only auto-initialize when run directly (node server.mjs)
|
|
57
|
+
const _isDirectRun = process.argv[1] && resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));
|
|
58
|
+
if (_isDirectRun) {
|
|
59
|
+
await resolvePiModule();
|
|
60
|
+
} else if (globalThis.__PI_MODULE__) {
|
|
61
|
+
_piModule = globalThis.__PI_MODULE__;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let createAgentSessionRuntime, createAgentSessionFromServices, createAgentSessionServices,
|
|
65
|
+
DefaultResourceLoader, SessionManager, SettingsManager, getAgentDir;
|
|
66
|
+
|
|
67
|
+
if (_piModule) {
|
|
68
|
+
({ createAgentSessionRuntime, createAgentSessionFromServices, createAgentSessionServices,
|
|
69
|
+
DefaultResourceLoader, SessionManager, SettingsManager, getAgentDir } = _piModule);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let AGENT_DIR = null;
|
|
73
|
+
|
|
74
|
+
let server = null;
|
|
75
|
+
let _booted = false;
|
|
76
|
+
|
|
77
|
+
async function boot() {
|
|
78
|
+
if (_booted) return;
|
|
79
|
+
if (!_piModule) {
|
|
80
|
+
if (globalThis.__PI_MODULE__) _piModule = globalThis.__PI_MODULE__;
|
|
81
|
+
else await resolvePiModule();
|
|
82
|
+
({ createAgentSessionRuntime, createAgentSessionFromServices, createAgentSessionServices,
|
|
83
|
+
DefaultResourceLoader, SessionManager, SettingsManager, getAgentDir } = _piModule);
|
|
84
|
+
}
|
|
85
|
+
AGENT_DIR = getAgentDir();
|
|
60
86
|
|
|
61
|
-
const AGENT_DIR = getAgentDir();
|
|
62
87
|
|
|
63
88
|
const createRuntime = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
64
89
|
const services = await createAgentSessionServices({ cwd });
|
|
@@ -868,7 +893,7 @@ function readBody(req) {
|
|
|
868
893
|
});
|
|
869
894
|
}
|
|
870
895
|
|
|
871
|
-
|
|
896
|
+
server = createServer(async (req, res) => {
|
|
872
897
|
const url = new URL(req.url, `http://localhost:${PORT}`);
|
|
873
898
|
const path = url.pathname;
|
|
874
899
|
|
|
@@ -1402,16 +1427,20 @@ const server = createServer(async (req, res) => {
|
|
|
1402
1427
|
json(res, 500, { error: String(err?.stack ?? err) });
|
|
1403
1428
|
}
|
|
1404
1429
|
});
|
|
1405
|
-
// When run directly (node server.mjs), start listening immediately.
|
|
1406
|
-
// When imported as a module (by extension.mjs), export control functions.
|
|
1407
|
-
const isDirectRun = process.argv[1] && resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));
|
|
1408
1430
|
|
|
1409
|
-
|
|
1431
|
+
_booted = true;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
// When run directly (node server.mjs), boot and listen immediately.
|
|
1435
|
+
const _isDirect = process.argv[1] && resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));
|
|
1436
|
+
if (_isDirect) {
|
|
1437
|
+
await boot();
|
|
1410
1438
|
server.listen(PORT, () => console.log(`[pi-web-ui] listening on http://localhost:${PORT}`));
|
|
1411
1439
|
}
|
|
1412
1440
|
|
|
1413
|
-
export {
|
|
1414
|
-
export function startServer(port) {
|
|
1441
|
+
export { PORT };
|
|
1442
|
+
export async function startServer(port) {
|
|
1443
|
+
await boot();
|
|
1415
1444
|
return new Promise((res, rej) => {
|
|
1416
1445
|
server.listen(port || PORT, () => {
|
|
1417
1446
|
console.log(`[pi-web-ui] listening on http://localhost:${port || PORT}`);
|
|
@@ -1420,6 +1449,6 @@ export function startServer(port) {
|
|
|
1420
1449
|
server.on("error", rej);
|
|
1421
1450
|
});
|
|
1422
1451
|
}
|
|
1423
|
-
export function stopServer() {
|
|
1424
|
-
return new Promise((res) => server.close(() => res()));
|
|
1452
|
+
export async function stopServer() {
|
|
1453
|
+
if (server) return new Promise((res) => server.close(() => res()));
|
|
1425
1454
|
}
|