pi-app 0.7.6 → 0.8.1

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 (96) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +3 -3
  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/_global-error.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  24. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  25. package/.next/server/app/api/agent/[id]/events/route.js +1 -1
  26. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  27. package/.next/server/app/api/agent/[id]/export.html/route.js +1 -1
  28. package/.next/server/app/api/agent/[id]/export.html/route.js.nft.json +1 -1
  29. package/.next/server/app/api/agent/[id]/route.js +1 -1
  30. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  31. package/.next/server/app/api/agent/new/route.js +1 -1
  32. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  33. package/.next/server/app/api/files/[...path]/route.js +3 -3
  34. package/.next/server/app/api/files/[...path]/route.js.nft.json +1 -1
  35. package/.next/server/app/api/history/[id]/route.js +1 -2
  36. package/.next/server/app/api/history/[id]/route.js.nft.json +1 -1
  37. package/.next/server/app/api/history/route.js +1 -2
  38. package/.next/server/app/api/history/route.js.nft.json +1 -1
  39. package/.next/server/app/api/models-config/route.js +1 -1
  40. package/.next/server/app/api/models-config/route.js.nft.json +1 -1
  41. package/.next/server/app/api/product-sessions/[id]/route.js +2 -3
  42. package/.next/server/app/api/product-sessions/[id]/route.js.nft.json +1 -1
  43. package/.next/server/app/api/sessions/[id]/context/route.js +1 -2
  44. package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +1 -1
  45. package/.next/server/app/api/sessions/[id]/export/route.js +1 -2
  46. package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
  47. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  48. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  49. package/.next/server/app/api/sessions/[id]/share/route.js +1 -1
  50. package/.next/server/app/api/sessions/route.js +1 -2
  51. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  52. package/.next/server/app/api/share/[token]/route.js +1 -2
  53. package/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
  54. package/.next/server/app/api/terminal/run/[...cwd]/route.js +1 -1
  55. package/.next/server/app/api/terminal/run/[...cwd]/route.js.nft.json +1 -1
  56. package/.next/server/app/api/terminal/state/[...cwd]/route.js +1 -1
  57. package/.next/server/app/api/terminal/state/[...cwd]/route.js.nft.json +1 -1
  58. package/.next/server/app/api/terminal/stop/[...cwd]/route.js +1 -1
  59. package/.next/server/app/api/terminal/stop/[...cwd]/route.js.nft.json +1 -1
  60. package/.next/server/app/api/terminal/stream/[...cwd]/route.js +1 -1
  61. package/.next/server/app/api/terminal/stream/[...cwd]/route.js.nft.json +1 -1
  62. package/.next/server/app/api/usage/route.js +1 -2
  63. package/.next/server/app/api/usage/route.js.nft.json +1 -1
  64. package/.next/server/app/index.html +1 -1
  65. package/.next/server/app/index.rsc +2 -2
  66. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  67. package/.next/server/app/index.segments/_full.segment.rsc +2 -2
  68. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  69. package/.next/server/app/index.segments/_index.segment.rsc +1 -1
  70. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  71. package/.next/server/app/page.js +2 -2
  72. package/.next/server/app/page_client-reference-manifest.js +1 -1
  73. package/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
  74. package/.next/server/app-paths-manifest.json +3 -3
  75. package/.next/server/chunks/1185.js +2 -2
  76. package/.next/server/chunks/402.js +2 -0
  77. package/.next/server/chunks/{3768.js → 5192.js} +1 -1
  78. package/.next/server/chunks/6429.js +1 -2
  79. package/.next/server/middleware-build-manifest.js +1 -1
  80. package/.next/server/middleware-manifest.json +5 -5
  81. package/.next/server/pages/404.html +1 -1
  82. package/.next/server/pages/500.html +1 -1
  83. package/.next/server/server-reference-manifest.json +1 -1
  84. package/.next/static/chunks/app/page-84b8dd2798476830.js +2 -0
  85. package/.next/trace +84 -84
  86. package/.next/trace-build +1 -1
  87. package/README.md +15 -0
  88. package/bin/pi.js +29 -0
  89. package/package.json +6 -1
  90. package/scripts/cli-link-common.mjs +110 -0
  91. package/scripts/install-cli.mjs +108 -0
  92. package/scripts/uninstall-cli.mjs +35 -0
  93. package/.next/server/chunks/6402.js +0 -2
  94. package/.next/static/chunks/app/page-275366a69e4447f4.js +0 -2
  95. /package/.next/static/{ScSrh8Z0sCMWAflRLnYlw → jWlwtI3NyKCLPvodN51mW}/_buildManifest.js +0 -0
  96. /package/.next/static/{ScSrh8Z0sCMWAflRLnYlw → jWlwtI3NyKCLPvodN51mW}/_ssgManifest.js +0 -0
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"run-webpack","duration":29549708,"timestamp":93152510,"id":14,"parentId":1,"tags":{},"startTime":1781179315316,"traceId":"1232ccadb30f6e97"},{"name":"run-typescript","duration":9259082,"timestamp":122706335,"id":8604,"parentId":1,"tags":{},"startTime":1781179344870,"traceId":"1232ccadb30f6e97"},{"name":"static-check","duration":1911797,"timestamp":132034473,"id":8607,"parentId":1,"tags":{},"startTime":1781179354198,"traceId":"1232ccadb30f6e97"},{"name":"static-generation","duration":5711903,"timestamp":134429306,"id":8723,"parentId":1,"tags":{},"startTime":1781179356593,"traceId":"1232ccadb30f6e97"},{"name":"collect-build-traces","duration":43009643,"timestamp":133948727,"id":8720,"parentId":1,"tags":{},"startTime":1781179356112,"traceId":"1232ccadb30f6e97"},{"name":"telemetry-flush","duration":56,"timestamp":176962689,"id":8732,"parentId":1,"tags":{},"startTime":1781179399126,"traceId":"1232ccadb30f6e97"},{"name":"next-build","duration":83965833,"timestamp":92996925,"id":1,"tags":{"buildMode":"default","version":"16.2.6","bundler":"webpack","has-custom-webpack-config":"true","use-build-worker":"false"},"startTime":1781179315160,"traceId":"1232ccadb30f6e97"}]
1
+ [{"name":"run-webpack","duration":27621811,"timestamp":103599810,"id":14,"parentId":1,"tags":{},"startTime":1781236908245,"traceId":"5f754b610205c293"},{"name":"run-typescript","duration":9176197,"timestamp":131225701,"id":8606,"parentId":1,"tags":{},"startTime":1781236935871,"traceId":"5f754b610205c293"},{"name":"static-check","duration":2013706,"timestamp":140462785,"id":8609,"parentId":1,"tags":{},"startTime":1781236945108,"traceId":"5f754b610205c293"},{"name":"static-generation","duration":5691335,"timestamp":142616080,"id":8725,"parentId":1,"tags":{},"startTime":1781236947261,"traceId":"5f754b610205c293"},{"name":"collect-build-traces","duration":44982767,"timestamp":142478872,"id":8722,"parentId":1,"tags":{},"startTime":1781236947124,"traceId":"5f754b610205c293"},{"name":"telemetry-flush","duration":46,"timestamp":187465911,"id":8734,"parentId":1,"tags":{},"startTime":1781236992111,"traceId":"5f754b610205c293"},{"name":"next-build","duration":84163070,"timestamp":103302897,"id":1,"tags":{"buildMode":"default","version":"16.2.6","bundler":"webpack","has-custom-webpack-config":"true","use-build-worker":"false"},"startTime":1781236907948,"traceId":"5f754b610205c293"}]
package/README.md CHANGED
@@ -19,6 +19,21 @@ pi-app
19
19
 
20
20
  启动后打开 [http://localhost:30141](http://localhost:30141)。
21
21
 
22
+ **一并提供 `pi` 命令行:**
23
+
24
+ 全局安装 pi-app 时会顺带提供 `pi` 命令(即 pi 编程智能体 CLI,与 pi-app 内置版本一致),无需单独安装:
25
+
26
+ ```bash
27
+ npm install -g pi-app
28
+ pi --help # 直接使用 pi CLI
29
+ ```
30
+
31
+ 行为说明:
32
+
33
+ - 安装后仅当系统中**尚未存在** `pi` 命令时,才会创建 `pi`(一个转发到 pi-app 内置 CLI 的独立 shim)。
34
+ - 若你已单独安装过 `pi`(如通过 `npm i -g @earendil-works/pi-coding-agent` 或 Homebrew),则**保留你已有的版本,不会覆盖**。
35
+ - 卸载说明:npm **不会**执行卸载钩子(`postuninstall`),因此 `npm uninstall -g pi-app` 后这个 `pi` shim 会残留。它是独立 shim 而非失效软链——此时运行 `pi` 不会报「文件不存在」,而是友好提示你重新安装 pi-app 或删除该文件(提示里会给出确切路径)。如需立即清理,按提示删除该 `pi` 文件即可(不会影响你自行安装的其他 `pi`)。
36
+
22
37
  **可选参数:**
23
38
 
24
39
  ```bash
package/bin/pi.js ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // Thin launcher that forwards to the pi coding-agent CLI bundled with pi-app.
5
+ // Installed (symlinked / shimmed) as the global `pi` command by
6
+ // scripts/install-cli.mjs, but ONLY when no `pi` already exists on the system.
7
+ //
8
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
9
+ const path = require("path");
10
+
11
+ let cliPath;
12
+ try {
13
+ cliPath = require.resolve("@earendil-works/pi-coding-agent/dist/cli.js");
14
+ } catch {
15
+ // Fallback to the package-local node_modules layout if resolution fails.
16
+ cliPath = path.join(
17
+ __dirname,
18
+ "..",
19
+ "node_modules",
20
+ "@earendil-works",
21
+ "pi-coding-agent",
22
+ "dist",
23
+ "cli.js",
24
+ );
25
+ }
26
+
27
+ // cli.js reads process.argv.slice(2) itself; requiring it runs the CLI.
28
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
29
+ require(cliPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-app",
3
- "version": "0.7.6",
3
+ "version": "0.8.1",
4
4
  "description": "Web UI for the pi coding agent",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/asiachrispy/pi-app",
@@ -16,6 +16,9 @@
16
16
  },
17
17
  "files": [
18
18
  "bin",
19
+ "scripts/install-cli.mjs",
20
+ "scripts/uninstall-cli.mjs",
21
+ "scripts/cli-link-common.mjs",
19
22
  ".next",
20
23
  "!.next/cache",
21
24
  "!.next/dev",
@@ -36,6 +39,8 @@
36
39
  "test:m2": "node scripts/m2-preflight.mjs",
37
40
  "test:m3": "node scripts/m3-preflight.mjs",
38
41
  "test:m4": "node scripts/m4-preflight.mjs",
42
+ "postinstall": "node scripts/install-cli.mjs",
43
+ "postuninstall": "node scripts/uninstall-cli.mjs",
39
44
  "package:macos": "bash scripts/package-macos-app.sh",
40
45
  "tunnel:cloudflare": "bash scripts/tunnel-cloudflared.sh",
41
46
  "relay:server": "node --experimental-strip-types scripts/pi-relay-server.ts",
@@ -0,0 +1,110 @@
1
+ // Shared helpers for installing/uninstalling the global `pi` command that
2
+ // forwards to the pi coding-agent CLI bundled with pi-app.
3
+ //
4
+ // Design notes:
5
+ // - We deliberately do NOT declare `bin.pi` in package.json. npm refuses to
6
+ // overwrite a global bin owned by another package (EEXIST) and would make
7
+ // `npm i -g pi-app` fail outright when the user already has `pi` installed.
8
+ // - Instead postinstall conditionally creates the link only when no `pi`
9
+ // exists, and removes it only if we are the ones who made it.
10
+ // - The global `pi` is a STANDALONE shim (not a symlink into the package).
11
+ // npm does not run uninstall lifecycle scripts (postuninstall), so after
12
+ // `npm uninstall -g pi-app` the shim would otherwise dangle. A standalone
13
+ // shim degrades gracefully: running `pi` then prints how to reinstall/remove
14
+ // instead of failing with a confusing "no such file" error.
15
+
16
+ import { execFileSync } from "node:child_process";
17
+ import { chmodSync, lstatSync, readFileSync } from "node:fs";
18
+ import { dirname, join, resolve } from "node:path";
19
+ import { fileURLToPath } from "node:url";
20
+
21
+ export const isWindows = process.platform === "win32";
22
+
23
+ /** Marker embedded in every shim we generate, used to detect ownership. */
24
+ export const SHIM_MARKER = "pi-app-managed-cli";
25
+
26
+ const here = dirname(fileURLToPath(import.meta.url));
27
+
28
+ /** pi-app package root (the dir containing package.json). */
29
+ export function getPkgRoot() {
30
+ return resolve(here, "..");
31
+ }
32
+
33
+ /** Absolute path to the launcher the shim forwards to. */
34
+ export function getLauncherPath() {
35
+ return join(getPkgRoot(), "bin", "pi.js");
36
+ }
37
+
38
+ /** True when npm is running this lifecycle script for a global install. */
39
+ export function isGlobalInstall() {
40
+ return process.env.npm_config_global === "true";
41
+ }
42
+
43
+ /**
44
+ * Resolve the directory npm links global bins into.
45
+ * Unix: <prefix>/bin. Windows: <prefix> itself.
46
+ */
47
+ export function getGlobalBinDir() {
48
+ const prefix = process.env.npm_config_prefix;
49
+ if (prefix) return isWindows ? prefix : join(prefix, "bin");
50
+
51
+ // Fallback: derive from the install location of this package.
52
+ // Unix: <prefix>/lib/node_modules/pi-app
53
+ // Windows: <prefix>/node_modules/pi-app
54
+ const pkgRoot = getPkgRoot();
55
+ return isWindows
56
+ ? resolve(pkgRoot, "..", "..")
57
+ : resolve(pkgRoot, "..", "..", "..", "bin");
58
+ }
59
+
60
+ /** Path of the global command file we manage. */
61
+ export function getLinkPath(binDir) {
62
+ return join(binDir, isWindows ? "pi.cmd" : "pi");
63
+ }
64
+
65
+ /** Whether an existing global `pi` is a shim created by us (safe to manage). */
66
+ export function shimIsOurs(linkPath) {
67
+ try {
68
+ return readFileSync(linkPath, "utf8").includes(SHIM_MARKER);
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
73
+
74
+ /** True if some `pi` command is already resolvable on PATH. */
75
+ export function piExistsOnPath() {
76
+ const finder = isWindows ? "where" : "which";
77
+ try {
78
+ execFileSync(finder, ["pi"], { stdio: "ignore" });
79
+ return true;
80
+ } catch {
81
+ return false;
82
+ }
83
+ }
84
+
85
+ /** Best-effort detection of "something already occupies this path". */
86
+ export function pathOccupied(linkPath) {
87
+ try {
88
+ lstatSync(linkPath); // lstat so broken symlinks count as occupied too
89
+ return true;
90
+ } catch {
91
+ return false;
92
+ }
93
+ }
94
+
95
+ export function makeExecutable(file) {
96
+ if (isWindows) return;
97
+ try {
98
+ chmodSync(file, 0o755);
99
+ } catch {
100
+ // best effort
101
+ }
102
+ }
103
+
104
+ const TAG = "[pi-app] ";
105
+ export function log(msg) {
106
+ process.stdout.write(`${TAG}${msg}\n`);
107
+ }
108
+ export function warn(msg) {
109
+ process.stderr.write(`${TAG}${msg}\n`);
110
+ }
@@ -0,0 +1,108 @@
1
+ // postinstall: make `pi` available globally when (and only when) the user
2
+ // doesn't already have a `pi` command. Never fails the install.
3
+
4
+ import { mkdirSync, unlinkSync, writeFileSync } from "node:fs";
5
+ import { dirname } from "node:path";
6
+ import {
7
+ getGlobalBinDir,
8
+ getLauncherPath,
9
+ getLinkPath,
10
+ isGlobalInstall,
11
+ isWindows,
12
+ log,
13
+ makeExecutable,
14
+ pathOccupied,
15
+ piExistsOnPath,
16
+ SHIM_MARKER,
17
+ shimIsOurs,
18
+ warn,
19
+ } from "./cli-link-common.mjs";
20
+
21
+ // A standalone shim (not a symlink into the package). It forwards to the
22
+ // bundled launcher, and—because npm doesn't run postuninstall—degrades
23
+ // gracefully if pi-app is later removed.
24
+ function shimContents(launcher) {
25
+ if (isWindows) {
26
+ const q = `"${launcher}"`;
27
+ return [
28
+ "@ECHO off",
29
+ `REM ${SHIM_MARKER} (do not edit) - forwards to the pi CLI bundled with pi-app`,
30
+ `IF EXIST ${q} (`,
31
+ ` node ${q} %*`,
32
+ ") ELSE (",
33
+ " echo pi: this command is provided by pi-app, which is no longer installed. Reinstall: npm i -g pi-app 1>&2",
34
+ " EXIT /B 127",
35
+ ")",
36
+ "",
37
+ ].join("\r\n");
38
+ }
39
+ return [
40
+ "#!/usr/bin/env node",
41
+ `// ${SHIM_MARKER} (do not edit) - forwards to the pi CLI bundled with pi-app`,
42
+ '"use strict";',
43
+ 'const fs = require("fs");',
44
+ `const launcher = ${JSON.stringify(launcher)};`,
45
+ "if (!fs.existsSync(launcher)) {",
46
+ ' process.stderr.write("pi: this command is provided by pi-app, which is no longer installed.\\n");',
47
+ ' process.stderr.write("Reinstall with: npm i -g pi-app (or delete this file: " + process.argv[1] + ")\\n");',
48
+ " process.exit(127);",
49
+ "}",
50
+ "require(launcher);",
51
+ "",
52
+ ].join("\n");
53
+ }
54
+
55
+ function createShim(linkPath, launcher) {
56
+ // npm runs postinstall BEFORE it creates the global bin dir and links bins,
57
+ // so on a fresh prefix this dir may not exist yet.
58
+ mkdirSync(dirname(linkPath), { recursive: true });
59
+ writeFileSync(linkPath, shimContents(launcher), "utf8");
60
+ makeExecutable(linkPath);
61
+ }
62
+
63
+ function main() {
64
+ if (!isGlobalInstall()) return; // only relevant for `npm i -g pi-app`
65
+
66
+ const launcher = getLauncherPath();
67
+ if (!pathOccupied(launcher)) {
68
+ warn(`launcher not found at ${launcher}; skipping pi CLI setup.`);
69
+ return;
70
+ }
71
+
72
+ const binDir = getGlobalBinDir();
73
+ const linkPath = getLinkPath(binDir);
74
+
75
+ // Already our shim from a previous install — refresh it (e.g. path changes).
76
+ if (shimIsOurs(linkPath)) {
77
+ try {
78
+ unlinkSync(linkPath);
79
+ } catch {
80
+ // ignore; createShim overwrites anyway
81
+ }
82
+ createShim(linkPath, launcher);
83
+ log(`pi CLI refreshed -> ${linkPath}`);
84
+ return;
85
+ }
86
+
87
+ // Something else owns this path — keep it, don't clobber.
88
+ if (pathOccupied(linkPath)) {
89
+ log(`existing pi found at ${linkPath}; keeping it (not overwriting).`);
90
+ return;
91
+ }
92
+
93
+ // A pi exists elsewhere on PATH (e.g. Homebrew, a separate global install).
94
+ if (piExistsOnPath()) {
95
+ log("an existing pi command was found on PATH; keeping it.");
96
+ return;
97
+ }
98
+
99
+ createShim(linkPath, launcher);
100
+ log(`pi CLI installed -> ${linkPath}`);
101
+ }
102
+
103
+ try {
104
+ main();
105
+ } catch (err) {
106
+ // postinstall must never break `npm i -g pi-app`.
107
+ warn(`could not set up the pi CLI automatically: ${err?.message ?? err}`);
108
+ }
@@ -0,0 +1,35 @@
1
+ // postuninstall: remove the global `pi` shim ONLY if we created it.
2
+ //
3
+ // NOTE: npm does NOT run uninstall lifecycle scripts, so this will typically
4
+ // NOT execute on `npm uninstall -g pi-app`. It is kept as best-effort for
5
+ // package managers that do honor it (and manual invocation). When it doesn't
6
+ // run, the standalone shim degrades gracefully instead of dangling. Never
7
+ // fails the uninstall.
8
+
9
+ import { unlinkSync } from "node:fs";
10
+ import {
11
+ getGlobalBinDir,
12
+ getLinkPath,
13
+ isGlobalInstall,
14
+ log,
15
+ shimIsOurs,
16
+ warn,
17
+ } from "./cli-link-common.mjs";
18
+
19
+ function main() {
20
+ if (!isGlobalInstall()) return;
21
+
22
+ const binDir = getGlobalBinDir();
23
+ const linkPath = getLinkPath(binDir);
24
+
25
+ if (!shimIsOurs(linkPath)) return; // not ours — leave it alone
26
+
27
+ unlinkSync(linkPath);
28
+ log(`removed pi CLI shim at ${linkPath}`);
29
+ }
30
+
31
+ try {
32
+ main();
33
+ } catch (err) {
34
+ warn(`could not clean up the pi CLI shim: ${err?.message ?? err}`);
35
+ }
@@ -1,2 +0,0 @@
1
- "use strict";exports.id=6402,exports.ids=[6402],exports.modules={12039:(a,b,c)=>{c.d(b,{m:()=>d});function d(a){let b="timelineSummary"===a.role&&"string"==typeof a.summary?{role:"timelineSummary",kind:"branch"===a.kind?"branch":"compaction",summary:a.summary,timestamp:"number"==typeof a.timestamp?a.timestamp:void 0}:"compactionSummary"===a.role?{role:"timelineSummary",kind:"compaction",summary:String(a.summary??""),timestamp:"number"==typeof a.timestamp?a.timestamp:void 0}:"branchSummary"===a.role?{role:"timelineSummary",kind:"branch",summary:String(a.summary??""),timestamp:"number"==typeof a.timestamp?a.timestamp:void 0}:null;if(b)return b;if("assistant"!==a.role)return a;let c=a.content;if(!Array.isArray(c))return a;let d=c.map(a=>("object"!=typeof a||null===a||Array.isArray(a)||"toolCall"!==a.type?null:{type:"toolCall",toolCallId:"string"==typeof a.toolCallId?a.toolCallId:"string"==typeof a.id?a.id:"",toolName:"string"==typeof a.toolName?a.toolName:"string"==typeof a.name?a.name:"",input:"object"!=typeof a.input||null===a.input||Array.isArray(a.input)?"object"!=typeof a.arguments||null===a.arguments||Array.isArray(a.arguments)?{}:a.arguments:a.input})??a);return{...a,content:d}}},14667:(a,b,c)=>{c.d(b,{ME:()=>f,aO:()=>e});let d=[/^\/tmp\//,/^\/tmp$/,/^\/private\/tmp\//,/^\/private\/tmp$/,/^\/var\/folders\/[^/]+\/[^/]+\/T\//,/^\/var\/folders\/[^/]+\/[^/]+\/T$/,/^\/private\/var\/folders\/[^/]+\/[^/]+\/T\//,/^\/private\/var\/folders\/[^/]+\/[^/]+\/T$/,/^[A-Za-z]:\\Users\\[^\\]+\\AppData\\Local\\Temp\\/i,/^[A-Za-z]:\\Windows\\Temp\\/i];function e(a){return!!a&&d.some(b=>b.test(a))}function f(a){return(function(a){let b=new Map;for(let c of a){if(!c.cwd)continue;let a=b.get(c.cwd);(!a||c.modified>a)&&b.set(c.cwd,c.modified)}return[...b.entries()].sort((a,b)=>b[1].localeCompare(a[1])).map(([a])=>a)})(a).filter(a=>!e(a))}},40257:(a,b,c)=>{c.d(b,{Aw:()=>h,y8:()=>i});var d=c(73024),e=c(76760),f=c(1751);function g(){return(0,e.join)((0,f.$M)(),"pi-web-preferences.json")}function h(){try{let a=(0,d.readFileSync)(g(),"utf8"),b=JSON.parse(a);return b&&"object"==typeof b?b:{}}catch{return{}}}function i(a){var b;let c,f;return b={...h(),...a},c=g(),(0,d.mkdirSync)((0,e.dirname)(c),{recursive:!0}),f=`${c}.tmp`,(0,d.writeFileSync)(f,`${JSON.stringify(b,null,2)}
2
- `,"utf8"),(0,d.renameSync)(f,c),b}},40402:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{BR:()=>s,O8:()=>r,Q0:()=>n,Uv:()=>t,dQ:()=>o,os:()=>q});var e=c(76760),f=c(75430),g=c(1751),h=c(12039),i=c(40257),j=c(58124),k=c(14667),l=a([f]);async function m(a){let b="PI_CODING_AGENT_DIR",c=process.env[b];process.env[b]=a;try{return await f.SessionManager.listAll()}finally{void 0===c?delete process.env[b]:process.env[b]=c}}async function n(){let a=[],b=b=>{for(let c of b)c.cwd&&a.push({cwd:c.cwd,modified:c.modified instanceof Date?c.modified.toISOString():String(c.modified)})};b(await f.SessionManager.listAll());let c=(0,g.$M)(),d=(0,g.AP)();if((0,e.resolve)(c)!==(0,e.resolve)(d))try{b(await m(d))}catch{}let h=(0,k.ME)(a),j=(0,i.Aw)().defaultWorkspaceCwd?.trim();return!j||h.includes(j)||(0,k.aO)(j)||h.push(j),h}async function o(){let a=await f.SessionManager.listAll(),b=new Map;for(let c of a)b.set(c.path,c.id);let c=(0,j.pI)(),d=p();return a.map(a=>{let e=c[a.id];return d.set(a.id,a.path),{path:a.path,id:a.id,cwd:a.cwd,name:a.name,created:a.created instanceof Date?a.created.toISOString():String(a.created),modified:a.modified instanceof Date?a.modified.toISOString():String(a.modified),messageCount:a.messageCount,firstMessage:a.firstMessage||"(no messages)",parentSessionId:a.parentSessionPath?b.get(a.parentSessionPath):void 0,productTitle:e?.title,productStatus:e?.status,lastResultSummary:e?.lastResultSummary}})}function p(){return globalThis.__piSessionPathCache||(globalThis.__piSessionPathCache=new Map),globalThis.__piSessionPathCache}async function q(a){let b=p().get(a);return b||(await o(),p().get(a)??null)}function r(a,b){p().set(a,b)}function s(a){p().delete(a)}function t(a,b){let c,d,e,g=new Map;for(let b of a)g.set(b.id,b);let i=(0,f.buildSessionContext)(a,b,g);if(null===b||(b&&(c=g.get(b)),c||(c=a[a.length-1]),!c))return{messages:[],entryIds:[],thinkingLevel:i.thinkingLevel,model:i.model};let j=[],k=c;for(;k;)j.unshift(k),k=k.parentId?g.get(k.parentId):void 0;for(let a of j)"compaction"===a.type&&(d=a.id,e=a.firstKeptEntryId);let l=[];if(d){l.push(d);let a=j.findIndex(a=>a.id===d),b=e?j.findIndex((b,c)=>c<a&&b.id===e):-1,c=b>=0?b:a;for(let b=c;b<a;b++)"message"===j[b].type&&l.push(j[b].id);for(let b=a+1;b<j.length;b++)"message"===j[b].type&&l.push(j[b].id)}else for(let a of j)"message"===a.type&&l.push(a.id);return{messages:i.messages.map(a=>(0,h.m)(a)),entryIds:l,thinkingLevel:i.thinkingLevel,model:i.model}}f=(l.then?(await l)():l)[0],d()}catch(a){d(a)}})},58124:(a,b,c)=>{c.d(b,{Ay:()=>l,pI:()=>k,r5:()=>j});var d=c(29021),e=c(33873),f=c(55511),g=c(1751);function h(){return(0,e.join)((0,g.$M)(),"product-sessions.json")}function i(){let a=h();if(!(0,d.existsSync)(a))return{};try{let b=(0,d.readFileSync)(a,"utf8");if(!b.trim())return{};let c=JSON.parse(b);return c&&"object"==typeof c?c:{}}catch(a){return"u">typeof console&&console.warn("[product-sessions] failed to parse store, treating as empty:",a),{}}}function j(a){return i()[a]??null}let k=function(){return i()};async function l(a,b){var c;let g;await (c=()=>{let c,g,j=i(),k=j[a];j[a]={...k,...b,startedAt:k?.startedAt??b.startedAt},c=h(),(0,d.mkdirSync)((0,e.dirname)(c),{recursive:!0}),g=`${c}.${(0,f.randomUUID)()}.tmp`,(0,d.writeFileSync)(g,JSON.stringify(j,null,2),"utf8"),(0,d.renameSync)(g,c)},g=(globalThis.__piProductSessionWriteQueue??Promise.resolve()).then(c,c),globalThis.__piProductSessionWriteQueue=g.catch(()=>void 0),g)}},80547:(a,b,c)=>{c.d(b,{As:()=>j,B9:()=>m,KJ:()=>l,af:()=>k});var d=c(73024),e=c.n(d),f=c(33873),g=c.n(f);let h=/^[a-zA-Z]:[\\/]/;function i(a){return h.test(a)||a.startsWith("\\\\")||a.startsWith("//")}function j(a){let b=a.join("/"),c=b.replace(/\\/g,"/");return i(c)?c:"/"+b.replace(/^\/+/,"")}function k(a,b){for(let c of b){let b=i(a)||i(c),d=b?g().win32:g(),e=b?"\\":g().sep,f=d.resolve(a),h=d.resolve(c),j=b?f.toLowerCase():f,k=b?h.toLowerCase():h,l=k.endsWith(e)?k:k+e;if(j===k||j.startsWith(l))return!0}return!1}function l(a,b){let c;try{c=e().realpathSync(a)}catch{return!1}let d=new Set;for(let a of b)try{d.add(e().realpathSync(a))}catch{}return k(c,d)}function m(a,b){let c=/^bytes=(\d*)-(\d*)$/.exec(a);if(!c||!c[1]&&!c[2])return{error:"invalid"};let d=c[1]?Number(c[1]):0,e=c[2]?Number(c[2]):b-1;return(!c[1]&&c[2]&&(d=Math.max(b-Number(c[2]),0),e=b-1),!Number.isSafeInteger(d)||!Number.isSafeInteger(e)||d<0||e<d||d>=b)?{error:"unsatisfiable"}:{start:d,end:Math.min(e,b-1)}}},93259:(a,b,c)=>{c.d(b,{_:()=>e});var d=c(92725);function e(a){return(0,d.rT)(a)}}};