@qt4798/pi-web 0.18.12 → 0.18.13

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.
Files changed (49) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +28 -28
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/required-server-files.js +1 -1
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/server/app/_not-found.html +1 -1
  15. package/.next/server/app/_not-found.rsc +1 -1
  16. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/.next/server/app/api/app-update/route.js +1 -1
  20. package/.next/server/app/api/files/[...path]/route.js +1 -1
  21. package/.next/server/app/index.html +1 -1
  22. package/.next/server/app/index.rsc +3 -3
  23. package/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
  24. package/.next/server/app/index.segments/_full.segment.rsc +3 -3
  25. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  26. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  27. package/.next/server/app/login.html +1 -1
  28. package/.next/server/app/login.rsc +1 -1
  29. package/.next/server/app/login.segments/_full.segment.rsc +1 -1
  30. package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  31. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  32. package/.next/server/app/page.js +1 -1
  33. package/.next/server/app/page_client-reference-manifest.js +1 -1
  34. package/.next/server/app-paths-manifest.json +28 -28
  35. package/.next/server/chunks/7915.js +1 -1
  36. package/.next/server/middleware-build-manifest.js +1 -1
  37. package/.next/server/pages/404.html +1 -1
  38. package/.next/server/pages/500.html +1 -1
  39. package/.next/server/server-reference-manifest.json +1 -1
  40. package/.next/static/chunks/app/{page-abc85eb2cca48bce.js → page-d143bb27f37954c7.js} +1 -1
  41. package/.next/trace +85 -84
  42. package/.next/trace-build +1 -1
  43. package/bin/fix-pi-agent-undici.js +4 -2
  44. package/bin/memory-watchdog.js +11 -2
  45. package/bin/pi-web.js +3 -1
  46. package/bin/with-memory-limit.js +28 -47
  47. package/package.json +3 -3
  48. /package/.next/static/{fs5JGinkTfT6aWXJqEdny → WSLpXBoGysol2bo7ZrmzF}/_buildManifest.js +0 -0
  49. /package/.next/static/{fs5JGinkTfT6aWXJqEdny → WSLpXBoGysol2bo7ZrmzF}/_ssgManifest.js +0 -0
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"run-webpack","duration":106255508,"timestamp":210837769574,"id":14,"parentId":1,"tags":{},"startTime":1791037121316,"traceId":"e9b9cef13ff3e0d4"},{"name":"run-typescript","duration":21415900,"timestamp":210944153845,"id":18321,"parentId":1,"tags":{},"startTime":1791037227688,"traceId":"e9b9cef13ff3e0d4"},{"name":"static-check","duration":7861741,"timestamp":210965597191,"id":18324,"parentId":1,"tags":{},"startTime":1791037249131,"traceId":"e9b9cef13ff3e0d4"},{"name":"static-generation","duration":4867979,"timestamp":210973928262,"id":18530,"parentId":1,"tags":{},"startTime":1791037257462,"traceId":"e9b9cef13ff3e0d4"},{"name":"collect-build-traces","duration":39015822,"timestamp":210973465847,"id":18527,"parentId":1,"tags":{},"startTime":1791037256999,"traceId":"e9b9cef13ff3e0d4"},{"name":"output-standalone","duration":7147307,"timestamp":211012482313,"id":18538,"parentId":1,"tags":{},"startTime":1791037296016,"traceId":"e9b9cef13ff3e0d4"},{"name":"telemetry-flush","duration":86,"timestamp":211019637118,"id":18541,"parentId":1,"tags":{},"startTime":1791037303171,"traceId":"e9b9cef13ff3e0d4"},{"name":"next-build","duration":182062040,"timestamp":210837575179,"id":1,"tags":{"buildMode":"default","version":"16.3.6","bundler":"webpack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1791037121122,"traceId":"e9b9cef13ff3e0d4"}]
1
+ [{"name":"run-webpack","duration":80717446,"timestamp":213926471571,"id":14,"parentId":1,"tags":{},"startTime":1791040210038,"traceId":"25b023912ecd0716"},{"name":"run-typescript","duration":15348693,"timestamp":214007209920,"id":18322,"parentId":1,"tags":{},"startTime":1791040290777,"traceId":"25b023912ecd0716"},{"name":"static-check","duration":5848786,"timestamp":214022576785,"id":18325,"parentId":1,"tags":{},"startTime":1791040306144,"traceId":"25b023912ecd0716"},{"name":"static-generation","duration":5544919,"timestamp":214028920696,"id":18531,"parentId":1,"tags":{},"startTime":1791040312488,"traceId":"25b023912ecd0716"},{"name":"collect-build-traces","duration":41451080,"timestamp":214028432664,"id":18528,"parentId":1,"tags":{},"startTime":1791040312000,"traceId":"25b023912ecd0716"},{"name":"output-standalone","duration":3774277,"timestamp":214069884223,"id":18539,"parentId":1,"tags":{},"startTime":1791040353451,"traceId":"25b023912ecd0716"},{"name":"telemetry-flush","duration":32,"timestamp":214073664684,"id":18542,"parentId":1,"tags":{},"startTime":1791040357232,"traceId":"25b023912ecd0716"},{"name":"next-build","duration":147255071,"timestamp":213926409652,"id":1,"tags":{"buildMode":"default","version":"16.3.6","bundler":"webpack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1791040209976,"traceId":"25b023912ecd0716"}]
@@ -73,8 +73,10 @@ function applyUndiciFix(rootDir = path.join(__dirname, ".."), opts = {}) {
73
73
  if (!fs.existsSync(topUndici)) return;
74
74
 
75
75
  try {
76
- const nestedVersion = require(path.join(nestedUndici, "package.json")).version;
77
- const topVersion = require(path.join(topUndici, "package.json")).version;
76
+ // Read the manifests as data (never require() a path built from config —
77
+ // requiring would execute module code from an externally-resolved location).
78
+ const nestedVersion = JSON.parse(fs.readFileSync(path.join(nestedUndici, "package.json"), "utf8")).version;
79
+ const topVersion = JSON.parse(fs.readFileSync(path.join(topUndici, "package.json"), "utf8")).version;
78
80
  // Already a real dir with the correct version → nothing to do.
79
81
  if (!nestedIsSymlink && nestedVersion === topVersion) return;
80
82
 
@@ -36,7 +36,6 @@ function resolveConfig(env) {
36
36
  if (!Number.isFinite(port) || port <= 0) return null;
37
37
  return {
38
38
  port,
39
- hostname: env.PI_WEB_HOSTNAME || "127.0.0.1",
40
39
  restartMb: parsePositiveInt(rawRestart, DEFAULT_RESTART_MB, 1),
41
40
  checkMinutes: parsePositiveInt(env.PI_WEB_RSS_CHECK_MINUTES, DEFAULT_CHECK_MINUTES, 1),
42
41
  };
@@ -52,7 +51,17 @@ function basicAuthHeaders(env) {
52
51
  }
53
52
 
54
53
  async function isServerIdle(config, env) {
55
- const res = await fetch(`http://${config.hostname}:${config.port}/api/agent/running`, {
54
+ // Literal loopback origin: the watchdog self-checks THIS process, which
55
+ // always answers on 127.0.0.1 regardless of the LAN bind address (-H), so
56
+ // the probe target is never derived from the environment. Only the port is
57
+ // injected, as a validated numeric URL component.
58
+ const probeUrl = new URL("/api/agent/running", "http://127.0.0.1");
59
+ const port = Number.isFinite(config.port) && config.port >= 1024 && config.port <= 65535
60
+ ? config.port
61
+ : 0;
62
+ if (!port) return null;
63
+ probeUrl.port = String(port);
64
+ const res = await fetch(probeUrl, {
56
65
  headers: basicAuthHeaders(env),
57
66
  signal: AbortSignal.timeout(RUNNING_CHECK_TIMEOUT_MS),
58
67
  });
package/bin/pi-web.js CHANGED
@@ -182,7 +182,9 @@ child.stdout.on("data", (chunk) => {
182
182
  if (isWindows) {
183
183
  // `start` is a cmd.exe built-in, so invoke cmd directly. The empty
184
184
  // title argument is required by `start` before the target URL.
185
- opener = spawn(process.env.ComSpec || "cmd.exe", ["/c", "start", "", url], {
185
+ // Literal "cmd.exe" (not %ComSpec%): the system shell is a fixed
186
+ // program, never taken from the environment.
187
+ opener = spawn("cmd.exe", ["/c", "start", "", url], {
186
188
  stdio: "ignore",
187
189
  detached: true,
188
190
  });
@@ -6,64 +6,45 @@ const { spawnSync } = require("child_process");
6
6
  /** Keep the V8 heap from ballooning during local runs. Next.js dev auto-sets
7
7
  * --max-old-space-size to 50% of physical RAM (12GB on a 24GB machine)
8
8
  * unless the user already capped it. A 3GB cap makes GC engage earlier and
9
- * bounds RSS growth for both dev and production start.
10
- */
11
- const MEMORY_LIMIT_MB = 3072;
12
- const SEMI_SPACE_MB = 128;
13
-
14
- /**
15
- * Merge a heap cap into an existing NODE_OPTIONS value. If the user already
16
- * set --max-old-space-size explicitly, theirs wins (we only add the semi-space
17
- * hint); otherwise we append both flags so V8 and Next.js see a hard cap.
9
+ * bounds RSS growth for both dev and production start. Also consumed by
10
+ * bin/pi-web.js to seed NODE_OPTIONS before spawning the server.
18
11
  */
19
12
  function mergedNodeOptions(existing) {
20
13
  const base = existing ?? "";
21
14
  const hasHeapLimit = /(^|\s)--max-old-space-size=\d+/.test(base);
22
- const flags = hasHeapLimit ? [] : [`--max-old-space-size=${MEMORY_LIMIT_MB}`, `--max-semi-space-size=${SEMI_SPACE_MB}`];
15
+ const flags = hasHeapLimit ? [] : [`--max-old-space-size=3072`, `--max-semi-space-size=128`];
23
16
  return [...flags, base].filter(Boolean).join(" ");
24
17
  }
25
18
 
26
- module.exports = { mergedNodeOptions, MEMORY_LIMIT_MB, SEMI_SPACE_MB };
19
+ module.exports = { mergedNodeOptions };
20
+
21
+ // CLI: with-memory-limit <task> — runs a fixed Next.js task with the capped
22
+ // heap. Each task is a fully literal spawn (constant program, constant argv,
23
+ // relative to the package root that npm scripts guarantee as cwd), so nothing
24
+ // from the command line or environment ever reaches a spawn. The heap cap
25
+ // rides as literal V8 flags in argv, which take precedence over any inherited
26
+ // NODE_OPTIONS for this process tree.
27
27
 
28
- // CLI: with-memory-limit <cmd> [args...] — runs cmd with the capped heap.
29
- // Child processes spawned by cmd inherit NODE_OPTIONS, so next dev / next
30
- // start and their next-server children all see the same limit.
31
28
  if (require.main === module) {
32
- const [cmd, ...args] = process.argv.slice(2);
33
- if (!cmd) {
34
- console.error("usage: node bin/with-memory-limit.js <cmd> [args...]");
35
- process.exit(1);
36
- }
37
- const env = { ...process.env, NODE_OPTIONS: mergedNodeOptions(process.env.NODE_OPTIONS) };
29
+ const [taskName] = process.argv.slice(2);
38
30
  let result;
39
- if (process.platform === "win32") {
40
- // spawnSync cannot execute npm's extensionless .bin shims on Windows
41
- // (ENOENT), and .cmd shims need cmd.exe (EINVAL since the Node CVE fix).
42
- // Prefer the .cmd/.bat sibling and run it through %ComSpec%.
43
- const fs = require("fs");
44
- let target = cmd;
45
- if (!/\.(exe|cmd|bat)$/i.test(target)) {
46
- for (const ext of [".cmd", ".bat"]) {
47
- if (fs.existsSync(target + ext)) {
48
- target += ext;
49
- break;
50
- }
51
- }
52
- }
53
- if (/\.(cmd|bat)$/i.test(target)) {
54
- // cmd.exe parses `/` as a switch character, so hand it a native path.
55
- const native = require("path").win32.normalize(target);
56
- const quote = (a) => (/["&<>^|()%!?\s]/.test(a) ? `"${a}"` : a);
57
- const line = [native, ...args].map(quote).join(" ");
58
- result = spawnSync(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", line], {
59
- stdio: "inherit",
60
- env,
61
- });
62
- } else {
63
- result = spawnSync(target, args, { stdio: "inherit", env });
64
- }
31
+ if (taskName === "nextDev") {
32
+ result = spawnSync("node", [
33
+ "--max-old-space-size=3072",
34
+ "--max-semi-space-size=128",
35
+ "node_modules/next/dist/bin/next",
36
+ "dev", "-H", "127.0.0.1", "-p", "0", "--turbopack",
37
+ ], { stdio: "inherit" });
38
+ } else if (taskName === "nextStart") {
39
+ result = spawnSync("node", [
40
+ "--max-old-space-size=3072",
41
+ "--max-semi-space-size=128",
42
+ "node_modules/next/dist/bin/next",
43
+ "start", "-H", "127.0.0.1", "-p", "0",
44
+ ], { stdio: "inherit" });
65
45
  } else {
66
- result = spawnSync(cmd, args, { stdio: "inherit", env });
46
+ console.error("usage: node bin/with-memory-limit.js nextDev|nextStart");
47
+ process.exit(1);
67
48
  }
68
49
  if (result.error) {
69
50
  console.error(`with-memory-limit: ${result.error.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qt4798/pi-web",
3
- "version": "0.18.12",
3
+ "version": "0.18.13",
4
4
  "description": "Web workspace for the pi coding agent",
5
5
  "homepage": "https://github.com/t479842598/pi-web-QT#readme",
6
6
  "repository": {
@@ -30,14 +30,14 @@
30
30
  "package.json"
31
31
  ],
32
32
  "scripts": {
33
- "dev": "node bin/fix-pi-agent-undici.js && node bin/with-memory-limit.js node_modules/.bin/next dev -H 127.0.0.1 -p 0 --turbopack",
33
+ "dev": "node bin/fix-pi-agent-undici.js && node bin/with-memory-limit.js nextDev",
34
34
  "dev:lan": "node bin/fix-pi-agent-undici.js && node bin/with-memory-limit.js node_modules/.bin/next dev -H 0.0.0.0 -p 0 --turbopack",
35
35
  "postinstall": "node bin/prepare-terminal.js",
36
36
  "theme:css": "node scripts/generate-theme-css.mjs",
37
37
  "prebuild": "node scripts/generate-theme-css.mjs",
38
38
  "build": "env -u TURBOPACK -u __NEXT_PRIVATE_STANDALONE_CONFIG next build --webpack",
39
39
  "bundle:backend": "node scripts/bundle-backend.mjs",
40
- "start": "node bin/fix-pi-agent-undici.js && node bin/with-memory-limit.js node_modules/.bin/next start -H 127.0.0.1 -p 0",
40
+ "start": "node bin/fix-pi-agent-undici.js && node bin/with-memory-limit.js nextStart",
41
41
  "start:lan": "node bin/fix-pi-agent-undici.js && node bin/with-memory-limit.js node_modules/.bin/next start -H 0.0.0.0 -p 0",
42
42
  "lint": "eslint .",
43
43
  "release": "npm version patch --no-git-tag-version && npm run build && npm publish --access public",