pi-sdk-web 0.5.17 → 0.5.18

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/cli.js CHANGED
@@ -16,6 +16,7 @@ import { getHeapStatistics } from "node:v8";
16
16
  import { dirname, join } from "node:path";
17
17
  import { findSessionByName, listSessions, loadBuiltinExtensions } from "./session.js";
18
18
  import { PiWebServer } from "./server.js";
19
+ import { logError, logInfo } from "./log.js";
19
20
  // ---------------------------------------------------------------------------
20
21
  // Pretend to be Pi for in-process extensions.
21
22
  //
@@ -90,11 +91,11 @@ function ensureHeapHeadroom() {
90
91
  return false; // close enough already
91
92
  const totalMb = totalmem() / (1024 * 1024);
92
93
  if (totalMb < target * 2) {
93
- console.log(`heap: keeping the default limit (${heapLimitMb().toFixed(0)}MB) - ` +
94
+ logInfo(`heap: keeping the default limit (${heapLimitMb().toFixed(0)}MB) - ` +
94
95
  `raising it to ${target}MB needs ~${target * 2}MB of RAM, host has ${totalMb.toFixed(0)}MB`);
95
96
  return false;
96
97
  }
97
- console.log(`heap: restarting with --max-old-space-size=${target} (current limit ${heapLimitMb().toFixed(0)}MB)`);
98
+ logInfo(`heap: restarting with --max-old-space-size=${target} (current limit ${heapLimitMb().toFixed(0)}MB)`);
98
99
  const child = spawn(process.execPath, [`--max-old-space-size=${target}`, fileURLToPath(import.meta.url), ...process.argv.slice(2)], { stdio: "inherit", env: { ...process.env, PI_WEB_HEAP_REEXEC: "1" } });
99
100
  // Stay alive without acting on the signal ourselves: the child is in the
100
101
  // same process group and runs its own graceful shutdown, and we exit with
@@ -103,7 +104,7 @@ function ensureHeapHeadroom() {
103
104
  process.on("SIGTERM", () => { });
104
105
  child.on("exit", (code, signal) => process.exit(signal ? 1 : (code ?? 1)));
105
106
  child.on("error", (err) => {
106
- console.error(`heap: failed to restart with a larger heap: ${err.message}`);
107
+ logError(`heap: failed to restart with a larger heap: ${err.message}`);
107
108
  process.exit(1);
108
109
  });
109
110
  return true;
@@ -145,7 +146,7 @@ async function cmdResume(name, port) {
145
146
  }
146
147
  catch {
147
148
  // Session cwd no longer exists - keep current directory (same as pii)
148
- console.error(`Session cwd not found (${cwd}), keeping current directory`);
149
+ logError(`Session cwd not found (${cwd}), keeping current directory`);
149
150
  }
150
151
  }
151
152
  // Create services the way Pi's CLI does: extensions (including built-in
@@ -186,14 +187,14 @@ async function cmdResume(name, port) {
186
187
  const { session } = runtime;
187
188
  const server = new PiWebServer(runtime, { port });
188
189
  await server.start();
189
- console.log(`server at http://127.0.0.1:${port}/ (session: ${info.name ?? info.id})`);
190
- console.log(`heap limit: ${heapLimitMb().toFixed(0)}MB`);
190
+ logInfo(`server at http://127.0.0.1:${port}/ (session: ${info.name ?? info.id})`);
191
+ logInfo(`heap limit: ${heapLimitMb().toFixed(0)}MB`);
191
192
  let shuttingDown = false;
192
193
  const shutdown = async (signal) => {
193
194
  if (shuttingDown)
194
195
  return; // Repeated Ctrl+C must not re-enter teardown
195
196
  shuttingDown = true;
196
- console.log(`\n${signal} received, shutting down...`);
197
+ logInfo(`${signal} received, shutting down...`);
197
198
  try {
198
199
  await server.stop();
199
200
  }
package/dist/log.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Timestamped logging for pi-web's own diagnostics.
3
+ *
4
+ * pi-web is a long-running server: its warnings (backpressure, memory
5
+ * watermarks, session issues) are read minutes to hours after the fact and
6
+ * mixed with other processes' output, so every line carries a local timestamp
7
+ * (`[2026-09-12 08:15:30] pi-web: …`).
8
+ *
9
+ * Only pi-web's own log lines go through here - command output (session
10
+ * lists, help text) stays plain so it can be piped or copied as-is.
11
+ */
12
+ function timestamp(now) {
13
+ const pad = (n) => String(n).padStart(2, "0");
14
+ return (`${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ` +
15
+ `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`);
16
+ }
17
+ /** Informational line (startup, status) on stdout. */
18
+ export function logInfo(message) {
19
+ console.log(`[${timestamp(new Date())}] ${message}`);
20
+ }
21
+ /** Diagnostic warning on stderr. */
22
+ export function logWarn(message) {
23
+ console.warn(`[${timestamp(new Date())}] ${message}`);
24
+ }
25
+ /** Error line on stderr. */
26
+ export function logError(message) {
27
+ console.error(`[${timestamp(new Date())}] ${message}`);
28
+ }
package/dist/server.js CHANGED
@@ -18,6 +18,7 @@ import { ModelRegistry, VERSION, } from "@earendil-works/pi-coding-agent";
18
18
  import { WebSocket, WebSocketServer } from "ws";
19
19
  import { listSessions } from "./session.js";
20
20
  import { WebUIContext } from "./ui-context.js";
21
+ import { logError, logWarn } from "./log.js";
21
22
  const DEFAULT_PORT = 4080;
22
23
  // Static frontend: prefer the in-package copy (built by `npm run build` for
23
24
  // global installs), fall back to the repo-root static/ during development.
@@ -202,7 +203,7 @@ export class PiWebServer {
202
203
  process.chdir(cwd);
203
204
  }
204
205
  catch {
205
- console.error(`Session cwd not found (${cwd}), keeping current directory`);
206
+ logError(`Session cwd not found (${cwd}), keeping current directory`);
206
207
  }
207
208
  }
208
209
  this.broadcastState();
@@ -272,7 +273,7 @@ export class PiWebServer {
272
273
  if (buffered > WS_BUFFER_HARD_LIMIT) {
273
274
  // Far beyond reading - treat as gone. The browser reconnects and
274
275
  // reloads, so no state is lost, and memory stays bounded.
275
- console.warn(`pi-web: client not reading (${(buffered / 1048576).toFixed(0)}MB queued) - closing it; ` +
276
+ logWarn(`pi-web: client not reading (${(buffered / 1048576).toFixed(0)}MB queued) - closing it; ` +
276
277
  "the browser will reconnect and reload history");
277
278
  this.backpressured.delete(client);
278
279
  client.terminate();
@@ -281,14 +282,14 @@ export class PiWebServer {
281
282
  if (droppable && buffered > WS_BUFFER_SOFT_LIMIT) {
282
283
  if (!this.backpressured.has(client)) {
283
284
  this.backpressured.add(client);
284
- console.warn(`pi-web: client is behind (${(buffered / 1048576).toFixed(1)}MB queued) - ` +
285
+ logWarn(`pi-web: client is behind (${(buffered / 1048576).toFixed(1)}MB queued) - ` +
285
286
  "skipping stream deltas until it catches up");
286
287
  }
287
288
  continue;
288
289
  }
289
290
  if (this.backpressured.has(client) && buffered < WS_BUFFER_SOFT_LIMIT / 2) {
290
291
  this.backpressured.delete(client);
291
- console.warn("pi-web: client caught up - stream deltas resumed");
292
+ logWarn("pi-web: client caught up - stream deltas resumed");
292
293
  }
293
294
  try {
294
295
  client.send(message);
@@ -319,7 +320,7 @@ export class PiWebServer {
319
320
  continue;
320
321
  this.memoryLogged.add(threshold);
321
322
  const queued = [...this.clients].map((c) => `${(c.bufferedAmount / 1048576).toFixed(1)}MB`).join(", ") || "no clients";
322
- console.warn(`pi-web: memory ${rssMb.toFixed(0)}MB (heap ${(heapUsed / 1048576).toFixed(0)}/` +
323
+ logWarn(`pi-web: memory ${rssMb.toFixed(0)}MB (heap ${(heapUsed / 1048576).toFixed(0)}/` +
323
324
  `${(heapTotal / 1048576).toFixed(0)}MB), queued per client: ${queued}`);
324
325
  }
325
326
  }
@@ -430,7 +431,7 @@ export class PiWebServer {
430
431
  // the largest single payload, so a client that never reads it must not be
431
432
  // allowed to queue forever.
432
433
  if (ws.bufferedAmount > WS_BUFFER_HARD_LIMIT) {
433
- console.warn("pi-web: client not reading its initial snapshot - closing it");
434
+ logWarn("pi-web: client not reading its initial snapshot - closing it");
434
435
  ws.terminate();
435
436
  return;
436
437
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-sdk-web",
3
- "version": "0.5.17",
3
+ "version": "0.5.18",
4
4
  "description": "Browser Web access for Pi (AI coding agent) via the Pi SDK - standalone module, zero modification to Pi itself",
5
5
  "type": "module",
6
6
  "bin": {