pi-webapp 0.1.8 → 0.1.9

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.
@@ -0,0 +1,2 @@
1
+ export function resolveNpmCli(options?: { execPath?: string; env?: NodeJS.ProcessEnv }): string;
2
+ export function npmCommand(args: readonly string[]): { file: string; args: string[] };
@@ -0,0 +1,36 @@
1
+ import { realpathSync, statSync } from "node:fs";
2
+ import { basename, delimiter, dirname, join, resolve } from "node:path";
3
+
4
+ function npmEntry(path) {
5
+ if (!path) return null;
6
+ try {
7
+ const real = realpathSync(path);
8
+ return basename(real) === "npm-cli.js" && statSync(real).isFile() ? real : null;
9
+ } catch { return null; }
10
+ }
11
+
12
+ /** Find npm's JavaScript entry point without relying on executable shell shims. */
13
+ export function resolveNpmCli({ execPath = process.execPath, env = process.env } = {}) {
14
+ const inherited = npmEntry(env.npm_execpath);
15
+ if (inherited) return inherited;
16
+
17
+ const directories = new Set([dirname(execPath)]);
18
+ try { directories.add(dirname(realpathSync(execPath))); } catch { /* Try the original path. */ }
19
+ const searchPath = Object.entries(env).find(([key]) => key.toLowerCase() === "path")?.[1] ?? "";
20
+ for (const directory of searchPath.split(delimiter).filter(Boolean)) directories.add(resolve(directory));
21
+ for (const directory of directories) {
22
+ for (const candidate of [
23
+ join(directory, "node_modules", "npm", "bin", "npm-cli.js"),
24
+ join(directory, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
25
+ join(directory, "npm"),
26
+ ]) {
27
+ const cli = npmEntry(candidate);
28
+ if (cli) return cli;
29
+ }
30
+ }
31
+ throw new Error("找不到 npm 入口 npm-cli.js;请安装包含 npm 的 Node.js,或将 npm 所在目录加入 PATH 后重启服务。");
32
+ }
33
+
34
+ export function npmCommand(args) {
35
+ return { file: process.execPath, args: [resolveNpmCli(), ...args] };
36
+ }
package/bin/pi-webapp.mjs CHANGED
@@ -8,6 +8,7 @@ import { delimiter, dirname, join, resolve } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import spawn from "cross-spawn";
10
10
  import { openWebPage } from "./open-web-page.mjs";
11
+ import { npmCommand } from "./npm-command.mjs";
11
12
 
12
13
  const minimum = [0, 87, 1];
13
14
  const launcher = fileURLToPath(import.meta.url);
@@ -47,13 +48,15 @@ function probe(command) {
47
48
 
48
49
  function installPi() {
49
50
  console.error("未找到 Pi,正在通过 npm 安装 @earendil-works/pi-coding-agent …");
50
- const result = spawn.sync("npm", ["install", "-g", "--ignore-scripts", "@earendil-works/pi-coding-agent"], { stdio: "inherit" });
51
+ const install = npmCommand(["install", "-g", "--ignore-scripts", "@earendil-works/pi-coding-agent"]);
52
+ const result = spawn.sync(install.file, install.args, { stdio: "inherit", windowsHide: true });
51
53
  if (result.error || result.status !== 0) {
52
54
  throw new Error(`Pi 安装失败。请手动运行 npm install -g --ignore-scripts @earendil-works/pi-coding-agent${result.error ? `(${result.error.message})` : ""}`);
53
55
  }
54
56
  const inPath = probe("pi");
55
57
  if (inPath) return inPath;
56
- const prefix = spawn.sync("npm", ["prefix", "-g"], { encoding: "utf8" });
58
+ const prefixCommand = npmCommand(["prefix", "-g"]);
59
+ const prefix = spawn.sync(prefixCommand.file, prefixCommand.args, { encoding: "utf8", windowsHide: true });
57
60
  if (prefix.status === 0) {
58
61
  const installed = process.platform === "win32" ? join(prefix.stdout.trim(), "pi.cmd") : join(prefix.stdout.trim(), "bin", "pi");
59
62
  if (existsSync(installed)) return probe(installed);
package/dist/extension.js CHANGED
@@ -1,23 +1,23 @@
1
- (function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new r.Error().stack;e&&(r._sentryDebugIds=r._sentryDebugIds||{},r._sentryDebugIds[e]="449b6114-32dc-4dde-9b3e-7a3c77caffc8",r._sentryDebugIdIdentifier="sentry-dbid-449b6114-32dc-4dde-9b3e-7a3c77caffc8")}catch{}})();import{delimiter as os,dirname as as,join as he,resolve as Be}from"node:path";import{realpathSync as cs,watch as ls}from"node:fs";import{realpath as ve}from"node:fs/promises";import{fileURLToPath as ds}from"node:url";import{DefaultPackageManager as $t,getAgentDir as J,ModelRuntime as ps,SessionManager as Vt,SettingsManager as us,VERSION as we}from"@earendil-works/pi-coding-agent";import{getSupportedThinkingLevels as fs}from"@earendil-works/pi-ai";import{randomBytes as Kr,randomUUID as ut,timingSafeEqual as Xr}from"node:crypto";import{readFile as Zr,readdir as Qr}from"node:fs/promises";import{createServer as ei}from"node:http";import{join as ft}from"node:path";import{mkdir as Jt,opendir as qt,stat as Yt}from"node:fs/promises";import{homedir as Kt}from"node:os";import{basename as Xt,dirname as Oe,join as Le,posix as Zt,resolve as $e,win32 as Qt}from"node:path";function Ve(r){return process.platform==="win32"?Qt.isAbsolute(r)&&/^(?:[A-Za-z]:[\\/]|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)/.test(r):Zt.isAbsolute(r)}function er(r,e,t){if(r.length===t&&e.name.localeCompare(r[r.length-1].name)>=0)return!0;let i=0,n=r.length;for(;i<n;){let o=i+n>>>1;e.name.localeCompare(r[o].name)<0?n=o:i=o+1}return r.splice(i,0,e),r.length<=t?!1:(r.pop(),!0)}async function Ue(r){if(r!==void 0&&!Ve(r))throw new Error("\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");let e=Kt(),t=$e(r??e),i=[];for(let f=t;;f=Oe(f)){let y=Oe(f);if(i.unshift({name:y===f?f:Xt(f),path:f,hidden:!1}),y===f)break}let n=[],o=!1,l=await qt(t);for await(let f of l)!f.isDirectory()&&!f.isSymbolicLink()||er(n,{name:f.name,isDirectory:f.isDirectory(),isSymbolicLink:f.isSymbolicLink()},1001)&&(o=!0);let u=[];for(let f of n){let y=Le(t,f.name);if(!f.isDirectory&&f.isSymbolicLink)try{if(!(await Yt(y)).isDirectory())continue}catch{continue}if(u.length===1e3){o=!0;break}u.push({name:f.name,path:y,hidden:f.name.startsWith(".")})}return{path:t,home:e,crumbs:i,entries:u,truncated:o}}async function Fe(r,e){if(!Ve(r))throw new Error("\u7236\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");if(!e.trim()||e==="."||e===".."||/[/\\]/.test(e))throw new Error("\u6587\u4EF6\u5939\u540D\u79F0\u65E0\u6548");let t=Le($e(r),e);return await Jt(t),t}import{execFile as tr}from"node:child_process";import{accessSync as rr,constants as ir}from"node:fs";import{delimiter as sr,join as nr}from"node:path";var or=(r,e,t)=>new Promise((i,n)=>{tr(r,[...e],{encoding:"utf8",signal:t,windowsHide:!0},(o,l,u)=>{o?n(Object.assign(new Error(o.message,{cause:o}),{code:o.code,stdout:l,stderr:u})):i({stdout:l,stderr:u})})});function ar(r){for(let e of(r??"").split(sr))if(e)for(let t of["zenity","kdialog"])try{return rr(nr(e,t),ir.X_OK),!0}catch{}return!1}function He(r=process.platform,e=process.env){return e.SSH_CONNECTION||e.SSH_TTY?"browse":r==="darwin"||r==="linux"&&(e.DISPLAY||e.WAYLAND_DISPLAY)&&ar(e.PATH)?"native":"browse"}function re(r){if(!(typeof r!="object"||r===null||!("code"in r)))return typeof r.code=="string"||typeof r.code=="number"?r.code:void 0}function cr(r){return typeof r=="object"&&r!==null&&"stderr"in r&&typeof r.stderr=="string"?r.stderr:""}function be(r){return r.replace(/[\r\n]+$/,"")||null}async function ze(r,e=process.platform,t=or){if(e==="darwin")try{let i=await t("osascript",["-e",'set selectedFolder to choose folder with prompt "Select Workspace Directory"',"-e","POSIX path of selectedFolder"],r);return be(i.stdout)}catch(i){if(!r.aborted&&re(i)===1&&/(?:User canceled|-128)/i.test(cr(i)))return null;throw i}if(e==="linux"){try{return be((await t("zenity",["--file-selection","--directory","--title=Select Workspace Directory"],r)).stdout)}catch(i){if(r.aborted)throw i;if(re(i)===1)return null;if(re(i)!=="ENOENT")throw i}try{return be((await t("kdialog",["--getexistingdirectory",".","--title","Select Workspace Directory"],r)).stdout)}catch(i){if(r.aborted)throw i;if(re(i)===1)return null;throw i}}throw new Error(`\u5F53\u524D\u7CFB\u7EDF\u4E0D\u652F\u6301\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\uFF1A${e}`)}import{createHash as lr,randomUUID as dr}from"node:crypto";import{mkdir as pr,readFile as ur,writeFile as fr}from"node:fs/promises";import{join as Ge}from"node:path";import{getAgentDir as gr}from"@earendil-works/pi-coding-agent";var ie=20*1024*1024,Je=20,mr=/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu;function hr(r){let e=r.indexOf("."),t=(e<0?r:r.slice(0,e)).replace(/[. ]+$/u,"");return mr.test(t)}function wr(r,e){let t=0,i="";for(let n of Buffer.from(r).toString("utf8")){let o=Buffer.byteLength(n);if(t+o>e)break;i+=n,t+=o}return i}function yr(r){if(r===void 0)return"file";let t=r.slice(Math.max(r.lastIndexOf("/"),r.lastIndexOf("\\"))+1).replace(/[\u0000-\u001f\u007f]/g,"").replace(/[<>:"|?*]/g,"_").trim().replace(/[. ]+$/u,"");return hr(t)&&(t=`_${t}`),t=wr(t,255).replace(/[. ]+$/u,""),t===""||t==="."||t===".."?"file":t}function vr(r){return r.length>=8&&r.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10]))?"image/png":r.length>=3&&r.subarray(0,3).equals(Buffer.from([255,216,255]))?"image/jpeg":r.length>=6&&["GIF87a","GIF89a"].includes(r.toString("ascii",0,6))?"image/gif":r.length>=12&&r.toString("ascii",0,4)==="RIFF"&&r.toString("ascii",8,12)==="WEBP"?"image/webp":null}async function qe(r,e,t,i){if(i.byteLength===0||i.byteLength>ie)throw new Error("\u6587\u4EF6\u4E3A\u7A7A\u6216\u8D85\u8FC7 20 MB");let n=yr(e),o=lr("sha256").update(i).digest("hex"),l=Ge(gr(),"pi-web","attachments",o);await pr(l,{recursive:!0});let u=Ge(l,n);try{await fr(u,i,{flag:"wx",mode:384})}catch(f){if(!(f instanceof Error&&"code"in f&&f.code==="EEXIST"))throw f}return{id:dr(),name:n,bytes:i.byteLength,path:u,mediaType:vr(i)??t.replace(/^image\//,"application/"),sessionId:r}}async function Ye(r){return{type:"image",data:(await ur(r.path)).toString("base64"),mimeType:r.mediaType}}import{randomBytes as br}from"node:crypto";function Ke(r,e,t){return r!=="openai-codex"||e!=="oauth"?t:{...t,prompt:i=>i.type==="select"&&i.options.some(n=>n.id==="browser")&&i.options.some(n=>n.id==="device_code")?Promise.resolve("browser"):t.prompt(i)}}var se=class{flows=new Map;reportError;constructor(e=()=>{}){this.reportError=e}start(e,t,i,n,o){let l=this.getActive();if(l){if(l.providerId===e&&l.method===t&&n===void 0)return l;throw new Error("\u5176\u4ED6\u63D0\u4F9B\u65B9\u7684\u767B\u5F55\u6B63\u5728\u8FDB\u884C\uFF0C\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D\u767B\u5F55")}this.flows.clear();let u=br(18).toString("base64url"),f={view:{id:u,providerId:e,method:t,status:"running"},controller:new AbortController};return this.flows.set(u,f),i(e,t,{signal:f.controller.signal,notify:y=>{f.view={...f.view,event:y,...y.type==="auth_url"||y.type==="device_code"?{authorization:y}:{}}},prompt:y=>{if(y.type==="secret"&&n!==void 0){let c=n;return n=void 0,Promise.resolve(c)}return new Promise((c,p)=>{let{signal:g,...m}=y;f.answer=c,f.reject=p,f.view={...f.view,status:"waiting",prompt:m},g?.aborted?p(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")):g?.addEventListener("abort",()=>p(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")),{once:!0})})}}).then(()=>{f.view.status!=="cancelled"&&(f.view={id:u,providerId:e,method:t,status:"done"})}).catch(y=>{if(f.view.status!=="cancelled"){let c=new Error("Provider login failed");y instanceof Error&&y.stack&&(c.stack=`${c.message}
1
+ (function(){try{var r=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},e=new r.Error().stack;e&&(r._sentryDebugIds=r._sentryDebugIds||{},r._sentryDebugIds[e]="f1a698c3-8c0a-43a0-b699-ccd098cbfcec",r._sentryDebugIdIdentifier="sentry-dbid-f1a698c3-8c0a-43a0-b699-ccd098cbfcec")}catch{}})();import{delimiter as wn,dirname as yn,join as he,resolve as De}from"node:path";import{realpathSync as vn,watch as bn}from"node:fs";import{realpath as ve}from"node:fs/promises";import{fileURLToPath as kn}from"node:url";import{DefaultPackageManager as zt,getAgentDir as J,ModelRuntime as Pn,SessionManager as Gt,SettingsManager as En,VERSION as we}from"@earendil-works/pi-coding-agent";import{getSupportedThinkingLevels as Sn}from"@earendil-works/pi-ai";import{randomBytes as ti,randomUUID as ft,timingSafeEqual as ri}from"node:crypto";import{readFile as ii,readdir as ni}from"node:fs/promises";import{createServer as si}from"node:http";import{join as gt}from"node:path";import{mkdir as Zt,opendir as Qt,stat as er}from"node:fs/promises";import{homedir as tr}from"node:os";import{basename as rr,dirname as Le,join as $e,posix as ir,resolve as Ve,win32 as nr}from"node:path";function Ue(r){return process.platform==="win32"?nr.isAbsolute(r)&&/^(?:[A-Za-z]:[\\/]|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)/.test(r):ir.isAbsolute(r)}function sr(r,e,t){if(r.length===t&&e.name.localeCompare(r[r.length-1].name)>=0)return!0;let i=0,s=r.length;for(;i<s;){let o=i+s>>>1;e.name.localeCompare(r[o].name)<0?s=o:i=o+1}return r.splice(i,0,e),r.length<=t?!1:(r.pop(),!0)}async function Fe(r){if(r!==void 0&&!Ue(r))throw new Error("\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");let e=tr(),t=Ve(r??e),i=[];for(let f=t;;f=Le(f)){let y=Le(f);if(i.unshift({name:y===f?f:rr(f),path:f,hidden:!1}),y===f)break}let s=[],o=!1,l=await Qt(t);for await(let f of l)!f.isDirectory()&&!f.isSymbolicLink()||sr(s,{name:f.name,isDirectory:f.isDirectory(),isSymbolicLink:f.isSymbolicLink()},1001)&&(o=!0);let u=[];for(let f of s){let y=$e(t,f.name);if(!f.isDirectory&&f.isSymbolicLink)try{if(!(await er(y)).isDirectory())continue}catch{continue}if(u.length===1e3){o=!0;break}u.push({name:f.name,path:y,hidden:f.name.startsWith(".")})}return{path:t,home:e,crumbs:i,entries:u,truncated:o}}async function He(r,e){if(!Ue(r))throw new Error("\u7236\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");if(!e.trim()||e==="."||e===".."||/[/\\]/.test(e))throw new Error("\u6587\u4EF6\u5939\u540D\u79F0\u65E0\u6548");let t=$e(Ve(r),e);return await Zt(t),t}import{execFile as or}from"node:child_process";import{accessSync as ar,constants as cr}from"node:fs";import{delimiter as lr,join as dr}from"node:path";var pr=(r,e,t)=>new Promise((i,s)=>{or(r,[...e],{encoding:"utf8",signal:t,windowsHide:!0},(o,l,u)=>{o?s(Object.assign(new Error(o.message,{cause:o}),{code:o.code,stdout:l,stderr:u})):i({stdout:l,stderr:u})})});function ur(r){for(let e of(r??"").split(lr))if(e)for(let t of["zenity","kdialog"])try{return ar(dr(e,t),cr.X_OK),!0}catch{}return!1}function ze(r=process.platform,e=process.env){return e.SSH_CONNECTION||e.SSH_TTY?"browse":r==="darwin"||r==="linux"&&(e.DISPLAY||e.WAYLAND_DISPLAY)&&ur(e.PATH)?"native":"browse"}function re(r){if(!(typeof r!="object"||r===null||!("code"in r)))return typeof r.code=="string"||typeof r.code=="number"?r.code:void 0}function fr(r){return typeof r=="object"&&r!==null&&"stderr"in r&&typeof r.stderr=="string"?r.stderr:""}function be(r){return r.replace(/[\r\n]+$/,"")||null}async function Ge(r,e=process.platform,t=pr){if(e==="darwin")try{let i=await t("osascript",["-e",'set selectedFolder to choose folder with prompt "Select Workspace Directory"',"-e","POSIX path of selectedFolder"],r);return be(i.stdout)}catch(i){if(!r.aborted&&re(i)===1&&/(?:User canceled|-128)/i.test(fr(i)))return null;throw i}if(e==="linux"){try{return be((await t("zenity",["--file-selection","--directory","--title=Select Workspace Directory"],r)).stdout)}catch(i){if(r.aborted)throw i;if(re(i)===1)return null;if(re(i)!=="ENOENT")throw i}try{return be((await t("kdialog",["--getexistingdirectory",".","--title","Select Workspace Directory"],r)).stdout)}catch(i){if(r.aborted)throw i;if(re(i)===1)return null;throw i}}throw new Error(`\u5F53\u524D\u7CFB\u7EDF\u4E0D\u652F\u6301\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\uFF1A${e}`)}import{createHash as gr,randomUUID as mr}from"node:crypto";import{mkdir as hr,readFile as wr,writeFile as yr}from"node:fs/promises";import{join as Je}from"node:path";import{getAgentDir as vr}from"@earendil-works/pi-coding-agent";var ie=20*1024*1024,qe=20,br=/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu;function kr(r){let e=r.indexOf("."),t=(e<0?r:r.slice(0,e)).replace(/[. ]+$/u,"");return br.test(t)}function Pr(r,e){let t=0,i="";for(let s of Buffer.from(r).toString("utf8")){let o=Buffer.byteLength(s);if(t+o>e)break;i+=s,t+=o}return i}function Er(r){if(r===void 0)return"file";let t=r.slice(Math.max(r.lastIndexOf("/"),r.lastIndexOf("\\"))+1).replace(/[\u0000-\u001f\u007f]/g,"").replace(/[<>:"|?*]/g,"_").trim().replace(/[. ]+$/u,"");return kr(t)&&(t=`_${t}`),t=Pr(t,255).replace(/[. ]+$/u,""),t===""||t==="."||t===".."?"file":t}function Sr(r){return r.length>=8&&r.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10]))?"image/png":r.length>=3&&r.subarray(0,3).equals(Buffer.from([255,216,255]))?"image/jpeg":r.length>=6&&["GIF87a","GIF89a"].includes(r.toString("ascii",0,6))?"image/gif":r.length>=12&&r.toString("ascii",0,4)==="RIFF"&&r.toString("ascii",8,12)==="WEBP"?"image/webp":null}async function Ye(r,e,t,i){if(i.byteLength===0||i.byteLength>ie)throw new Error("\u6587\u4EF6\u4E3A\u7A7A\u6216\u8D85\u8FC7 20 MB");let s=Er(e),o=gr("sha256").update(i).digest("hex"),l=Je(vr(),"pi-web","attachments",o);await hr(l,{recursive:!0});let u=Je(l,s);try{await yr(u,i,{flag:"wx",mode:384})}catch(f){if(!(f instanceof Error&&"code"in f&&f.code==="EEXIST"))throw f}return{id:mr(),name:s,bytes:i.byteLength,path:u,mediaType:Sr(i)??t.replace(/^image\//,"application/"),sessionId:r}}async function Ke(r){return{type:"image",data:(await wr(r.path)).toString("base64"),mimeType:r.mediaType}}import{randomBytes as Ir}from"node:crypto";function Xe(r,e,t){return r!=="openai-codex"||e!=="oauth"?t:{...t,prompt:i=>i.type==="select"&&i.options.some(s=>s.id==="browser")&&i.options.some(s=>s.id==="device_code")?Promise.resolve("browser"):t.prompt(i)}}var ne=class{flows=new Map;reportError;constructor(e=()=>{}){this.reportError=e}start(e,t,i,s,o){let l=this.getActive();if(l){if(l.providerId===e&&l.method===t&&s===void 0)return l;throw new Error("\u5176\u4ED6\u63D0\u4F9B\u65B9\u7684\u767B\u5F55\u6B63\u5728\u8FDB\u884C\uFF0C\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D\u767B\u5F55")}this.flows.clear();let u=Ir(18).toString("base64url"),f={view:{id:u,providerId:e,method:t,status:"running"},controller:new AbortController};return this.flows.set(u,f),i(e,t,{signal:f.controller.signal,notify:y=>{f.view={...f.view,event:y,...y.type==="auth_url"||y.type==="device_code"?{authorization:y}:{}}},prompt:y=>{if(y.type==="secret"&&s!==void 0){let c=s;return s=void 0,Promise.resolve(c)}return new Promise((c,p)=>{let{signal:g,...m}=y;f.answer=c,f.reject=p,f.view={...f.view,status:"waiting",prompt:m},g?.aborted?p(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")):g?.addEventListener("abort",()=>p(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")),{once:!0})})}}).then(()=>{f.view.status!=="cancelled"&&(f.view={id:u,providerId:e,method:t,status:"done"})}).catch(y=>{if(f.view.status!=="cancelled"){let c=new Error("Provider login failed");y instanceof Error&&y.stack&&(c.stack=`${c.message}
2
2
  ${y.stack.split(`
3
3
  `).slice(1).join(`
4
- `)}`);let p=this.reportError(c,{...o,stage:"provider_login"});f.view={id:u,providerId:e,method:t,status:"error",error:"\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u63D0\u4F9B\u65B9\u63D0\u793A\u5E76\u91CD\u8BD5\u3002",errorId:p}}}),{...f.view}}get(e){let t=this.flows.get(e)?.view;return t?{...t}:void 0}getActive(){let e=[...this.flows.values()].find(({view:t})=>t.status==="running"||t.status==="waiting")?.view;return e?{...e}:void 0}respond(e,t){let i=this.flows.get(e);if(!i?.answer||i.view.status!=="waiting"||i.view.prompt?.type==="select"&&!i.view.prompt.options.some(o=>o.id===t))return!1;let n=i.answer;return i.answer=void 0,i.reject=void 0,i.view={...i.view,status:"running",prompt:void 0},n(t),!0}cancel(e){let t=this.flows.get(e);return!t||t.view.status==="done"||t.view.status==="error"?!1:(t.view={...t.view,status:"cancelled",prompt:void 0},t.controller.abort(),t.reject?.(new Error("\u767B\u5F55\u5DF2\u53D6\u6D88")),t.answer=void 0,t.reject=void 0,!0)}close(){for(let e of this.flows.keys())this.cancel(e);this.flows.clear()}};import{randomBytes as kr}from"node:crypto";import{readFile as Pr,rename as Er,rm as Ir,stat as Sr,writeFile as xr,mkdir as Cr}from"node:fs/promises";import{dirname as Ar}from"node:path";var _r=["openai-completions","openai-responses","anthropic-messages"];function ke(r){if(!r||typeof r!="object")return!1;let e=r;if(typeof e.id!="string"||!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(e.id)||typeof e.name!="string"||!e.name.trim()||e.name.length>100||typeof e.modelId!="string"||!e.modelId.trim()||e.modelId.length>200||!_r.includes(e.api)||typeof e.baseUrl!="string"||e.baseUrl.length>2048)return!1;try{let t=new URL(e.baseUrl);return(t.protocol==="https:"||t.protocol==="http:")&&!!t.hostname&&!t.username&&!t.password&&!t.hash}catch{return!1}}async function Xe(r,e){if(!ke(e))throw new Error("\u81EA\u5B9A\u4E49\u63D0\u4F9B\u65B9\u540D\u79F0\u3001\u5730\u5740\u6216\u6A21\u578B\u65E0\u6548");let t;try{t=await Pr(r,"utf8")}catch(u){if(u.code!=="ENOENT")throw u}let i;if(t===void 0)i={providers:{}};else{try{i=JSON.parse(t)}catch{throw new Error("models.json \u542B\u6CE8\u91CA\u6216\u683C\u5F0F\u9519\u8BEF\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u624B\u52A8\u6DFB\u52A0\u63D0\u4F9B\u65B9")}if(!i||typeof i!="object"||!i.providers||typeof i.providers!="object"||Array.isArray(i.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548")}if(Object.hasOwn(i.providers,e.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");let n={...i,providers:{...i.providers,[e.id]:{name:e.name.trim(),baseUrl:e.baseUrl,api:e.api,models:[{id:e.modelId.trim()}]}}};await Cr(Ar(r),{recursive:!0});let o=t===void 0?384:(await Sr(r)).mode&511,l=`${r}.pi-web-${kr(6).toString("hex")}.tmp`;try{await xr(l,`${JSON.stringify(n,null,2)}
5
- `,{mode:o,flag:"wx"}),await Er(l,r)}finally{await Ir(l,{force:!0})}}import{randomBytes as Tr}from"node:crypto";import{mkdir as Mr,readFile as Rr,rename as Wr,rm as Nr,stat as jr,writeFile as Br}from"node:fs/promises";import{dirname as Dr}from"node:path";function Ze(r){if(!r||r.length>2048)return!1;try{let e=new URL(r);return(e.protocol==="https:"||e.protocol==="http:")&&!!e.hostname&&!e.username&&!e.password&&!e.search&&!e.hash}catch{return!1}}function Qe(r){if(!r||typeof r!="object")return!1;let e=r;return e.action==="save"?(e.originalId===void 0||typeof e.originalId=="string")&&et(e.model):e.action==="base_url"?e.baseUrl===null||typeof e.baseUrl=="string"&&Ze(e.baseUrl):e.action==="remove"&&typeof e.id=="string"&&e.id.length>0&&e.id.length<=200}function et(r){if(!r||typeof r!="object")return!1;let e=r;if(typeof e.id!="string"||!e.id.trim()||e.id.length>200||e.name!==void 0&&(typeof e.name!="string"||!e.name.trim()||e.name.length>200))return!1;for(let t of[e.contextWindow,e.maxTokens])if(t!==void 0&&(!Number.isSafeInteger(t)||t<=0))return!1;return e.input===void 0||Array.isArray(e.input)&&e.input.length>0&&e.input.every(t=>t==="text"||t==="image")&&new Set(e.input).size===e.input.length}async function tt(r){let e;try{e=await Rr(r,"utf8")}catch(i){if(i.code!=="ENOENT")throw i}if(e===void 0)return{config:{providers:{}}};let t;try{t=JSON.parse(e)}catch{throw new Error("models.json \u542B\u6CE8\u91CA\u6216\u683C\u5F0F\u9519\u8BEF\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u624B\u52A8\u4FEE\u6539")}if(!t||typeof t!="object"||!t.providers||typeof t.providers!="object"||Array.isArray(t.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548");return{config:t,existing:e}}async function Or(r,e,t){await Mr(Dr(r),{recursive:!0});let i=t===void 0?384:(await jr(r)).mode&511,n=`${r}.pi-web-${Tr(6).toString("hex")}.tmp`;try{await Br(n,`${JSON.stringify(e,null,2)}
6
- `,{mode:i,flag:"wx"}),await Wr(n,r)}finally{await Nr(n,{force:!0})}}async function rt(r,e,t){if(!t.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:i}=await tt(r),n=i.providers[e],o=new Set(n?.models?.map(l=>l.id)??[]);return{providerId:e,baseUrl:n?.baseUrl,models:t.getModels(e).map(l=>({id:l.id,name:l.name,contextWindow:l.contextWindow,maxTokens:l.maxTokens,input:[...l.input],source:o.has(l.id)?"custom":"builtin",overridden:!!n?.modelOverrides?.[l.id]}))}}async function it(r,e,t,i){if(!i.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:n,existing:o}=await tt(r),l={...n.providers[e]??{}},u=[...l.models??[]],f={...l.modelOverrides??{}};if(t.action==="base_url"){if(t.baseUrl!==null&&!Ze(t.baseUrl))throw new Error("API \u5730\u5740\u65E0\u6548");t.baseUrl===null?delete l.baseUrl:l.baseUrl=t.baseUrl}else if(t.action==="save"){if(!et(t.model))throw new Error("\u6A21\u578B\u53C2\u6570\u65E0\u6548");let y={id:t.model.id.trim(),...t.model.name===void 0?{}:{name:t.model.name},...t.model.contextWindow===void 0?{}:{contextWindow:t.model.contextWindow},...t.model.maxTokens===void 0?{}:{maxTokens:t.model.maxTokens},...t.model.input===void 0?{}:{input:t.model.input}},c=t.originalId,p=c===void 0?-1:u.findIndex(g=>g.id===c);if(c===void 0&&(u.some(g=>g.id===y.id)||i.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");if(p>=0){if(y.id!==c&&(u.some(m=>m.id===y.id)||i.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");let g={...u[p],...y};for(let m of["name","contextWindow","maxTokens","input"])y[m]===void 0&&delete g[m];u[p]=g}else if(c!==void 0&&i.getModel(e,c)){if(y.id!==c)throw new Error("\u5185\u7F6E\u6A21\u578B ID \u4E0D\u53EF\u4FEE\u6539");let{id:g,...m}=y;f[c]={...f[c],...m};for(let k of["name","contextWindow","maxTokens","input"])y[k]===void 0&&delete f[c][k]}else{if(c!==void 0)throw new Error("\u6A21\u578B\u4E0D\u5B58\u5728");u.push(y)}}else{let y=u.findIndex(c=>c.id===t.id);if(y>=0)u.splice(y,1);else if(Object.hasOwn(f,t.id))delete f[t.id];else throw new Error("\u53EA\u80FD\u79FB\u9664\u81EA\u5B9A\u4E49\u6A21\u578B\u6216\u6062\u590D\u5DF2\u4FEE\u6539\u7684\u5185\u7F6E\u6A21\u578B")}u.length?l.models=u:delete l.models,Object.keys(f).length?l.modelOverrides=f:delete l.modelOverrides,Object.keys(l).length?n.providers[e]=l:delete n.providers[e],await Or(r,n,o)}function st(r){return/^(?:npm:|git:|https?:\/\/|ssh:\/\/|git@)/i.test(r.trim())}import{randomBytes as dt,createHash as Hr}from"node:crypto";import{fileURLToPath as zr}from"node:url";var nt="pi-webapp@0.1.8+d80a7230908decf48708",$="d80a7230908decf48708";var ot={userInfo:!1,cookies:!1,httpHeaders:!1,httpBodies:[],urlQueryParams:!1,genAI:{inputs:!1,outputs:!1},graphQL:{document:!1,variables:!1},databaseQueryData:!1,queues:!1,stackFrameVariables:!1,frameContextLines:0},Lr=new Set(["stage","route","method","status","durationMs","connection","idle","model","thinkingLevel","messageCount","attachmentCount","session","requestId","operationId","errorId","repeats","dropped","componentStack","eventType","sequence","nodeVersion","piVersion","platform","browser","buildId","code"]),$r=new Set(["/api/plugins","/api/plugin-action","/api/plugin-interaction","/api/resume","/api/update","/api/update/version","/api/provider/models","/api/provider/logout","/api/provider/login/active","/api/telemetry/config","/api/image","/api/attachment","/api/attachment/remove","/api/session","/api/providers","/api/models","/api/config","/api/workspaces","/api/commands","/api/events","/api/message","/api/abort","/api/compact","/api/new-session","/api/model","/api/thinking-level","/api/provider/login","/api/provider/login/respond","/api/provider/login/cancel","/api/provider/custom","/api/workspace/add","/api/workspace/select","/api/workspace/new-session","/api/workspace/remove","/api/session/select","/api/directory/capability","/api/directory/list","/api/directory/create","/api/directory/pick"]);function at(r){return r==="/api/message"||r.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(r)}function B(r){return r.slice(0,8192).replace(/(?:Bearer\s+\S+|(?:api[_-]?key|token|password|secret|authorization)\s*[=:]\s*\S+)/gi,"[redacted]").replace(/\b(?:sk-|sntrys_|eyJ)[A-Za-z0-9_.-]+/g,"[redacted]").replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,"[email]").replace(/https?:\/\/[^\s)]+/gi,"[url]").replace(/(?:file:\/\/)?(?:\/[\w.~-]+){2,}(?::\d+(?::\d+)?)?/g,"[path]").replace(/[A-Za-z]:\\[^\s)]+/g,"[path]").replace(/(["'`])[^\n]*?\1/g,"[quoted]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function V(r){let e={};for(let t of Lr){let i=r[t];t==="route"&&typeof i=="string"?e[t]=$r.has(i.split("?")[0])?i.split("?")[0]:"[route]":typeof i=="string"?e[t]=["requestId","operationId","errorId","session","buildId"].includes(t)&&/^[\w-]{1,80}$/.test(i)?i:B(i):(typeof i=="boolean"||typeof i=="number"&&Number.isFinite(i)||i===null)&&(e[t]=i)}return e}function Pe(r){let e=r.replace(/\\/g,"/").split(/[?#]/)[0];return e.startsWith("node:")?e.slice(0,150):`app:///${(e.match(/(?:^|\/)((?:web\/src|extension|shared|dist|assets)\/[^\s:)]+)$/)?.[1]??e.split("/").pop()??"unknown").replace(/[^\w./-]/g,"_").slice(-200)}`}function oe(r,e=0){let t=r instanceof Error?r:new Error(typeof r=="string"?r:"Non-Error rejection"),i=new Error(B(t.message));if(i.name=B(t.name).slice(0,100),t.stack){let n=t.stack.split(`
4
+ `)}`);let p=this.reportError(c,{...o,stage:"provider_login"});f.view={id:u,providerId:e,method:t,status:"error",error:"\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u63D0\u4F9B\u65B9\u63D0\u793A\u5E76\u91CD\u8BD5\u3002",errorId:p}}}),{...f.view}}get(e){let t=this.flows.get(e)?.view;return t?{...t}:void 0}getActive(){let e=[...this.flows.values()].find(({view:t})=>t.status==="running"||t.status==="waiting")?.view;return e?{...e}:void 0}respond(e,t){let i=this.flows.get(e);if(!i?.answer||i.view.status!=="waiting"||i.view.prompt?.type==="select"&&!i.view.prompt.options.some(o=>o.id===t))return!1;let s=i.answer;return i.answer=void 0,i.reject=void 0,i.view={...i.view,status:"running",prompt:void 0},s(t),!0}cancel(e){let t=this.flows.get(e);return!t||t.view.status==="done"||t.view.status==="error"?!1:(t.view={...t.view,status:"cancelled",prompt:void 0},t.controller.abort(),t.reject?.(new Error("\u767B\u5F55\u5DF2\u53D6\u6D88")),t.answer=void 0,t.reject=void 0,!0)}close(){for(let e of this.flows.keys())this.cancel(e);this.flows.clear()}};import{randomBytes as xr}from"node:crypto";import{readFile as Cr,rename as Ar,rm as _r,stat as Tr,writeFile as Mr,mkdir as Rr}from"node:fs/promises";import{dirname as Wr}from"node:path";var Nr=["openai-completions","openai-responses","anthropic-messages"];function ke(r){if(!r||typeof r!="object")return!1;let e=r;if(typeof e.id!="string"||!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(e.id)||typeof e.name!="string"||!e.name.trim()||e.name.length>100||typeof e.modelId!="string"||!e.modelId.trim()||e.modelId.length>200||!Nr.includes(e.api)||typeof e.baseUrl!="string"||e.baseUrl.length>2048)return!1;try{let t=new URL(e.baseUrl);return(t.protocol==="https:"||t.protocol==="http:")&&!!t.hostname&&!t.username&&!t.password&&!t.hash}catch{return!1}}async function Ze(r,e){if(!ke(e))throw new Error("\u81EA\u5B9A\u4E49\u63D0\u4F9B\u65B9\u540D\u79F0\u3001\u5730\u5740\u6216\u6A21\u578B\u65E0\u6548");let t;try{t=await Cr(r,"utf8")}catch(u){if(u.code!=="ENOENT")throw u}let i;if(t===void 0)i={providers:{}};else{try{i=JSON.parse(t)}catch{throw new Error("models.json \u542B\u6CE8\u91CA\u6216\u683C\u5F0F\u9519\u8BEF\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u624B\u52A8\u6DFB\u52A0\u63D0\u4F9B\u65B9")}if(!i||typeof i!="object"||!i.providers||typeof i.providers!="object"||Array.isArray(i.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548")}if(Object.hasOwn(i.providers,e.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");let s={...i,providers:{...i.providers,[e.id]:{name:e.name.trim(),baseUrl:e.baseUrl,api:e.api,models:[{id:e.modelId.trim()}]}}};await Rr(Wr(r),{recursive:!0});let o=t===void 0?384:(await Tr(r)).mode&511,l=`${r}.pi-web-${xr(6).toString("hex")}.tmp`;try{await Mr(l,`${JSON.stringify(s,null,2)}
5
+ `,{mode:o,flag:"wx"}),await Ar(l,r)}finally{await _r(l,{force:!0})}}import{randomBytes as jr}from"node:crypto";import{mkdir as Br,readFile as Dr,rename as Or,rm as Lr,stat as $r,writeFile as Vr}from"node:fs/promises";import{dirname as Ur}from"node:path";function Qe(r){if(!r||r.length>2048)return!1;try{let e=new URL(r);return(e.protocol==="https:"||e.protocol==="http:")&&!!e.hostname&&!e.username&&!e.password&&!e.search&&!e.hash}catch{return!1}}function et(r){if(!r||typeof r!="object")return!1;let e=r;return e.action==="save"?(e.originalId===void 0||typeof e.originalId=="string")&&tt(e.model):e.action==="base_url"?e.baseUrl===null||typeof e.baseUrl=="string"&&Qe(e.baseUrl):e.action==="remove"&&typeof e.id=="string"&&e.id.length>0&&e.id.length<=200}function tt(r){if(!r||typeof r!="object")return!1;let e=r;if(typeof e.id!="string"||!e.id.trim()||e.id.length>200||e.name!==void 0&&(typeof e.name!="string"||!e.name.trim()||e.name.length>200))return!1;for(let t of[e.contextWindow,e.maxTokens])if(t!==void 0&&(!Number.isSafeInteger(t)||t<=0))return!1;return e.input===void 0||Array.isArray(e.input)&&e.input.length>0&&e.input.every(t=>t==="text"||t==="image")&&new Set(e.input).size===e.input.length}async function rt(r){let e;try{e=await Dr(r,"utf8")}catch(i){if(i.code!=="ENOENT")throw i}if(e===void 0)return{config:{providers:{}}};let t;try{t=JSON.parse(e)}catch{throw new Error("models.json \u542B\u6CE8\u91CA\u6216\u683C\u5F0F\u9519\u8BEF\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u624B\u52A8\u4FEE\u6539")}if(!t||typeof t!="object"||!t.providers||typeof t.providers!="object"||Array.isArray(t.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548");return{config:t,existing:e}}async function Fr(r,e,t){await Br(Ur(r),{recursive:!0});let i=t===void 0?384:(await $r(r)).mode&511,s=`${r}.pi-web-${jr(6).toString("hex")}.tmp`;try{await Vr(s,`${JSON.stringify(e,null,2)}
6
+ `,{mode:i,flag:"wx"}),await Or(s,r)}finally{await Lr(s,{force:!0})}}async function it(r,e,t){if(!t.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:i}=await rt(r),s=i.providers[e],o=new Set(s?.models?.map(l=>l.id)??[]);return{providerId:e,baseUrl:s?.baseUrl,models:t.getModels(e).map(l=>({id:l.id,name:l.name,contextWindow:l.contextWindow,maxTokens:l.maxTokens,input:[...l.input],source:o.has(l.id)?"custom":"builtin",overridden:!!s?.modelOverrides?.[l.id]}))}}async function nt(r,e,t,i){if(!i.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:s,existing:o}=await rt(r),l={...s.providers[e]??{}},u=[...l.models??[]],f={...l.modelOverrides??{}};if(t.action==="base_url"){if(t.baseUrl!==null&&!Qe(t.baseUrl))throw new Error("API \u5730\u5740\u65E0\u6548");t.baseUrl===null?delete l.baseUrl:l.baseUrl=t.baseUrl}else if(t.action==="save"){if(!tt(t.model))throw new Error("\u6A21\u578B\u53C2\u6570\u65E0\u6548");let y={id:t.model.id.trim(),...t.model.name===void 0?{}:{name:t.model.name},...t.model.contextWindow===void 0?{}:{contextWindow:t.model.contextWindow},...t.model.maxTokens===void 0?{}:{maxTokens:t.model.maxTokens},...t.model.input===void 0?{}:{input:t.model.input}},c=t.originalId,p=c===void 0?-1:u.findIndex(g=>g.id===c);if(c===void 0&&(u.some(g=>g.id===y.id)||i.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");if(p>=0){if(y.id!==c&&(u.some(m=>m.id===y.id)||i.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");let g={...u[p],...y};for(let m of["name","contextWindow","maxTokens","input"])y[m]===void 0&&delete g[m];u[p]=g}else if(c!==void 0&&i.getModel(e,c)){if(y.id!==c)throw new Error("\u5185\u7F6E\u6A21\u578B ID \u4E0D\u53EF\u4FEE\u6539");let{id:g,...m}=y;f[c]={...f[c],...m};for(let k of["name","contextWindow","maxTokens","input"])y[k]===void 0&&delete f[c][k]}else{if(c!==void 0)throw new Error("\u6A21\u578B\u4E0D\u5B58\u5728");u.push(y)}}else{let y=u.findIndex(c=>c.id===t.id);if(y>=0)u.splice(y,1);else if(Object.hasOwn(f,t.id))delete f[t.id];else throw new Error("\u53EA\u80FD\u79FB\u9664\u81EA\u5B9A\u4E49\u6A21\u578B\u6216\u6062\u590D\u5DF2\u4FEE\u6539\u7684\u5185\u7F6E\u6A21\u578B")}u.length?l.models=u:delete l.models,Object.keys(f).length?l.modelOverrides=f:delete l.modelOverrides,Object.keys(l).length?s.providers[e]=l:delete s.providers[e],await Fr(r,s,o)}function st(r){return/^(?:npm:|git:|https?:\/\/|ssh:\/\/|git@)/i.test(r.trim())}import{randomBytes as pt,createHash as Yr}from"node:crypto";import{fileURLToPath as Kr}from"node:url";var ot="pi-webapp@0.1.9+4e474e01cb4c03bcacf2",$="4e474e01cb4c03bcacf2";var at={userInfo:!1,cookies:!1,httpHeaders:!1,httpBodies:[],urlQueryParams:!1,genAI:{inputs:!1,outputs:!1},graphQL:{document:!1,variables:!1},databaseQueryData:!1,queues:!1,stackFrameVariables:!1,frameContextLines:0},Hr=new Set(["stage","route","method","status","durationMs","connection","idle","model","thinkingLevel","messageCount","attachmentCount","session","requestId","operationId","errorId","repeats","dropped","componentStack","eventType","sequence","nodeVersion","piVersion","platform","browser","buildId","code"]),zr=new Set(["/api/plugins","/api/plugin-action","/api/plugin-interaction","/api/resume","/api/update","/api/update/version","/api/provider/models","/api/provider/logout","/api/provider/login/active","/api/telemetry/config","/api/image","/api/attachment","/api/attachment/remove","/api/session","/api/providers","/api/models","/api/config","/api/workspaces","/api/commands","/api/events","/api/message","/api/abort","/api/compact","/api/new-session","/api/model","/api/thinking-level","/api/provider/login","/api/provider/login/respond","/api/provider/login/cancel","/api/provider/custom","/api/workspace/add","/api/workspace/select","/api/workspace/new-session","/api/workspace/remove","/api/session/select","/api/directory/capability","/api/directory/list","/api/directory/create","/api/directory/pick"]);function ct(r){return r==="/api/message"||r.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(r)}function B(r){return r.slice(0,8192).replace(/(?:Bearer\s+\S+|(?:api[_-]?key|token|password|secret|authorization)\s*[=:]\s*\S+)/gi,"[redacted]").replace(/\b(?:sk-|sntrys_|eyJ)[A-Za-z0-9_.-]+/g,"[redacted]").replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,"[email]").replace(/https?:\/\/[^\s)]+/gi,"[url]").replace(/(?:file:\/\/)?(?:\/[\w.~-]+){2,}(?::\d+(?::\d+)?)?/g,"[path]").replace(/[A-Za-z]:\\[^\s)]+/g,"[path]").replace(/(["'`])[^\n]*?\1/g,"[quoted]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function V(r){let e={};for(let t of Hr){let i=r[t];t==="route"&&typeof i=="string"?e[t]=zr.has(i.split("?")[0])?i.split("?")[0]:"[route]":typeof i=="string"?e[t]=["requestId","operationId","errorId","session","buildId"].includes(t)&&/^[\w-]{1,80}$/.test(i)?i:B(i):(typeof i=="boolean"||typeof i=="number"&&Number.isFinite(i)||i===null)&&(e[t]=i)}return e}function Pe(r){let e=r.replace(/\\/g,"/").split(/[?#]/)[0];return e.startsWith("node:")?e.slice(0,150):`app:///${(e.match(/(?:^|\/)((?:web\/src|extension|shared|dist|assets)\/[^\s:)]+)$/)?.[1]??e.split("/").pop()??"unknown").replace(/[^\w./-]/g,"_").slice(-200)}`}function oe(r,e=0){let t=r instanceof Error?r:new Error(typeof r=="string"?r:"Non-Error rejection"),i=new Error(B(t.message));if(i.name=B(t.name).slice(0,100),t.stack){let s=t.stack.split(`
7
7
  `).slice(1,31).map(o=>{let l=o.match(/((?:file:\/\/|https?:\/\/|\/|[A-Za-z]:\\)[^\s()]+):(\d+):(\d+)(\)?)$/);return l?`${B(o.slice(0,l.index))}${l[1]}:${l[2]}:${l[3]}${l[4]}`:B(o)});i.stack=`${i.name}: ${i.message}
8
- ${n.join(`
8
+ ${s.join(`
9
9
  `)}`}return e<3&&t.cause!==void 0&&(i.cause=oe(t.cause,e+1)),i}function ae(r,e){let t=new Error(e);return r instanceof Error&&(t.name=r.name,r.stack&&(t.stack=`${t.name}: ${e}
10
10
  ${r.stack.split(`
11
11
  `).slice(1).join(`
12
- `)}`)),t}function Vr(r){return{...r.filename?{filename:Pe(r.filename)}:{},...r.abs_path?{abs_path:Pe(r.abs_path)}:{},...r.function?{function:B(r.function)}:{},lineno:r.lineno,colno:r.colno,in_app:r.in_app}}function Ur(r){return{event_id:r.event_id,timestamp:r.timestamp,platform:r.platform,level:r.level,release:r.release,dist:r.dist,environment:B(r.environment??"production"),...r.message?{message:B(r.message)}:{},exception:r.exception?{values:r.exception.values?.slice(0,4).map(e=>({type:B(e.type??"Error"),value:B(e.value??""),...e.stacktrace?{stacktrace:{frames:e.stacktrace.frames?.slice(-30).map(Vr)}}:{},...e.mechanism?{mechanism:{type:e.mechanism.type,handled:e.mechanism.handled}}:{}}))}:void 0,tags:{side:r.tags?.side,buildId:r.tags?.buildId},contexts:{diagnostic:V(r.contexts?.diagnostic??{})},breadcrumbs:r.breadcrumbs?.slice(-100).map(e=>({timestamp:e.timestamp,category:B(e.category??"app"),data:V(e.data??{})})),debug_meta:r.debug_meta?{images:r.debug_meta.images?.slice(0,10).map(e=>({type:e.type,debug_id:e.debug_id,...e.code_file?{code_file:Pe(e.code_file)}:{}}))}:void 0}}function ct(r,e){return e.attachments=[],Ur(r)}var K=class{items=[];bytes=0;encoder=new TextEncoder;add(e,t={}){let i={timestamp:Date.now()/1e3,category:B(e),data:V(t)},n=this.encoder.encode(JSON.stringify(i)).byteLength+1;for(this.items.push({item:i,size:n}),this.bytes+=n;this.items.length>100||this.bytes>64*1024-2;)this.bytes-=this.items.shift().size}snapshot(){return this.items.map(({item:e})=>e)}},Ee=class{windowAt=-1;total=0;seen=new Map;take(e,t=Date.now()){(this.windowAt<0||t-this.windowAt>=6e4)&&(this.windowAt=t,this.total=0);let i=this.seen.get(e);if(i&&t-i.at<6e4){i.repeats++;return}if(!(this.total>=20))return this.total++,this.seen.size>=64&&!i&&this.seen.delete(this.seen.keys().next().value),this.seen.set(e,{at:t,repeats:0}),{repeats:i?.repeats??0}}},Fr=new Set(["\u4F1A\u8BDD\u5DF2\u5207\u6362","Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F","\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F","\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A","\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u4F1A\u8BDD","\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A","\u65B0\u4F1A\u8BDD\u5DF2\u53D6\u6D88","\u5DF2\u6709\u767B\u5F55\u6B63\u5728\u8FDB\u884C","\u6A21\u578B\u4E0D\u53EF\u7528","\u6A21\u578B\u63D0\u4F9B\u65B9\u672A\u914D\u7F6E\u8BA4\u8BC1","\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6","\u5176\u4ED6\u63D0\u4F9B\u65B9\u7684\u767B\u5F55\u6B63\u5728\u8FDB\u884C\uFF0C\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D\u767B\u5F55","\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1","\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u4EA4\u4E92\u6216\u5BA1\u6279","\u8BF7\u5148\u9009\u62E9\u6A21\u578B","\u8BF7\u5148\u8FDE\u63A5\u5F53\u524D\u6A21\u578B","\u63D2\u4EF6\u672A\u542F\u7528","\u4F1A\u8BDD\u8FD0\u884C\u5B9E\u4F8B\u5DF2\u5207\u6362","\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728","\u6587\u4EF6\u8D85\u8FC7 20 MB","\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927","\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A","\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548"]);function U(r){return r instanceof Error&&(r.name==="AbortError"||Fr.has(r.message))}var ne=class{budget=new Ee;breadcrumbs;scopeClass;seen=new WeakSet;state={};client;side;buildId;constructor(e,t,i,n,o=new K){this.client=e,this.side=t,this.buildId=i,this.scopeClass=n.Scope,this.breadcrumbs=o,e.addIntegration(n.linkedErrorsIntegration({limit:4}))}setState(e){this.state=V(e)}capture(e,t={},i){try{if(U(e))return;if(typeof e=="object"&&e!==null){if(this.seen.has(e))return;this.seen.add(e)}let n=oe(e),o=`${n.name}:${n.message}:${n.stack?.split(`
13
- `)[1]??""}:${t.stage??""}`,l=this.budget.take(o);if(!l)return;let u=new this.scopeClass;u.setClient(this.client),u.setTags({side:this.side,buildId:this.buildId}),u.setContext("diagnostic",V({...this.state,...t,repeats:l.repeats}));for(let f of this.breadcrumbs.snapshot())u.addBreadcrumb(f,100);return u.captureException(n,i?{event_id:i}:void 0)}catch{return}}ignore(e){this.seen.add(e)}};function lt(r,e){return r({...e,bufferSize:20},async({body:t})=>{let i=await fetch(e.url,{method:"POST",body:t,signal:AbortSignal.timeout(3e3),credentials:"omit",referrerPolicy:"no-referrer",redirect:"error",headers:{"Content-Type":"application/x-sentry-envelope"}});return{statusCode:i.status,headers:{"x-sentry-rate-limits":i.headers.get("x-sentry-rate-limits"),"retry-after":i.headers.get("retry-after")}}})}var Gr="https://070c0b7c5ac18d940c294e63ecfa0793@o4506663318716416.ingest.us.sentry.io/4512191040716800";function Jr(r=process.env,e=console.warn){let t=i=>{let n={enabled:!1,environment:r.PI_WEB_SENTRY_ENVIRONMENT||"production",release:nt,buildId:$},o=r[`PI_WEB_SENTRY_${i}_DSN`]??r.PI_WEB_SENTRY_DSN??Gr;if(r.PI_WEB_SENTRY_ENABLED==="false"||!o)return n;try{let l=new URL(o);if(l.protocol!=="https:"||!/^[\w-]+$/.test(l.username)||l.password||l.search||l.hash||!/\/(?:[\w-]+\/)*\d+$/.test(l.pathname))throw new Error;return{...n,enabled:!0,dsn:o}}catch{return e(`pi-webapp: invalid ${i.toLowerCase()} Sentry DSN; error reporting disabled for this side.`),n}};return{browser:t("BROWSER"),node:t("NODE")}}var F=class{config;ready;reporter;client;salt=dt(16);breadcrumbs=new K;seen=new WeakSet;early=[];state={nodeVersion:process.version,platform:process.platform};fatal;closed=!1;failed=!1;get enabled(){return this.config.node.enabled&&!this.closed&&!this.failed}constructor(e={}){if(this.config=Jr(e.env),!this.config.node.enabled){this.ready=Promise.resolve();return}if(e.monitor!==!1){let t=zr(import.meta.url).replace(/\\/g,"/"),i=t.slice(0,t.lastIndexOf("/")+1);this.fatal=n=>{n.stack?.replace(/\\/g,"/").includes(t.endsWith("extension.js")?t:i)&&this.capture(n,{stage:"fatal"})},process.on("uncaughtExceptionMonitor",this.fatal)}this.ready=import("@sentry/node").then(t=>{if(!this.closed){this.client=new t.NodeClient({...this.config.node,dist:$,integrations:[],transport:e.transport??(i=>lt(t.createTransport,i)),stackParser:t.defaultStackParser,beforeSend:ct,sendClientReports:!1,dataCollection:{...ot,httpBodies:[]},includeServerName:!1,enableRuntimeChannelInjection:!1,beforeSendLog:()=>null,beforeSendMetric:()=>null,enableOpenTelemetrySetup:!1,maxBreadcrumbs:100}),this.reporter=new ne(this.client,"node",$,t,this.breadcrumbs),this.reporter.setState(this.state);for(let i of this.early)this.reporter.capture(i.error,i.context,i.eventId)}}).catch(()=>{this.failed=!0,console.warn("pi-webapp: Sentry initialization failed; error reporting disabled.")}).finally(()=>{this.early=[]})}capture(e,t={}){try{if(!this.enabled||U(e))return;if(typeof e=="object"&&e!==null){if(this.seen.has(e))return;this.seen.add(e)}if(this.reporter)return this.reporter.capture(e,t);if(this.early.length>=20)return;let i=dt(16).toString("hex");return this.early.push({error:oe(e),context:V(t),eventId:i}),i}catch{return}}setState(e){this.state=V({...this.state,...e}),this.reporter?.setState(this.state)}breadcrumb(e,t={}){this.enabled&&this.breadcrumbs.add(e,t)}session(e){return Hr("sha256").update(this.salt).update(e).digest("hex").slice(0,16)}async close(){let e=performance.now(),t;try{await Promise.race([this.ready,new Promise(i=>{t=setTimeout(i,500)})])}finally{clearTimeout(t),this.closed=!0,this.fatal&&process.off("uncaughtExceptionMonitor",this.fatal)}try{await this.client?.close(Math.max(1,500-(performance.now()-e)))}catch{}}};import{VERSION as ti}from"@earendil-works/pi-coding-agent";import{readFile as qr}from"node:fs/promises";import{join as Yr}from"node:path";async function pt(r){try{let e=JSON.parse(await qr(Yr(r,".vite/manifest.json"),"utf8"));if(!e||typeof e!="object")return{};let t=new Set;for(let n of Object.values(e))if(!(!n||typeof n!="object"))for(let o of[n.file,...Array.isArray(n.css)?n.css:[],...Array.isArray(n.assets)?n.assets:[]])typeof o=="string"&&/^assets\/[\w.-]+\.(?:js|css|woff2?|ttf|png|jpe?g|svg|webp)$/.test(o)&&t.add(o);let i={js:"text/javascript; charset=utf-8",css:"text/css; charset=utf-8",svg:"image/svg+xml",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf"};return Object.fromEntries([...t].map(n=>[`/${n}`,{path:n,type:i[n.split(".").pop()]}]))}catch{return{}}}var ri={"/":{path:"index.html",type:"text/html; charset=utf-8"},"/assets/app.js":{path:"assets/app.js",type:"text/javascript; charset=utf-8"},"/assets/style.css":{path:"assets/style.css",type:"text/css; charset=utf-8"}};function w(r,e,t){typeof t=="object"&&t!==null&&"error"in t&&(t={errorCode:e>=500?"server_error":"validation_error",...t,requestId:r.getHeader("X-Request-ID"),operationId:r.getHeader("X-Operation-ID")}),r.writeHead(e,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),r.end(JSON.stringify(t))}function ii(r,e){let t=r.headers.authorization;if(typeof t!="string"||!t.startsWith("Bearer "))return!1;let i=Buffer.from(t.slice(7),"utf8");return i.length===e.length&&Xr(i,e)}async function si(r){let e=0,t=[];for await(let i of r){let n=Buffer.isBuffer(i)?i:Buffer.from(i);if(e+=n.length,e>64*1024)throw new Error("\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927");t.push(n)}return JSON.parse(Buffer.concat(t).toString("utf8"))}async function ni(r){let e=0,t=[];for await(let i of r){let n=Buffer.isBuffer(i)?i:Buffer.from(i);if(e+=n.length,e>ie)throw new Error("\u6587\u4EF6\u8D85\u8FC7 20 MB");t.push(n)}return Buffer.concat(t)}async function oi(r,e=0){await new Promise((i,n)=>{r.once("error",n),r.listen(e,"127.0.0.1",()=>{r.off("error",n),i()})});let t=r.address();if(t===null||typeof t=="string")throw new Error("\u65E0\u6CD5\u786E\u5B9A\u76D1\u542C\u7AEF\u53E3");return t.port}async function gt(r,e,t=new F){t.setState({piVersion:ti});let i=process.env.PI_WEBAPP_RESTART_TOKEN,n=i&&/^[A-Za-z0-9_-]{32}$/.test(i)?i:Kr(24).toString("base64url"),o=Buffer.from(n),l=He(),u=new Set,f=new Map,y=new se((h,d)=>t.capture(h,d)),c=h=>t.setState({nodeVersion:process.version,platform:process.platform,session:t.session(h.sessionId),idle:h.idle,model:h.model,thinkingLevel:h.thinkingLevel,messageCount:h.messages.length}),p="",g=!1,m={...ri,...await pt(e)};for(let h of await Qr(ft(e,"assets")).catch(()=>[])){let d=/^[\w.-]+\.(js|css|woff2?|ttf)$/.exec(h);if(!d)continue;let C={js:"text/javascript; charset=utf-8",css:"text/css; charset=utf-8",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf"};m[`/assets/${h}`]={path:`assets/${h}`,type:C[d[1]]}}let k=ei(async(h,d)=>{let C=R=>typeof R=="string"&&/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(R),E=C(h.headers["x-request-id"])?h.headers["x-request-id"]:ut(),x={requestId:E,operationId:C(h.headers["x-operation-id"])?h.headers["x-operation-id"]:void 0};d.setHeader("X-Request-ID",E),x.operationId&&d.setHeader("X-Operation-ID",x.operationId);let v="/",zt=performance.now(),W=(R,a,b)=>{let I=!U(R)&&at(v)?ae(R,"Agent or provider operation failed"):R,O=t.capture(I,{...x,route:v,method:h.method,status:a,stage:"http"});w(d,a,{error:b,errorId:O,errorReported:t.enabled,errorCode:U(R)?"validation_error":"unexpected_error"})};d.once("finish",()=>{v.startsWith("/api/telemetry/")||t.breadcrumb("request",{...x,route:v,method:h.method,status:d.statusCode,durationMs:Math.round(performance.now()-zt)})});try{d.setHeader("X-Content-Type-Options","nosniff"),d.setHeader("Referrer-Policy","no-referrer"),d.setHeader("Content-Security-Policy",`default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'self'${t.config.browser.dsn?` ${new URL(t.config.browser.dsn).origin}`:""}; img-src 'self' data: blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'`);try{v=new URL(h.url??"/",p).pathname}catch{w(d,400,{error:"\u8BF7\u6C42\u5730\u5740\u65E0\u6548"});return}let R=m[v];if(h.method==="GET"&&R){try{let a=await Zr(ft(e,R.path));d.writeHead(200,{"Content-Type":R.type,"Cache-Control":"no-store"}),d.end(a)}catch(a){W(a,500,"\u9875\u9762\u6587\u4EF6\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v.startsWith("/plugins/")){try{let a=await r.pluginAsset?.(h.url??v);if(!a){w(d,404,{error:"\u63D2\u4EF6\u8D44\u6E90\u4E0D\u5B58\u5728"});return}d.writeHead(200,{"Content-Type":a.type,"Cache-Control":"no-store"}),d.end(a.bytes)}catch(a){W(a,404,"\u63D2\u4EF6\u8D44\u6E90\u4E0D\u53EF\u7528")}return}if(!v.startsWith("/api/")){w(d,404,{error:"\u672A\u627E\u5230"});return}if(!ii(h,o)){w(d,401,{error:"\u8BBF\u95EE\u4EE4\u724C\u65E0\u6548"});return}if(h.method==="GET"&&v==="/api/telemetry/config"){w(d,200,t.config.browser);return}if(h.method==="GET"&&v==="/api/update/version"){try{w(d,200,{current:await r.selfUpdate?.runningVersion()??null})}catch(a){W(a,503,a instanceof Error?a.message:"\u65E0\u6CD5\u8BFB\u53D6\u7248\u672C")}return}if(h.method==="GET"&&v==="/api/update"){try{w(d,200,await r.selfUpdate?.check()??{canRestart:!1,reason:"\u5F53\u524D\u6269\u5C55\u4E0D\u652F\u6301\u5728\u7EBF\u5347\u7EA7"})}catch(a){W(a,503,a instanceof Error?a.message:"\u68C0\u67E5\u66F4\u65B0\u5931\u8D25")}return}if(h.method==="GET"&&v==="/api/image"){let a=new URL(h.url??v,p),b=a.searchParams.get("sessionId")??"",S=a.searchParams.get("messageId")??"",I=Number(a.searchParams.get("index"));if(!b||b!==r.snapshot().sessionId||!S||!Number.isInteger(I)||I<0||I>100){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u56FE\u7247\u5730\u5740\u65E0\u6548"});return}let O=r.image?.(b,S,I);if(!O||!["image/png","image/jpeg","image/webp","image/gif"].includes(O.mimeType)){w(d,404,{error:"\u56FE\u7247\u4E0D\u53EF\u7528"});return}d.writeHead(200,{"Content-Type":O.mimeType,"Cache-Control":"private, no-store"}),d.end(O.data);return}if(h.method==="POST"&&v==="/api/attachment"){if(h.headers.origin!==void 0&&h.headers.origin!==p){w(d,403,{error:"\u6765\u6E90\u4E0D\u5339\u914D"});return}let a=new URL(h.url??v,p),b=a.searchParams.get("sessionId"),S=a.searchParams.get("name");try{if(!b||!S||S.length>1024||b!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u6587\u4EF6\u540D\u65E0\u6548"});return}if(Number(h.headers["content-length"]??0)>ie){w(d,413,{error:"\u6587\u4EF6\u8D85\u8FC7 20 MB"});return}let I=await qe(b,S,h.headers["content-type"]??"application/octet-stream",await ni(h));if(b!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}f.set(I.id,I),w(d,201,{id:I.id,name:I.name,bytes:I.bytes})}catch(I){W(I,400,I instanceof Error?I.message:"\u4E0A\u4F20\u5931\u8D25")}return}if(h.method==="GET"&&v==="/api/session"){try{let a=r.snapshot();c(a),w(d,200,a)}catch(a){W(a,503,"\u5F53\u524D\u4F1A\u8BDD\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/plugins"){try{w(d,200,await r.plugins?.()??{plugins:[],errors:[]})}catch(a){W(a,503,"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/providers"){try{w(d,200,await r.providers?.()??[])}catch(a){W(a,503,"\u6A21\u578B\u63D0\u4F9B\u65B9\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/provider/models"){let a=new URL(h.url??v,p).searchParams.get("providerId")??"";try{if(!a||!r.providerModels){w(d,400,{error:"\u63D0\u4F9B\u65B9\u65E0\u6548"});return}w(d,200,await r.providerModels(a))}catch(b){W(b,400,b instanceof Error?b.message:"\u6A21\u578B\u76EE\u5F55\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/provider/login/active"){w(d,200,{active:y.getActive()??null});return}if(h.method==="GET"&&v==="/api/provider/login"){let a=new URL(h.url??v,p).searchParams.get("id")??"",b=y.get(a);w(d,b?200:404,b??{error:"\u767B\u5F55\u6D41\u7A0B\u4E0D\u5B58\u5728"});return}if(h.method==="GET"&&(v==="/api/models"||v==="/api/config"||v==="/api/workspaces"||v==="/api/commands")){try{w(d,200,v==="/api/models"?await r.models():v==="/api/config"?await r.config():v==="/api/commands"?r.commands?.()??[]:await r.workspaces())}catch(a){W(a,503,"Pi \u914D\u7F6E\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/directory/capability"){w(d,200,{kind:l});return}if(h.method==="GET"&&v==="/api/events"){let a;try{a=r.snapshot(),c(a)}catch(b){W(b,503,"\u5F53\u524D\u4F1A\u8BDD\u4E0D\u53EF\u7528");return}d.writeHead(200,{"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"no-store",Connection:"keep-alive","X-Accel-Buffering":"no"}),u.add(d),d.write(`${JSON.stringify({type:"snapshot",session:a})}
14
- `),d.on("close",()=>u.delete(d));return}if(h.method==="POST"&&["/api/plugin-interaction","/api/plugin-action","/api/update","/api/message","/api/attachment/remove","/api/abort","/api/resume","/api/compact","/api/new-session","/api/model","/api/thinking-level","/api/config","/api/provider/login","/api/provider/login/respond","/api/provider/login/cancel","/api/provider/custom","/api/provider/models","/api/provider/logout","/api/workspace/add","/api/workspace/select","/api/workspace/new-session","/api/workspace/remove","/api/session/select","/api/directory/list","/api/directory/create","/api/directory/pick"].includes(v)){if(h.headers.origin!==void 0&&h.headers.origin!==p){w(d,403,{error:"\u6765\u6E90\u4E0D\u5339\u914D"});return}if(!h.headers["content-type"]?.startsWith("application/json")){w(d,415,{error:"\u9700\u8981 JSON \u8BF7\u6C42"});return}try{let a;try{a=await si(h)}catch(b){if(b instanceof SyntaxError||U(b)){w(d,400,{error:"\u8BF7\u6C42\u5185\u5BB9\u65E0\u6548"});return}throw b}if(typeof a!="object"||a===null||!("sessionId"in a)||typeof a.sessionId!="string"){w(d,400,{error:"\u7F3A\u5C11\u4F1A\u8BDD\u6807\u8BC6"});return}if(v==="/api/plugin-interaction"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("pluginId"in a)||typeof a.pluginId!="string"||a.pluginId.length>200||!("requestId"in a)||typeof a.requestId!="string"||a.requestId.length>200||!r.resolvePluginInteraction||!("value"in a)){w(d,400,{error:"\u63D2\u4EF6\u4EA4\u4E92\u54CD\u5E94\u65E0\u6548"});return}await r.resolvePluginInteraction(a.sessionId,a.pluginId,a.requestId,a.value),w(d,200,{accepted:!0});return}if(v==="/api/plugin-action"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("pluginId"in a)||typeof a.pluginId!="string"||a.pluginId.length>200||!("action"in a)||typeof a.action!="string"||a.action.length>100||!r.invokePluginAction){w(d,400,{error:"\u63D2\u4EF6\u52A8\u4F5C\u65E0\u6548"});return}let b=await r.invokePluginAction(a.sessionId,a.pluginId,a.action,"input"in a?a.input:void 0);w(d,200,{value:b});return}if(v==="/api/update"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!r.snapshot().idle){w(d,409,{error:"\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u540E\u518D\u5347\u7EA7"});return}if(!r.selfUpdate){w(d,409,{error:"\u5F53\u524D\u6269\u5C55\u4E0D\u652F\u6301\u5728\u7EBF\u5347\u7EA7"});return}let b=await r.selfUpdate.prepare();g=!0,w(d,202,{accepted:!0,version:b.version}),setTimeout(()=>{r.selfUpdate?.requestRestart(b).catch(S=>{g=!1,t.capture(S,{stage:"restart"}),console.error("pi-webapp restart:",S)})},500).unref();return}if(v==="/api/provider/custom"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("provider"in a)||!ke(a.provider)||!r.addCustomProvider){w(d,400,{error:"\u81EA\u5B9A\u4E49\u63D0\u4F9B\u65B9\u65E0\u6548"});return}await r.addCustomProvider(a.sessionId,a.provider),w(d,201,{accepted:!0});return}if(v==="/api/provider/models"||v==="/api/provider/logout"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("providerId"in a)||typeof a.providerId!="string"){w(d,400,{error:"\u63D0\u4F9B\u65B9\u65E0\u6548"});return}if(v==="/api/provider/models"){if(!("change"in a)||!Qe(a.change)||!r.updateProviderModel){w(d,400,{error:"\u6A21\u578B\u53C2\u6570\u65E0\u6548"});return}await r.updateProviderModel(a.sessionId,a.providerId,a.change)}else{if(!r.logoutProvider){w(d,400,{error:"\u65E0\u6CD5\u79FB\u9664\u8BA4\u8BC1"});return}await r.logoutProvider(a.sessionId,a.providerId)}w(d,200,{accepted:!0});return}if(v.startsWith("/api/provider/login")){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(v==="/api/provider/login"){if(!("providerId"in a)||typeof a.providerId!="string"||!("method"in a)||a.method!=="api_key"&&a.method!=="oauth"||!r.loginProvider||!r.providers){w(d,400,{error:"\u767B\u5F55\u65B9\u5F0F\u65E0\u6548"});return}if(!(await r.providers()).some(O=>O.id===a.providerId&&O.methods.includes(a.method))){w(d,400,{error:"\u63D0\u4F9B\u65B9\u4E0D\u652F\u6301\u6B64\u767B\u5F55\u65B9\u5F0F"});return}let S="initialSecret"in a?a.initialSecret:void 0;if(S!==void 0&&(a.method!=="api_key"||typeof S!="string"||!S.trim()||S.length>16384)){w(d,400,{error:"API Key \u65E0\u6548"});return}let I=y.start(a.providerId,a.method,r.loginProvider,S,x);w(d,202,{id:I.id});return}if(!("id"in a)||typeof a.id!="string"){w(d,400,{error:"\u767B\u5F55\u6D41\u7A0B\u65E0\u6548"});return}if(v==="/api/provider/login/cancel"){w(d,y.cancel(a.id)?202:404,{accepted:!0});return}if(!("value"in a)||typeof a.value!="string"||a.value.length>16384||!y.respond(a.id,a.value)){w(d,400,{error:"\u767B\u5F55\u8F93\u5165\u65E0\u6548"});return}w(d,202,{accepted:!0});return}if(v==="/api/attachment/remove"){if(!("id"in a)||typeof a.id!="string"||a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u9644\u4EF6\u65E0\u6548"});return}f.get(a.id)?.sessionId===a.sessionId&&f.delete(a.id),w(d,202,{accepted:!0});return}if(v==="/api/directory/pick"){if(l!=="native"){w(d,409,{error:"\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\u4E0D\u53EF\u7528"});return}let b=new AbortController;d.once("close",()=>b.abort()),w(d,200,{path:await ze(b.signal)});return}if(v==="/api/directory/list"){if("path"in a&&(typeof a.path!="string"||a.path.length>4096)){w(d,400,{error:"\u76EE\u5F55\u8DEF\u5F84\u65E0\u6548"});return}w(d,200,await Ue("path"in a?a.path:void 0));return}if(v==="/api/directory/create"){if(!("path"in a)||typeof a.path!="string"||a.path.length>4096||!("name"in a)||typeof a.name!="string"||a.name.length>255){w(d,400,{error:"\u6587\u4EF6\u5939\u540D\u79F0\u6216\u8DEF\u5F84\u65E0\u6548"});return}w(d,200,{path:await Fe(a.path,a.name)});return}if(v==="/api/workspace/add"){if(!("path"in a)||typeof a.path!="string"||a.path.length>4096||!("create"in a)||typeof a.create!="boolean"){w(d,400,{error:"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u65E0\u6548"});return}await r.addWorkspace(a.path,a.create),w(d,202,{accepted:!0});return}if(v==="/api/workspace/select"||v==="/api/workspace/remove"||v==="/api/workspace/new-session"){if(!("id"in a)||typeof a.id!="string"){w(d,400,{error:"\u5DE5\u4F5C\u533A\u65E0\u6548"});return}v==="/api/workspace/select"?await r.selectWorkspace(a.id):v==="/api/workspace/new-session"?await r.newSessionInWorkspace(a.id):await r.removeWorkspace(a.id),w(d,202,{accepted:!0});return}if(v==="/api/session/select"){if(!("workspaceId"in a)||typeof a.workspaceId!="string"||!("id"in a)||typeof a.id!="string"||!("path"in a)||typeof a.path!="string"){w(d,400,{error:"\u4F1A\u8BDD\u65E0\u6548"});return}await r.selectSession(a.workspaceId,a.id,a.path),w(d,202,{accepted:!0});return}if(v==="/api/thinking-level"){if(!("level"in a)||typeof a.level!="string"){w(d,400,{error:"\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548"});return}await r.setThinkingLevel(a.sessionId,a.level)}else if(v==="/api/model"){if(!("provider"in a)||typeof a.provider!="string"||!("id"in a)||typeof a.id!="string"){w(d,400,{error:"\u6A21\u578B\u65E0\u6548"});return}await r.setModel(a.sessionId,a.provider,a.id)}else if(v==="/api/config"){let b=a;if(!["packages","extensions","skills"].includes(b.kind)||!["global","project"].includes(b.scope)||!["add","remove"].includes(b.action)||typeof b.value!="string"||!b.value.trim()||b.value.length>2048){w(d,400,{error:"\u914D\u7F6E\u9879\u65E0\u6548"});return}if(b.action==="add"&&b.kind!=="packages"&&st(b.value)){w(d,400,{error:"npm \u6216 Git \u6765\u6E90\u8BF7\u5728\u300C\u5305\u300D\u4E2D\u6DFB\u52A0\uFF1B\u6269\u5C55\u548C\u6280\u80FD\u53EA\u63A5\u53D7\u6587\u4EF6\u6216\u76EE\u5F55\u8DEF\u5F84"});return}w(d,200,await r.updateConfig(b));return}else if(v==="/api/message"){let b="attachments"in a?a.attachments:[];if(!Array.isArray(b)||b.length>Je||b.some(N=>typeof N!="string")||new Set(b).size!==b.length){w(d,400,{error:"\u9644\u4EF6\u65E0\u6548\u6216\u8FC7\u591A"});return}let S=b.map(N=>f.get(N));if(S.some(N=>!N||N.sessionId!==a.sessionId)){w(d,400,{error:"\u9644\u4EF6\u4E0D\u53EF\u7528"});return}if(!("text"in a)||typeof a.text!="string"||!a.text.trim()&&b.length===0||a.text.length>32e3){w(d,400,{error:"\u6D88\u606F\u65E0\u6548\u6216\u8FC7\u957F"});return}let I=S,O=[a.text.trim(),...I.map(N=>`\u9644\u4EF6 ${JSON.stringify(N.name)}\uFF1A${N.path}`)].filter(Boolean).join(`
12
+ `)}`)),t}function Gr(r){return{...r.filename?{filename:Pe(r.filename)}:{},...r.abs_path?{abs_path:Pe(r.abs_path)}:{},...r.function?{function:B(r.function)}:{},lineno:r.lineno,colno:r.colno,in_app:r.in_app}}function Jr(r){return{event_id:r.event_id,timestamp:r.timestamp,platform:r.platform,level:r.level,release:r.release,dist:r.dist,environment:B(r.environment??"production"),...r.message?{message:B(r.message)}:{},exception:r.exception?{values:r.exception.values?.slice(0,4).map(e=>({type:B(e.type??"Error"),value:B(e.value??""),...e.stacktrace?{stacktrace:{frames:e.stacktrace.frames?.slice(-30).map(Gr)}}:{},...e.mechanism?{mechanism:{type:e.mechanism.type,handled:e.mechanism.handled}}:{}}))}:void 0,tags:{side:r.tags?.side,buildId:r.tags?.buildId},contexts:{diagnostic:V(r.contexts?.diagnostic??{})},breadcrumbs:r.breadcrumbs?.slice(-100).map(e=>({timestamp:e.timestamp,category:B(e.category??"app"),data:V(e.data??{})})),debug_meta:r.debug_meta?{images:r.debug_meta.images?.slice(0,10).map(e=>({type:e.type,debug_id:e.debug_id,...e.code_file?{code_file:Pe(e.code_file)}:{}}))}:void 0}}function lt(r,e){return e.attachments=[],Jr(r)}var K=class{items=[];bytes=0;encoder=new TextEncoder;add(e,t={}){let i={timestamp:Date.now()/1e3,category:B(e),data:V(t)},s=this.encoder.encode(JSON.stringify(i)).byteLength+1;for(this.items.push({item:i,size:s}),this.bytes+=s;this.items.length>100||this.bytes>64*1024-2;)this.bytes-=this.items.shift().size}snapshot(){return this.items.map(({item:e})=>e)}},Ee=class{windowAt=-1;total=0;seen=new Map;take(e,t=Date.now()){(this.windowAt<0||t-this.windowAt>=6e4)&&(this.windowAt=t,this.total=0);let i=this.seen.get(e);if(i&&t-i.at<6e4){i.repeats++;return}if(!(this.total>=20))return this.total++,this.seen.size>=64&&!i&&this.seen.delete(this.seen.keys().next().value),this.seen.set(e,{at:t,repeats:0}),{repeats:i?.repeats??0}}},qr=new Set(["\u4F1A\u8BDD\u5DF2\u5207\u6362","Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F","\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F","\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A","\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u4F1A\u8BDD","\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A","\u65B0\u4F1A\u8BDD\u5DF2\u53D6\u6D88","\u5DF2\u6709\u767B\u5F55\u6B63\u5728\u8FDB\u884C","\u6A21\u578B\u4E0D\u53EF\u7528","\u6A21\u578B\u63D0\u4F9B\u65B9\u672A\u914D\u7F6E\u8BA4\u8BC1","\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6","\u5176\u4ED6\u63D0\u4F9B\u65B9\u7684\u767B\u5F55\u6B63\u5728\u8FDB\u884C\uFF0C\u8BF7\u5148\u5B8C\u6210\u6216\u53D6\u6D88\u5F53\u524D\u767B\u5F55","\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1","\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u4EA4\u4E92\u6216\u5BA1\u6279","\u8BF7\u5148\u9009\u62E9\u6A21\u578B","\u8BF7\u5148\u8FDE\u63A5\u5F53\u524D\u6A21\u578B","\u63D2\u4EF6\u672A\u542F\u7528","\u4F1A\u8BDD\u8FD0\u884C\u5B9E\u4F8B\u5DF2\u5207\u6362","\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728","\u6587\u4EF6\u8D85\u8FC7 20 MB","\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927","\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A","\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548"]);function U(r){return r instanceof Error&&(r.name==="AbortError"||qr.has(r.message))}var se=class{budget=new Ee;breadcrumbs;scopeClass;seen=new WeakSet;state={};client;side;buildId;constructor(e,t,i,s,o=new K){this.client=e,this.side=t,this.buildId=i,this.scopeClass=s.Scope,this.breadcrumbs=o,e.addIntegration(s.linkedErrorsIntegration({limit:4}))}setState(e){this.state=V(e)}capture(e,t={},i){try{if(U(e))return;if(typeof e=="object"&&e!==null){if(this.seen.has(e))return;this.seen.add(e)}let s=oe(e),o=`${s.name}:${s.message}:${s.stack?.split(`
13
+ `)[1]??""}:${t.stage??""}`,l=this.budget.take(o);if(!l)return;let u=new this.scopeClass;u.setClient(this.client),u.setTags({side:this.side,buildId:this.buildId}),u.setContext("diagnostic",V({...this.state,...t,repeats:l.repeats}));for(let f of this.breadcrumbs.snapshot())u.addBreadcrumb(f,100);return u.captureException(s,i?{event_id:i}:void 0)}catch{return}}ignore(e){this.seen.add(e)}};function dt(r,e){return r({...e,bufferSize:20},async({body:t})=>{let i=await fetch(e.url,{method:"POST",body:t,signal:AbortSignal.timeout(3e3),credentials:"omit",referrerPolicy:"no-referrer",redirect:"error",headers:{"Content-Type":"application/x-sentry-envelope"}});return{statusCode:i.status,headers:{"x-sentry-rate-limits":i.headers.get("x-sentry-rate-limits"),"retry-after":i.headers.get("retry-after")}}})}var Xr="https://070c0b7c5ac18d940c294e63ecfa0793@o4506663318716416.ingest.us.sentry.io/4512191040716800";function Zr(r=process.env,e=console.warn){let t=i=>{let s={enabled:!1,environment:r.PI_WEB_SENTRY_ENVIRONMENT||"production",release:ot,buildId:$},o=r[`PI_WEB_SENTRY_${i}_DSN`]??r.PI_WEB_SENTRY_DSN??Xr;if(r.PI_WEB_SENTRY_ENABLED==="false"||!o)return s;try{let l=new URL(o);if(l.protocol!=="https:"||!/^[\w-]+$/.test(l.username)||l.password||l.search||l.hash||!/\/(?:[\w-]+\/)*\d+$/.test(l.pathname))throw new Error;return{...s,enabled:!0,dsn:o}}catch{return e(`pi-webapp: invalid ${i.toLowerCase()} Sentry DSN; error reporting disabled for this side.`),s}};return{browser:t("BROWSER"),node:t("NODE")}}var F=class{config;ready;reporter;client;salt=pt(16);breadcrumbs=new K;seen=new WeakSet;early=[];state={nodeVersion:process.version,platform:process.platform};fatal;closed=!1;failed=!1;get enabled(){return this.config.node.enabled&&!this.closed&&!this.failed}constructor(e={}){if(this.config=Zr(e.env),!this.config.node.enabled){this.ready=Promise.resolve();return}if(e.monitor!==!1){let t=Kr(import.meta.url).replace(/\\/g,"/"),i=t.slice(0,t.lastIndexOf("/")+1);this.fatal=s=>{s.stack?.replace(/\\/g,"/").includes(t.endsWith("extension.js")?t:i)&&this.capture(s,{stage:"fatal"})},process.on("uncaughtExceptionMonitor",this.fatal)}this.ready=import("@sentry/node").then(t=>{if(!this.closed){this.client=new t.NodeClient({...this.config.node,dist:$,integrations:[],transport:e.transport??(i=>dt(t.createTransport,i)),stackParser:t.defaultStackParser,beforeSend:lt,sendClientReports:!1,dataCollection:{...at,httpBodies:[]},includeServerName:!1,enableRuntimeChannelInjection:!1,beforeSendLog:()=>null,beforeSendMetric:()=>null,enableOpenTelemetrySetup:!1,maxBreadcrumbs:100}),this.reporter=new se(this.client,"node",$,t,this.breadcrumbs),this.reporter.setState(this.state);for(let i of this.early)this.reporter.capture(i.error,i.context,i.eventId)}}).catch(()=>{this.failed=!0,console.warn("pi-webapp: Sentry initialization failed; error reporting disabled.")}).finally(()=>{this.early=[]})}capture(e,t={}){try{if(!this.enabled||U(e))return;if(typeof e=="object"&&e!==null){if(this.seen.has(e))return;this.seen.add(e)}if(this.reporter)return this.reporter.capture(e,t);if(this.early.length>=20)return;let i=pt(16).toString("hex");return this.early.push({error:oe(e),context:V(t),eventId:i}),i}catch{return}}setState(e){this.state=V({...this.state,...e}),this.reporter?.setState(this.state)}breadcrumb(e,t={}){this.enabled&&this.breadcrumbs.add(e,t)}session(e){return Yr("sha256").update(this.salt).update(e).digest("hex").slice(0,16)}async close(){let e=performance.now(),t;try{await Promise.race([this.ready,new Promise(i=>{t=setTimeout(i,500)})])}finally{clearTimeout(t),this.closed=!0,this.fatal&&process.off("uncaughtExceptionMonitor",this.fatal)}try{await this.client?.close(Math.max(1,500-(performance.now()-e)))}catch{}}};import{VERSION as oi}from"@earendil-works/pi-coding-agent";import{readFile as Qr}from"node:fs/promises";import{join as ei}from"node:path";async function ut(r){try{let e=JSON.parse(await Qr(ei(r,".vite/manifest.json"),"utf8"));if(!e||typeof e!="object")return{};let t=new Set;for(let s of Object.values(e))if(!(!s||typeof s!="object"))for(let o of[s.file,...Array.isArray(s.css)?s.css:[],...Array.isArray(s.assets)?s.assets:[]])typeof o=="string"&&/^assets\/[\w.-]+\.(?:js|css|woff2?|ttf|png|jpe?g|svg|webp)$/.test(o)&&t.add(o);let i={js:"text/javascript; charset=utf-8",css:"text/css; charset=utf-8",svg:"image/svg+xml",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf"};return Object.fromEntries([...t].map(s=>[`/${s}`,{path:s,type:i[s.split(".").pop()]}]))}catch{return{}}}var ai={"/":{path:"index.html",type:"text/html; charset=utf-8"},"/assets/app.js":{path:"assets/app.js",type:"text/javascript; charset=utf-8"},"/assets/style.css":{path:"assets/style.css",type:"text/css; charset=utf-8"}};function w(r,e,t){typeof t=="object"&&t!==null&&"error"in t&&(t={errorCode:e>=500?"server_error":"validation_error",...t,requestId:r.getHeader("X-Request-ID"),operationId:r.getHeader("X-Operation-ID")}),r.writeHead(e,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),r.end(JSON.stringify(t))}function ci(r,e){let t=r.headers.authorization;if(typeof t!="string"||!t.startsWith("Bearer "))return!1;let i=Buffer.from(t.slice(7),"utf8");return i.length===e.length&&ri(i,e)}async function li(r){let e=0,t=[];for await(let i of r){let s=Buffer.isBuffer(i)?i:Buffer.from(i);if(e+=s.length,e>64*1024)throw new Error("\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927");t.push(s)}return JSON.parse(Buffer.concat(t).toString("utf8"))}async function di(r){let e=0,t=[];for await(let i of r){let s=Buffer.isBuffer(i)?i:Buffer.from(i);if(e+=s.length,e>ie)throw new Error("\u6587\u4EF6\u8D85\u8FC7 20 MB");t.push(s)}return Buffer.concat(t)}async function pi(r,e=0){await new Promise((i,s)=>{r.once("error",s),r.listen(e,"127.0.0.1",()=>{r.off("error",s),i()})});let t=r.address();if(t===null||typeof t=="string")throw new Error("\u65E0\u6CD5\u786E\u5B9A\u76D1\u542C\u7AEF\u53E3");return t.port}async function mt(r,e,t=new F){t.setState({piVersion:oi});let i=process.env.PI_WEBAPP_RESTART_TOKEN,s=i&&/^[A-Za-z0-9_-]{32}$/.test(i)?i:ti(24).toString("base64url"),o=Buffer.from(s),l=ze(),u=new Set,f=new Map,y=new ne((h,d)=>t.capture(h,d)),c=h=>t.setState({nodeVersion:process.version,platform:process.platform,session:t.session(h.sessionId),idle:h.idle,model:h.model,thinkingLevel:h.thinkingLevel,messageCount:h.messages.length}),p="",g=!1,m={...ai,...await ut(e)};for(let h of await ni(gt(e,"assets")).catch(()=>[])){let d=/^[\w.-]+\.(js|css|woff2?|ttf)$/.exec(h);if(!d)continue;let C={js:"text/javascript; charset=utf-8",css:"text/css; charset=utf-8",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf"};m[`/assets/${h}`]={path:`assets/${h}`,type:C[d[1]]}}let k=si(async(h,d)=>{let C=R=>typeof R=="string"&&/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(R),E=C(h.headers["x-request-id"])?h.headers["x-request-id"]:ft(),x={requestId:E,operationId:C(h.headers["x-operation-id"])?h.headers["x-operation-id"]:void 0};d.setHeader("X-Request-ID",E),x.operationId&&d.setHeader("X-Operation-ID",x.operationId);let v="/",Kt=performance.now(),W=(R,a,b)=>{let S=!U(R)&&ct(v)?ae(R,"Agent or provider operation failed"):R,O=t.capture(S,{...x,route:v,method:h.method,status:a,stage:"http"});w(d,a,{error:b,errorId:O,errorReported:t.enabled,errorCode:U(R)?"validation_error":"unexpected_error"})};d.once("finish",()=>{v.startsWith("/api/telemetry/")||t.breadcrumb("request",{...x,route:v,method:h.method,status:d.statusCode,durationMs:Math.round(performance.now()-Kt)})});try{d.setHeader("X-Content-Type-Options","nosniff"),d.setHeader("Referrer-Policy","no-referrer"),d.setHeader("Content-Security-Policy",`default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'self'${t.config.browser.dsn?` ${new URL(t.config.browser.dsn).origin}`:""}; img-src 'self' data: blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'`);try{v=new URL(h.url??"/",p).pathname}catch{w(d,400,{error:"\u8BF7\u6C42\u5730\u5740\u65E0\u6548"});return}let R=m[v];if(h.method==="GET"&&R){try{let a=await ii(gt(e,R.path));d.writeHead(200,{"Content-Type":R.type,"Cache-Control":"no-store"}),d.end(a)}catch(a){W(a,500,"\u9875\u9762\u6587\u4EF6\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v.startsWith("/plugins/")){try{let a=await r.pluginAsset?.(h.url??v);if(!a){w(d,404,{error:"\u63D2\u4EF6\u8D44\u6E90\u4E0D\u5B58\u5728"});return}d.writeHead(200,{"Content-Type":a.type,"Cache-Control":"no-store"}),d.end(a.bytes)}catch(a){W(a,404,"\u63D2\u4EF6\u8D44\u6E90\u4E0D\u53EF\u7528")}return}if(!v.startsWith("/api/")){w(d,404,{error:"\u672A\u627E\u5230"});return}if(!ci(h,o)){w(d,401,{error:"\u8BBF\u95EE\u4EE4\u724C\u65E0\u6548"});return}if(h.method==="GET"&&v==="/api/telemetry/config"){w(d,200,t.config.browser);return}if(h.method==="GET"&&v==="/api/update/version"){try{w(d,200,{current:await r.selfUpdate?.runningVersion()??null})}catch(a){W(a,503,a instanceof Error?a.message:"\u65E0\u6CD5\u8BFB\u53D6\u7248\u672C")}return}if(h.method==="GET"&&v==="/api/update"){try{w(d,200,await r.selfUpdate?.check()??{canRestart:!1,reason:"\u5F53\u524D\u6269\u5C55\u4E0D\u652F\u6301\u5728\u7EBF\u5347\u7EA7"})}catch(a){W(a,503,a instanceof Error?a.message:"\u68C0\u67E5\u66F4\u65B0\u5931\u8D25")}return}if(h.method==="GET"&&v==="/api/image"){let a=new URL(h.url??v,p),b=a.searchParams.get("sessionId")??"",I=a.searchParams.get("messageId")??"",S=Number(a.searchParams.get("index"));if(!b||b!==r.snapshot().sessionId||!I||!Number.isInteger(S)||S<0||S>100){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u56FE\u7247\u5730\u5740\u65E0\u6548"});return}let O=r.image?.(b,I,S);if(!O||!["image/png","image/jpeg","image/webp","image/gif"].includes(O.mimeType)){w(d,404,{error:"\u56FE\u7247\u4E0D\u53EF\u7528"});return}d.writeHead(200,{"Content-Type":O.mimeType,"Cache-Control":"private, no-store"}),d.end(O.data);return}if(h.method==="POST"&&v==="/api/attachment"){if(h.headers.origin!==void 0&&h.headers.origin!==p){w(d,403,{error:"\u6765\u6E90\u4E0D\u5339\u914D"});return}let a=new URL(h.url??v,p),b=a.searchParams.get("sessionId"),I=a.searchParams.get("name");try{if(!b||!I||I.length>1024||b!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u6587\u4EF6\u540D\u65E0\u6548"});return}if(Number(h.headers["content-length"]??0)>ie){w(d,413,{error:"\u6587\u4EF6\u8D85\u8FC7 20 MB"});return}let S=await Ye(b,I,h.headers["content-type"]??"application/octet-stream",await di(h));if(b!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}f.set(S.id,S),w(d,201,{id:S.id,name:S.name,bytes:S.bytes})}catch(S){W(S,400,S instanceof Error?S.message:"\u4E0A\u4F20\u5931\u8D25")}return}if(h.method==="GET"&&v==="/api/session"){try{let a=r.snapshot();c(a),w(d,200,a)}catch(a){W(a,503,"\u5F53\u524D\u4F1A\u8BDD\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/plugins"){try{w(d,200,await r.plugins?.()??{plugins:[],errors:[]})}catch(a){W(a,503,"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/providers"){try{w(d,200,await r.providers?.()??[])}catch(a){W(a,503,"\u6A21\u578B\u63D0\u4F9B\u65B9\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/provider/models"){let a=new URL(h.url??v,p).searchParams.get("providerId")??"";try{if(!a||!r.providerModels){w(d,400,{error:"\u63D0\u4F9B\u65B9\u65E0\u6548"});return}w(d,200,await r.providerModels(a))}catch(b){W(b,400,b instanceof Error?b.message:"\u6A21\u578B\u76EE\u5F55\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/provider/login/active"){w(d,200,{active:y.getActive()??null});return}if(h.method==="GET"&&v==="/api/provider/login"){let a=new URL(h.url??v,p).searchParams.get("id")??"",b=y.get(a);w(d,b?200:404,b??{error:"\u767B\u5F55\u6D41\u7A0B\u4E0D\u5B58\u5728"});return}if(h.method==="GET"&&(v==="/api/models"||v==="/api/config"||v==="/api/workspaces"||v==="/api/commands")){try{w(d,200,v==="/api/models"?await r.models():v==="/api/config"?await r.config():v==="/api/commands"?r.commands?.()??[]:await r.workspaces())}catch(a){W(a,503,"Pi \u914D\u7F6E\u4E0D\u53EF\u7528")}return}if(h.method==="GET"&&v==="/api/directory/capability"){w(d,200,{kind:l});return}if(h.method==="GET"&&v==="/api/events"){let a;try{a=r.snapshot(),c(a)}catch(b){W(b,503,"\u5F53\u524D\u4F1A\u8BDD\u4E0D\u53EF\u7528");return}d.writeHead(200,{"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"no-store",Connection:"keep-alive","X-Accel-Buffering":"no"}),u.add(d),d.write(`${JSON.stringify({type:"snapshot",session:a})}
14
+ `),d.on("close",()=>u.delete(d));return}if(h.method==="POST"&&["/api/plugin-interaction","/api/plugin-action","/api/update","/api/message","/api/attachment/remove","/api/abort","/api/resume","/api/compact","/api/new-session","/api/model","/api/thinking-level","/api/config","/api/provider/login","/api/provider/login/respond","/api/provider/login/cancel","/api/provider/custom","/api/provider/models","/api/provider/logout","/api/workspace/add","/api/workspace/select","/api/workspace/new-session","/api/workspace/remove","/api/session/select","/api/directory/list","/api/directory/create","/api/directory/pick"].includes(v)){if(h.headers.origin!==void 0&&h.headers.origin!==p){w(d,403,{error:"\u6765\u6E90\u4E0D\u5339\u914D"});return}if(!h.headers["content-type"]?.startsWith("application/json")){w(d,415,{error:"\u9700\u8981 JSON \u8BF7\u6C42"});return}try{let a;try{a=await li(h)}catch(b){if(b instanceof SyntaxError||U(b)){w(d,400,{error:"\u8BF7\u6C42\u5185\u5BB9\u65E0\u6548"});return}throw b}if(typeof a!="object"||a===null||!("sessionId"in a)||typeof a.sessionId!="string"){w(d,400,{error:"\u7F3A\u5C11\u4F1A\u8BDD\u6807\u8BC6"});return}if(v==="/api/plugin-interaction"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("pluginId"in a)||typeof a.pluginId!="string"||a.pluginId.length>200||!("requestId"in a)||typeof a.requestId!="string"||a.requestId.length>200||!r.resolvePluginInteraction||!("value"in a)){w(d,400,{error:"\u63D2\u4EF6\u4EA4\u4E92\u54CD\u5E94\u65E0\u6548"});return}await r.resolvePluginInteraction(a.sessionId,a.pluginId,a.requestId,a.value),w(d,200,{accepted:!0});return}if(v==="/api/plugin-action"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("pluginId"in a)||typeof a.pluginId!="string"||a.pluginId.length>200||!("action"in a)||typeof a.action!="string"||a.action.length>100||!r.invokePluginAction){w(d,400,{error:"\u63D2\u4EF6\u52A8\u4F5C\u65E0\u6548"});return}let b=await r.invokePluginAction(a.sessionId,a.pluginId,a.action,"input"in a?a.input:void 0);w(d,200,{value:b});return}if(v==="/api/update"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!r.snapshot().idle){w(d,409,{error:"\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u540E\u518D\u5347\u7EA7"});return}if(!r.selfUpdate){w(d,409,{error:"\u5F53\u524D\u6269\u5C55\u4E0D\u652F\u6301\u5728\u7EBF\u5347\u7EA7"});return}let b=await r.selfUpdate.prepare();g=!0,w(d,202,{accepted:!0,version:b.version}),setTimeout(()=>{r.selfUpdate?.requestRestart(b).catch(I=>{g=!1,t.capture(I,{stage:"restart"}),console.error("pi-webapp restart:",I)})},500).unref();return}if(v==="/api/provider/custom"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("provider"in a)||!ke(a.provider)||!r.addCustomProvider){w(d,400,{error:"\u81EA\u5B9A\u4E49\u63D0\u4F9B\u65B9\u65E0\u6548"});return}await r.addCustomProvider(a.sessionId,a.provider),w(d,201,{accepted:!0});return}if(v==="/api/provider/models"||v==="/api/provider/logout"){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("providerId"in a)||typeof a.providerId!="string"){w(d,400,{error:"\u63D0\u4F9B\u65B9\u65E0\u6548"});return}if(v==="/api/provider/models"){if(!("change"in a)||!et(a.change)||!r.updateProviderModel){w(d,400,{error:"\u6A21\u578B\u53C2\u6570\u65E0\u6548"});return}await r.updateProviderModel(a.sessionId,a.providerId,a.change)}else{if(!r.logoutProvider){w(d,400,{error:"\u65E0\u6CD5\u79FB\u9664\u8BA4\u8BC1"});return}await r.logoutProvider(a.sessionId,a.providerId)}w(d,200,{accepted:!0});return}if(v.startsWith("/api/provider/login")){if(a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(v==="/api/provider/login"){if(!("providerId"in a)||typeof a.providerId!="string"||!("method"in a)||a.method!=="api_key"&&a.method!=="oauth"||!r.loginProvider||!r.providers){w(d,400,{error:"\u767B\u5F55\u65B9\u5F0F\u65E0\u6548"});return}if(!(await r.providers()).some(O=>O.id===a.providerId&&O.methods.includes(a.method))){w(d,400,{error:"\u63D0\u4F9B\u65B9\u4E0D\u652F\u6301\u6B64\u767B\u5F55\u65B9\u5F0F"});return}let I="initialSecret"in a?a.initialSecret:void 0;if(I!==void 0&&(a.method!=="api_key"||typeof I!="string"||!I.trim()||I.length>16384)){w(d,400,{error:"API Key \u65E0\u6548"});return}let S=y.start(a.providerId,a.method,r.loginProvider,I,x);w(d,202,{id:S.id});return}if(!("id"in a)||typeof a.id!="string"){w(d,400,{error:"\u767B\u5F55\u6D41\u7A0B\u65E0\u6548"});return}if(v==="/api/provider/login/cancel"){w(d,y.cancel(a.id)?202:404,{accepted:!0});return}if(!("value"in a)||typeof a.value!="string"||a.value.length>16384||!y.respond(a.id,a.value)){w(d,400,{error:"\u767B\u5F55\u8F93\u5165\u65E0\u6548"});return}w(d,202,{accepted:!0});return}if(v==="/api/attachment/remove"){if(!("id"in a)||typeof a.id!="string"||a.sessionId!==r.snapshot().sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u9644\u4EF6\u65E0\u6548"});return}f.get(a.id)?.sessionId===a.sessionId&&f.delete(a.id),w(d,202,{accepted:!0});return}if(v==="/api/directory/pick"){if(l!=="native"){w(d,409,{error:"\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\u4E0D\u53EF\u7528"});return}let b=new AbortController;d.once("close",()=>b.abort()),w(d,200,{path:await Ge(b.signal)});return}if(v==="/api/directory/list"){if("path"in a&&(typeof a.path!="string"||a.path.length>4096)){w(d,400,{error:"\u76EE\u5F55\u8DEF\u5F84\u65E0\u6548"});return}w(d,200,await Fe("path"in a?a.path:void 0));return}if(v==="/api/directory/create"){if(!("path"in a)||typeof a.path!="string"||a.path.length>4096||!("name"in a)||typeof a.name!="string"||a.name.length>255){w(d,400,{error:"\u6587\u4EF6\u5939\u540D\u79F0\u6216\u8DEF\u5F84\u65E0\u6548"});return}w(d,200,{path:await He(a.path,a.name)});return}if(v==="/api/workspace/add"){if(!("path"in a)||typeof a.path!="string"||a.path.length>4096||!("create"in a)||typeof a.create!="boolean"){w(d,400,{error:"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u65E0\u6548"});return}await r.addWorkspace(a.path,a.create),w(d,202,{accepted:!0});return}if(v==="/api/workspace/select"||v==="/api/workspace/remove"||v==="/api/workspace/new-session"){if(!("id"in a)||typeof a.id!="string"){w(d,400,{error:"\u5DE5\u4F5C\u533A\u65E0\u6548"});return}v==="/api/workspace/select"?await r.selectWorkspace(a.id):v==="/api/workspace/new-session"?await r.newSessionInWorkspace(a.id):await r.removeWorkspace(a.id),w(d,202,{accepted:!0});return}if(v==="/api/session/select"){if(!("workspaceId"in a)||typeof a.workspaceId!="string"||!("id"in a)||typeof a.id!="string"||!("path"in a)||typeof a.path!="string"){w(d,400,{error:"\u4F1A\u8BDD\u65E0\u6548"});return}await r.selectSession(a.workspaceId,a.id,a.path),w(d,202,{accepted:!0});return}if(v==="/api/thinking-level"){if(!("level"in a)||typeof a.level!="string"){w(d,400,{error:"\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548"});return}await r.setThinkingLevel(a.sessionId,a.level)}else if(v==="/api/model"){if(!("provider"in a)||typeof a.provider!="string"||!("id"in a)||typeof a.id!="string"){w(d,400,{error:"\u6A21\u578B\u65E0\u6548"});return}await r.setModel(a.sessionId,a.provider,a.id)}else if(v==="/api/config"){let b=a;if(!["packages","extensions","skills"].includes(b.kind)||!["global","project"].includes(b.scope)||!["add","remove"].includes(b.action)||typeof b.value!="string"||!b.value.trim()||b.value.length>2048){w(d,400,{error:"\u914D\u7F6E\u9879\u65E0\u6548"});return}if(b.action==="add"&&b.kind!=="packages"&&st(b.value)){w(d,400,{error:"npm \u6216 Git \u6765\u6E90\u8BF7\u5728\u300C\u5305\u300D\u4E2D\u6DFB\u52A0\uFF1B\u6269\u5C55\u548C\u6280\u80FD\u53EA\u63A5\u53D7\u6587\u4EF6\u6216\u76EE\u5F55\u8DEF\u5F84"});return}w(d,200,await r.updateConfig(b));return}else if(v==="/api/message"){let b="attachments"in a?a.attachments:[];if(!Array.isArray(b)||b.length>qe||b.some(N=>typeof N!="string")||new Set(b).size!==b.length){w(d,400,{error:"\u9644\u4EF6\u65E0\u6548\u6216\u8FC7\u591A"});return}let I=b.map(N=>f.get(N));if(I.some(N=>!N||N.sessionId!==a.sessionId)){w(d,400,{error:"\u9644\u4EF6\u4E0D\u53EF\u7528"});return}if(!("text"in a)||typeof a.text!="string"||!a.text.trim()&&b.length===0||a.text.length>32e3){w(d,400,{error:"\u6D88\u606F\u65E0\u6548\u6216\u8FC7\u957F"});return}let S=I,O=[a.text.trim(),...S.map(N=>`\u9644\u4EF6 ${JSON.stringify(N.name)}\uFF1A${N.path}`)].filter(Boolean).join(`
15
15
 
16
- `),Gt=await Promise.all(I.filter(N=>["image/png","image/jpeg","image/webp","image/gif"].includes(N.mediaType)).map(Ye));x.operationId??=ut(),d.setHeader("X-Operation-ID",x.operationId),t.breadcrumb("send",{...x,attachmentCount:I.length}),await r.send(a.sessionId,O,Gt,x);for(let N of b)f.delete(N)}else if(v==="/api/compact"){if(!r.compact)throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u652F\u6301\u538B\u7F29");await r.compact(a.sessionId)}else if(v==="/api/resume"){let b=r.snapshot();if(a.sessionId!==b.sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!b.idle){w(d,409,{error:"Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F"});return}if(!b.paused){w(d,409,{error:"\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1"});return}if(b.interactions?.length){w(d,409,{error:"\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u4EA4\u4E92\u6216\u5BA1\u6279"});return}if(!r.resume)throw new Error("\u5F53\u524D\u670D\u52A1\u4E0D\u652F\u6301\u7EE7\u7EED\uFF0C\u8BF7\u91CD\u8F7D Pi");await r.resume(a.sessionId)}else v==="/api/abort"?await r.abort(a.sessionId):await r.newSession(a.sessionId);w(d,202,{accepted:!0})}catch(a){let b=a instanceof Error?a.message:"\u8BF7\u6C42\u5931\u8D25";W(a,b==="\u4F1A\u8BDD\u5DF2\u5207\u6362"?409:400,b)}return}w(d,404,{error:"\u672A\u627E\u5230"})}catch(R){d.headersSent?(t.capture(R,{...x,route:v,stage:"http_stream"}),d.end()):W(R,500,"\u8BF7\u6C42\u5931\u8D25")}}),P=Number(process.env.PI_WEBAPP_RESTART_PORT),M;try{M=await oi(k,Number.isInteger(P)&&P>0&&P<65536&&i===n?P:0)}catch(h){throw t.capture(h,{stage:"listen"}),await t.close(),h}return p=`http://127.0.0.1:${M}`,{protocolVersion:7,buildId:$,reportError(h,d){return t.capture(h,d)},breadcrumb(h,d){t.breadcrumb(h,d)},url:`${p}/#${n}`,publish(h){if(h.type==="snapshot"&&c(h.session),h.type==="error"&&!h.errorCode&&(h={...h,errorCode:"unexpected_error",errorId:t.capture(new Error("Agent execution failed"),{stage:"agent",requestId:h.requestId,operationId:h.operationId})}),h.type==="error"&&(h={...h,errorReported:h.errorReported??t.enabled}),h.type==="snapshot")for(let[C,E]of f)E.sessionId!==h.session.sessionId&&f.delete(C);let d=`${JSON.stringify(h)}
16
+ `),Xt=await Promise.all(S.filter(N=>["image/png","image/jpeg","image/webp","image/gif"].includes(N.mediaType)).map(Ke));x.operationId??=ft(),d.setHeader("X-Operation-ID",x.operationId),t.breadcrumb("send",{...x,attachmentCount:S.length}),await r.send(a.sessionId,O,Xt,x);for(let N of b)f.delete(N)}else if(v==="/api/compact"){if(!r.compact)throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u652F\u6301\u538B\u7F29");await r.compact(a.sessionId)}else if(v==="/api/resume"){let b=r.snapshot();if(a.sessionId!==b.sessionId){w(d,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!b.idle){w(d,409,{error:"Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F"});return}if(!b.paused){w(d,409,{error:"\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1"});return}if(b.interactions?.length){w(d,409,{error:"\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u4EA4\u4E92\u6216\u5BA1\u6279"});return}if(!r.resume)throw new Error("\u5F53\u524D\u670D\u52A1\u4E0D\u652F\u6301\u7EE7\u7EED\uFF0C\u8BF7\u91CD\u8F7D Pi");await r.resume(a.sessionId)}else v==="/api/abort"?await r.abort(a.sessionId):await r.newSession(a.sessionId);w(d,202,{accepted:!0})}catch(a){let b=a instanceof Error?a.message:"\u8BF7\u6C42\u5931\u8D25";W(a,b==="\u4F1A\u8BDD\u5DF2\u5207\u6362"?409:400,b)}return}w(d,404,{error:"\u672A\u627E\u5230"})}catch(R){d.headersSent?(t.capture(R,{...x,route:v,stage:"http_stream"}),d.end()):W(R,500,"\u8BF7\u6C42\u5931\u8D25")}}),P=Number(process.env.PI_WEBAPP_RESTART_PORT),M;try{M=await pi(k,Number.isInteger(P)&&P>0&&P<65536&&i===s?P:0)}catch(h){throw t.capture(h,{stage:"listen"}),await t.close(),h}return p=`http://127.0.0.1:${M}`,{protocolVersion:7,buildId:$,reportError(h,d){return t.capture(h,d)},breadcrumb(h,d){t.breadcrumb(h,d)},url:`${p}/#${s}`,publish(h){if(h.type==="snapshot"&&c(h.session),h.type==="error"&&!h.errorCode&&(h={...h,errorCode:"unexpected_error",errorId:t.capture(new Error("Agent execution failed"),{stage:"agent",requestId:h.requestId,operationId:h.operationId})}),h.type==="error"&&(h={...h,errorReported:h.errorReported??t.enabled}),h.type==="snapshot")for(let[C,E]of f)E.sessionId!==h.session.sessionId&&f.delete(C);let d=`${JSON.stringify(h)}
17
17
  `;for(let C of u)C.write(d)},async close(h){y.close();for(let C of u)C.end(`${JSON.stringify({type:"shutdown",reconnect:h?.reconnect??g})}
18
- `);u.clear();let d;try{await new Promise((C,E)=>{k.close(x=>x?E(x):C()),d=setTimeout(()=>k.closeAllConnections(),50).unref()})}finally{clearTimeout(d),await t.close()}}}}import{getSupportedThinkingLevels as ai}from"@earendil-works/pi-ai";function mt(r){let e=[],t=r;for(;;){let i=/(^|\n\n)附件 ("(?:\\.|[^"\\])*"):([^\n]+)$/u.exec(t);if(!i||!/[\\/]pi-web[\\/]attachments[\\/][a-f0-9]{64}[\\/]/u.test(i[3]))break;let n;try{n=JSON.parse(i[2])}catch{break}e.unshift({name:n,image:/\.(?:png|jpe?g|webp|gif)$/iu.test(n)}),t=t.slice(0,i.index)}return{text:t,attachments:e}}var X="pi-webapp/paused",Ie="pi-webapp/resume";function Z(r){for(let e=r.length-1;e>=0;e--){let t=r[e];if(t.type==="custom_message"&&t.customType===Ie)return!1;if(t.type==="custom"&&t.customType===X)return!0;if(t.type==="message"){if(t.message.role==="user")return!1;if(t.message.role==="assistant"){if(t.message.stopReason==="aborted")return!0;if(t.message.stopReason==="stop"||t.message.stopReason==="length"||t.message.stopReason==="error")return!1}}}return!1}function Se(r,e){let t=[],i;for(let n of r){if(n.type==="message"&&(i=n.id),n.type!=="custom")continue;let o=e.find(l=>n.customType.startsWith(`${l}/`));if(o){try{if(JSON.stringify(n.data).length>128*1024)continue}catch{continue}t.push({id:n.id,pluginId:o,kind:n.customType,data:n.data,timestamp:n.timestamp,...i?{afterMessageId:i}:{}})}}return t}function H(r){return typeof r=="string"?[{kind:"text",text:r}]:r.flatMap(e=>e.type==="text"?[{kind:"text",text:e.text}]:e.type==="thinking"?[{kind:"thinking",text:e.thinking}]:e.type==="image"?[{kind:"image",text:"\u56FE\u7247\u9644\u4EF6"}]:e.type==="toolCall"?[{kind:"toolCall",text:JSON.stringify(e.arguments??{}),toolName:e.name,toolCallId:e.id}]:[])}function xe(r){if(r.type==="custom_message")return r.display?{id:r.id,role:"notice",timestamp:r.timestamp,blocks:H(r.content)}:null;if(r.type!=="message")return null;let{message:e}=r;return e.role==="user"||e.role==="assistant"?{id:r.id,role:e.role,timestamp:r.timestamp,blocks:H(e.content),...e.role==="assistant"?{...e.stopReason==="error"&&e.errorMessage?{error:e.errorMessage}:{},usage:{input:e.usage.input,output:e.usage.output,cacheRead:e.usage.cacheRead,cacheWrite:e.usage.cacheWrite,...e.usage.reasoning===void 0?{}:{reasoning:e.usage.reasoning},totalTokens:e.usage.totalTokens,cost:e.usage.cost.total},model:`${e.provider}/${e.model}`}:{}}:e.role==="toolResult"?{id:r.id,role:"tool",timestamp:r.timestamp,blocks:H(e.content),isError:e.isError,toolCallId:e.toolCallId,toolName:e.toolName}:null}function Ce(r,e){let t=r?.trim();if(t)return t;let i=e.find(o=>o.role==="user"),n=mt(i?.blocks.find(o=>o.kind==="text")?.text??"").text.replace(/\s+/g," ").trim();return n?n.slice(0,50):"\u5F53\u524D\u4F1A\u8BDD"}function ht(r,e,t=[]){let i=r.sessionManager.getBranch().flatMap(n=>{let o=xe(n);return o?[o]:[]});return{schemaVersion:1,sessionId:r.sessionManager.getSessionId(),cwd:r.cwd,name:Ce(e,i),model:r.model?`${r.model.provider}/${r.model.id}`:null,thinkingLevel:r.thinkingLevel??null,thinkingLevels:r.model?ai(r.model):["off"],idle:r.isIdle(),paused:Z(r.sessionManager.getBranch()),contextUsage:r.getContextUsage()??null,messages:i,pluginEntries:Se(r.sessionManager.getBranch(),t)}}import{randomUUID as Ae}from"node:crypto";import{mkdir as wt,readFile as ci,realpath as yt,rename as li,rm as di,stat as vt,writeFile as pi}from"node:fs/promises";import{basename as bt,dirname as ui,isAbsolute as kt,join as fi}from"node:path";var ce=class{items=[];hiddenPaths=[];mutationChain=Promise.resolve();file;constructor(e){this.file=e}async load(){try{let e=JSON.parse(await ci(this.file,"utf8")),t,i=[];if(Array.isArray(e)?t=e:e&&typeof e=="object"&&"version"in e&&e.version===2&&"items"in e&&"hiddenPaths"in e&&(t=e.items,i=e.hiddenPaths),!Array.isArray(t)||!Array.isArray(i))throw new Error("\u5DE5\u4F5C\u533A\u8BB0\u5F55\u65E0\u6548");this.items=t.filter(n=>typeof n=="object"&&n!==null&&typeof n.id=="string"&&typeof n.path=="string"&&typeof n.title=="string"),this.hiddenPaths=i.filter(n=>typeof n=="string")}catch(e){if(e.code!=="ENOENT")throw e}}list(){return[...this.items]}get(e){return this.items.find(t=>t.id===e)}async add(e,t=!1){if(!kt(e)||e.includes("\0"))throw new Error("\u8BF7\u8F93\u5165\u5B8C\u6574\u7684\u76EE\u5F55\u8DEF\u5F84");t&&await wt(e,{recursive:!0});let i=await yt(e);if(!(await vt(i)).isDirectory())throw new Error("\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55");return this.mutate(async()=>{let n=this.hiddenPaths.filter(f=>f!==i),o=this.items.find(f=>f.path===i);if(o)return n.length!==this.hiddenPaths.length&&(await this.save(this.items,n),this.hiddenPaths=n),o;let l={id:Ae(),path:i,title:bt(i)||i},u=[l,...this.items];return await this.save(u,n),this.items=u,this.hiddenPaths=n,l})}async discover(e){let t=(await Promise.all([...new Set(e)].filter(kt).map(async i=>{try{let n=await yt(i);return(await vt(n)).isDirectory()?n:null}catch{return null}}))).filter(i=>i!==null);await this.mutate(async()=>{let i=new Set([...this.items.map(l=>l.path),...this.hiddenPaths]),n=[];for(let l of t)i.has(l)||(i.add(l),n.push({id:Ae(),path:l,title:bt(l)||l}));if(n.length===0)return;let o=[...this.items,...n];await this.save(o,this.hiddenPaths),this.items=o})}async remove(e){await this.mutate(async()=>{let t=this.get(e);if(!t)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");let i=this.items.filter(o=>o.id!==e),n=[...new Set([...this.hiddenPaths,t.path])];await this.save(i,n),this.items=i,this.hiddenPaths=n})}mutate(e){let t=this.mutationChain.then(e,e);return this.mutationChain=t.then(()=>{},()=>{}),t}async save(e,t){await wt(ui(this.file),{recursive:!0});let i=`${this.file}.${Ae()}.tmp`;try{await pi(i,JSON.stringify({version:2,items:e,hiddenPaths:t},null,2),{mode:384}),await li(i,this.file)}catch(n){throw await di(i,{force:!0}),n}}};function Pt(r){return fi(r,"pi-web","workspaces.json")}import{createAgentSession as Hi,createEventBus as zi,DefaultResourceLoader as Gi,getAgentDir as Ji,SessionManager as ue,VERSION as Me}from"@earendil-works/pi-coding-agent";var gi="pi-webapp:interaction-open:v1",mi="pi-webapp:interaction-accept:v1",Et="pi-webapp:interaction-settle:v1",hi="pi-webapp:interaction-cancel:v1";var q=class{bus;accepts;changed;requests=new Map;detach;constructor(e,t,i){this.bus=e,this.accepts=t,this.changed=i,this.detach=[e.on(gi,n=>{!wi(n)||!t(n)||this.requests.has(n.requestId)||(this.requests.set(n.requestId,n),e.emit(mi,{requestId:n.requestId}),i())}),e.on(hi,n=>{let o=n,l=this.requests.get(o?.requestId);l&&l.sessionId===o.sessionId&&l.pluginId===o.pluginId&&(this.requests.delete(o.requestId),i())})]}pending(e){return[...this.requests.values()].filter(t=>t.sessionId===e)}resolve(e,t,i,n){let o=this.requests.get(i);if(!o||o.sessionId!==e||o.pluginId!==t||!this.accepts(o))throw new Error("Interaction expired or session changed");this.requests.delete(i),this.bus.emit(Et,{requestId:i,value:n}),this.changed()}cancelAll(e="Session changed"){for(let t of this.requests.values())this.bus.emit(Et,{requestId:t.requestId,error:e});this.requests.clear(),this.changed()}dispose(){for(let e of this.detach)e();this.cancelAll("Interaction host unloaded")}};function wi(r){if(!r||typeof r!="object")return!1;let e=r;for(let t of["requestId","sessionId","pluginId","kind"])if(typeof e[t]!="string"||!e[t]||e[t].length>200)return!1;try{return JSON.stringify(e.data).length<=128*1024}catch{return!1}}var yi=1,vi="pi-webapp:action:v1",bi="pi-webapp:action-response:v1",le="pi-webapp:plugin-changed:v1";function It(r){if(!r||typeof r!="object")return!1;let e=r;return e.apiVersion===yi&&typeof e.client=="string"&&/^\.\/dist\/[\w.-]+\.js$/.test(e.client)&&(e.style===void 0||typeof e.style=="string"&&/^\.\/dist\/[\w.-]+\.css$/.test(e.style))}function de(r,e,t=15e3,i){return new Promise((n,o)=>{let l=!1,u=(p,g)=>{l||(l=!0,clearTimeout(y),f(),i?.removeEventListener("abort",c),p?o(p):n(g))},f=r.on(bi,p=>{let g=p;g?.requestId===e.requestId&&u(g.ok?null:new Error(g.error??"Plugin action failed"),g.value)}),y=setTimeout(()=>u(new Error(`Plugin action timed out: ${e.pluginId}/${e.action}`)),t),c=()=>u(new Error("Plugin action runtime unloaded"));if(i?.addEventListener("abort",c,{once:!0}),i?.aborted)c();else try{r.emit(vi,e)}catch(p){u(p instanceof Error?p:new Error(String(p)))}})}import{realpath as Nt}from"node:fs/promises";import{readFile as _e,realpath as At,stat as _t}from"node:fs/promises";import{createHash as ki}from"node:crypto";import{dirname as St,isAbsolute as Pi,join as Te,parse as Ei,resolve as Ii,sep as Si,delimiter as xi}from"node:path";import{DefaultPackageManager as Ci,getAgentDir as Ai,SettingsManager as _i}from"@earendil-works/pi-coding-agent";async function xt(r,e){let t=await _e(r),i=e?await _e(e):void 0;if(t.length>8*1024*1024||(i?.length??0)>8*1024*1024)throw new Error("Plugin asset exceeds 8 MB");let n=ki("sha256").update(t).update("\0").update(i??"").digest("hex");return{clientBytes:t,styleBytes:i,revision:n}}function Ti(){return(process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS??"").split(xi).filter(Boolean).map(r=>Ii(r))}async function Mi(r){let e=St(r);for(;e!==Ei(e).root;)try{return await _t(Te(e,"package.json")),e}catch{e=St(e)}return null}async function Ct(r,e){let t=await At(Te(r,e));if(!t.startsWith(r+Si))throw new Error("Asset escapes package root");let i=await _t(t);if(!i.isFile()||i.size>8*1024*1024)throw new Error("Plugin asset is not a regular file under 8 MB");return t}var z=class r{plugins;errors;extensionRoots;constructor(e,t,i){this.plugins=e,this.errors=t,this.extensionRoots=i}static async discover(e,t,i=Ti()){let n=_i.create(e,void 0,{projectTrusted:t}),o=new Ci({cwd:e,agentDir:Ai(),settingsManager:n}),l=await o.resolve(async()=>"skip"),u=i.length?await o.resolveExtensionSources(i,{temporary:!0}):{extensions:[]},f=new Set;for(let m of[...l.extensions,...u.extensions]){if(!m.enabled)continue;let k=await Mi(m.path);k&&f.add(k)}for(let m of i)Pi(m)&&f.add(m);let y=[],c=[],p=[],g=new Set;for(let m of f)try{let k=await At(m),P=JSON.parse(await _e(Te(k,"package.json"),"utf8"));if(P.piWebapp===void 0)continue;if(typeof P.name!="string"||!P.name)throw new Error("Missing package name");if(!It(P.piWebapp))throw new Error("Unsupported piWebapp manifest or asset path");if(g.has(P.name))throw new Error(`Duplicate plugin id: ${P.name}`);let M=await Ct(k,P.piWebapp.client),h=P.piWebapp.style?await Ct(k,P.piWebapp.style):void 0;g.add(P.name),y.push({id:P.name,root:k,manifest:P.piWebapp,clientPath:M,stylePath:h,...await xt(M,h)}),p.push(k)}catch(k){c.push(`${m}: ${k instanceof Error?k.message:String(k)}`)}return y.sort((m,k)=>m.id.localeCompare(k.id)),new r(y,c,p)}has(e){return this.plugins.some(t=>t.id===e)}ids(){return this.plugins.map(e=>e.id)}async refreshAssets(){for(let e of this.plugins)Object.assign(e,await xt(e.clientPath,e.stylePath))}view(){return{plugins:this.plugins.map(e=>({id:e.id,client:`/plugins/${encodeURIComponent(e.id)}/client.js?v=${e.revision}`,...e.stylePath?{style:`/plugins/${encodeURIComponent(e.id)}/client.css?v=${e.revision}`}:{}})),errors:this.errors}}async asset(e){let t=new URL(e,"http://localhost"),i=/^\/plugins\/([^/]+)\/(client\.js|client\.css)$/.exec(t.pathname);if(!i)return null;let n;try{n=decodeURIComponent(i[1])}catch{return null}let o=this.plugins.find(u=>u.id===n);if(!o||t.searchParams.has("v")&&t.searchParams.get("v")!==o.revision)return null;let l=i[2]==="client.js"?o.clientBytes:o.styleBytes;return l?{bytes:l,type:i[2]==="client.js"?"text/javascript; charset=utf-8":"text/css; charset=utf-8"}:null}};import{realpath as Tt}from"node:fs/promises";import{SessionManager as Ri}from"@earendil-works/pi-coding-agent";async function Q(r,e){let t=await Tt(r),i=e??await Ri.listAll(),n=await Promise.all(i.map(async o=>o.cwd!==""&&await Tt(o.cwd).catch(()=>null)===t));return i.filter((o,l)=>n[l])}var G=class{tail=Promise.resolve();run(e){let t=this.tail.then(e);return this.tail=t.catch(()=>{}),t}wrap(e){return(...t)=>this.run(()=>e(...t))}},Mt=new WeakMap;function Rt(r,e,t,i=5e3,n=()=>{}){let o=Mt.get(r);if(o)return o;let l=(async()=>{let u;try{await Promise.race([r.extensionRunner.emit({type:"session_shutdown",reason:e}),new Promise((f,y)=>{u=setTimeout(()=>y(new Error("Plugin shutdown timed out")),i)})])}catch(f){t(f instanceof Error?f.message:String(f))}finally{clearTimeout(u);try{n()}finally{r.dispose()}}})();return Mt.set(r,l),l}function pe(r){let t=[...r].reverse().find(i=>i.role==="assistant")?.blocks.filter(i=>i.kind==="text").map(i=>i.text).join(`
19
- `);return{customType:Ie,display:!1,details:{action:"resume"},content:"The user clicked Continue for the interrupted turn. Continue the response to the latest user request from the interrupted point. Preserve completed work and do not repeat text already delivered. Check existing task progress when needed."+(t?`
18
+ `);u.clear();let d;try{await new Promise((C,E)=>{k.close(x=>x?E(x):C()),d=setTimeout(()=>k.closeAllConnections(),50).unref()})}finally{clearTimeout(d),await t.close()}}}}import{getSupportedThinkingLevels as ui}from"@earendil-works/pi-ai";function ht(r){let e=[],t=r;for(;;){let i=/(^|\n\n)附件 ("(?:\\.|[^"\\])*"):([^\n]+)$/u.exec(t);if(!i||!/[\\/]pi-web[\\/]attachments[\\/][a-f0-9]{64}[\\/]/u.test(i[3]))break;let s;try{s=JSON.parse(i[2])}catch{break}e.unshift({name:s,image:/\.(?:png|jpe?g|webp|gif)$/iu.test(s)}),t=t.slice(0,i.index)}return{text:t,attachments:e}}var X="pi-webapp/paused",Se="pi-webapp/resume";function Z(r){for(let e=r.length-1;e>=0;e--){let t=r[e];if(t.type==="custom_message"&&t.customType===Se)return!1;if(t.type==="custom"&&t.customType===X)return!0;if(t.type==="message"){if(t.message.role==="user")return!1;if(t.message.role==="assistant"){if(t.message.stopReason==="aborted")return!0;if(t.message.stopReason==="stop"||t.message.stopReason==="length"||t.message.stopReason==="error")return!1}}}return!1}function Ie(r,e){let t=[],i;for(let s of r){if(s.type==="message"&&(i=s.id),s.type!=="custom")continue;let o=e.find(l=>s.customType.startsWith(`${l}/`));if(o){try{if(JSON.stringify(s.data).length>128*1024)continue}catch{continue}t.push({id:s.id,pluginId:o,kind:s.customType,data:s.data,timestamp:s.timestamp,...i?{afterMessageId:i}:{}})}}return t}function H(r){return typeof r=="string"?[{kind:"text",text:r}]:r.flatMap(e=>e.type==="text"?[{kind:"text",text:e.text}]:e.type==="thinking"?[{kind:"thinking",text:e.thinking}]:e.type==="image"?[{kind:"image",text:"\u56FE\u7247\u9644\u4EF6"}]:e.type==="toolCall"?[{kind:"toolCall",text:JSON.stringify(e.arguments??{}),toolName:e.name,toolCallId:e.id}]:[])}function xe(r){if(r.type==="custom_message")return r.display?{id:r.id,role:"notice",timestamp:r.timestamp,blocks:H(r.content)}:null;if(r.type!=="message")return null;let{message:e}=r;return e.role==="user"||e.role==="assistant"?{id:r.id,role:e.role,timestamp:r.timestamp,blocks:H(e.content),...e.role==="assistant"?{...e.stopReason==="error"&&e.errorMessage?{error:e.errorMessage}:{},usage:{input:e.usage.input,output:e.usage.output,cacheRead:e.usage.cacheRead,cacheWrite:e.usage.cacheWrite,...e.usage.reasoning===void 0?{}:{reasoning:e.usage.reasoning},totalTokens:e.usage.totalTokens,cost:e.usage.cost.total},model:`${e.provider}/${e.model}`}:{}}:e.role==="toolResult"?{id:r.id,role:"tool",timestamp:r.timestamp,blocks:H(e.content),isError:e.isError,toolCallId:e.toolCallId,toolName:e.toolName}:null}function Ce(r,e){let t=r?.trim();if(t)return t;let i=e.find(o=>o.role==="user"),s=ht(i?.blocks.find(o=>o.kind==="text")?.text??"").text.replace(/\s+/g," ").trim();return s?s.slice(0,50):"\u5F53\u524D\u4F1A\u8BDD"}function wt(r,e,t=[]){let i=r.sessionManager.getBranch().flatMap(s=>{let o=xe(s);return o?[o]:[]});return{schemaVersion:1,sessionId:r.sessionManager.getSessionId(),cwd:r.cwd,name:Ce(e,i),model:r.model?`${r.model.provider}/${r.model.id}`:null,thinkingLevel:r.thinkingLevel??null,thinkingLevels:r.model?ui(r.model):["off"],idle:r.isIdle(),paused:Z(r.sessionManager.getBranch()),contextUsage:r.getContextUsage()??null,messages:i,pluginEntries:Ie(r.sessionManager.getBranch(),t)}}import{randomUUID as Ae}from"node:crypto";import{mkdir as yt,readFile as fi,realpath as vt,rename as gi,rm as mi,stat as bt,writeFile as hi}from"node:fs/promises";import{basename as kt,dirname as wi,isAbsolute as Pt,join as yi}from"node:path";var ce=class{items=[];hiddenPaths=[];mutationChain=Promise.resolve();file;constructor(e){this.file=e}async load(){try{let e=JSON.parse(await fi(this.file,"utf8")),t,i=[];if(Array.isArray(e)?t=e:e&&typeof e=="object"&&"version"in e&&e.version===2&&"items"in e&&"hiddenPaths"in e&&(t=e.items,i=e.hiddenPaths),!Array.isArray(t)||!Array.isArray(i))throw new Error("\u5DE5\u4F5C\u533A\u8BB0\u5F55\u65E0\u6548");this.items=t.filter(s=>typeof s=="object"&&s!==null&&typeof s.id=="string"&&typeof s.path=="string"&&typeof s.title=="string"),this.hiddenPaths=i.filter(s=>typeof s=="string")}catch(e){if(e.code!=="ENOENT")throw e}}list(){return[...this.items]}get(e){return this.items.find(t=>t.id===e)}async add(e,t=!1){if(!Pt(e)||e.includes("\0"))throw new Error("\u8BF7\u8F93\u5165\u5B8C\u6574\u7684\u76EE\u5F55\u8DEF\u5F84");t&&await yt(e,{recursive:!0});let i=await vt(e);if(!(await bt(i)).isDirectory())throw new Error("\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55");return this.mutate(async()=>{let s=this.hiddenPaths.filter(f=>f!==i),o=this.items.find(f=>f.path===i);if(o)return s.length!==this.hiddenPaths.length&&(await this.save(this.items,s),this.hiddenPaths=s),o;let l={id:Ae(),path:i,title:kt(i)||i},u=[l,...this.items];return await this.save(u,s),this.items=u,this.hiddenPaths=s,l})}async discover(e){let t=(await Promise.all([...new Set(e)].filter(Pt).map(async i=>{try{let s=await vt(i);return(await bt(s)).isDirectory()?s:null}catch{return null}}))).filter(i=>i!==null);await this.mutate(async()=>{let i=new Set([...this.items.map(l=>l.path),...this.hiddenPaths]),s=[];for(let l of t)i.has(l)||(i.add(l),s.push({id:Ae(),path:l,title:kt(l)||l}));if(s.length===0)return;let o=[...this.items,...s];await this.save(o,this.hiddenPaths),this.items=o})}async remove(e){await this.mutate(async()=>{let t=this.get(e);if(!t)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");let i=this.items.filter(o=>o.id!==e),s=[...new Set([...this.hiddenPaths,t.path])];await this.save(i,s),this.items=i,this.hiddenPaths=s})}mutate(e){let t=this.mutationChain.then(e,e);return this.mutationChain=t.then(()=>{},()=>{}),t}async save(e,t){await yt(wi(this.file),{recursive:!0});let i=`${this.file}.${Ae()}.tmp`;try{await hi(i,JSON.stringify({version:2,items:e,hiddenPaths:t},null,2),{mode:384}),await gi(i,this.file)}catch(s){throw await mi(i,{force:!0}),s}}};function Et(r){return yi(r,"pi-web","workspaces.json")}import{createAgentSession as Yi,createEventBus as Ki,DefaultResourceLoader as Xi,getAgentDir as Zi,SessionManager as ue,VERSION as Me}from"@earendil-works/pi-coding-agent";var vi="pi-webapp:interaction-open:v1",bi="pi-webapp:interaction-accept:v1",St="pi-webapp:interaction-settle:v1",ki="pi-webapp:interaction-cancel:v1";var q=class{bus;accepts;changed;requests=new Map;detach;constructor(e,t,i){this.bus=e,this.accepts=t,this.changed=i,this.detach=[e.on(vi,s=>{!Pi(s)||!t(s)||this.requests.has(s.requestId)||(this.requests.set(s.requestId,s),e.emit(bi,{requestId:s.requestId}),i())}),e.on(ki,s=>{let o=s,l=this.requests.get(o?.requestId);l&&l.sessionId===o.sessionId&&l.pluginId===o.pluginId&&(this.requests.delete(o.requestId),i())})]}pending(e){return[...this.requests.values()].filter(t=>t.sessionId===e)}resolve(e,t,i,s){let o=this.requests.get(i);if(!o||o.sessionId!==e||o.pluginId!==t||!this.accepts(o))throw new Error("Interaction expired or session changed");this.requests.delete(i),this.bus.emit(St,{requestId:i,value:s}),this.changed()}cancelAll(e="Session changed"){for(let t of this.requests.values())this.bus.emit(St,{requestId:t.requestId,error:e});this.requests.clear(),this.changed()}dispose(){for(let e of this.detach)e();this.cancelAll("Interaction host unloaded")}};function Pi(r){if(!r||typeof r!="object")return!1;let e=r;for(let t of["requestId","sessionId","pluginId","kind"])if(typeof e[t]!="string"||!e[t]||e[t].length>200)return!1;try{return JSON.stringify(e.data).length<=128*1024}catch{return!1}}var Ei=1,Si="pi-webapp:action:v1",Ii="pi-webapp:action-response:v1",le="pi-webapp:plugin-changed:v1";function It(r){if(!r||typeof r!="object")return!1;let e=r;return e.apiVersion===Ei&&typeof e.client=="string"&&/^\.\/dist\/[\w.-]+\.js$/.test(e.client)&&(e.style===void 0||typeof e.style=="string"&&/^\.\/dist\/[\w.-]+\.css$/.test(e.style))}function de(r,e,t=15e3,i){return new Promise((s,o)=>{let l=!1,u=(p,g)=>{l||(l=!0,clearTimeout(y),f(),i?.removeEventListener("abort",c),p?o(p):s(g))},f=r.on(Ii,p=>{let g=p;g?.requestId===e.requestId&&u(g.ok?null:new Error(g.error??"Plugin action failed"),g.value)}),y=setTimeout(()=>u(new Error(`Plugin action timed out: ${e.pluginId}/${e.action}`)),t),c=()=>u(new Error("Plugin action runtime unloaded"));if(i?.addEventListener("abort",c,{once:!0}),i?.aborted)c();else try{r.emit(Si,e)}catch(p){u(p instanceof Error?p:new Error(String(p)))}})}import{realpath as jt}from"node:fs/promises";import{readFile as _e,realpath as _t,stat as Tt}from"node:fs/promises";import{createHash as xi}from"node:crypto";import{dirname as xt,isAbsolute as Ci,join as Te,parse as Ai,resolve as _i,sep as Ti,delimiter as Mi}from"node:path";import{DefaultPackageManager as Ri,getAgentDir as Wi,SettingsManager as Ni}from"@earendil-works/pi-coding-agent";async function Ct(r,e){let t=await _e(r),i=e?await _e(e):void 0;if(t.length>8*1024*1024||(i?.length??0)>8*1024*1024)throw new Error("Plugin asset exceeds 8 MB");let s=xi("sha256").update(t).update("\0").update(i??"").digest("hex");return{clientBytes:t,styleBytes:i,revision:s}}function ji(){return(process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS??"").split(Mi).filter(Boolean).map(r=>_i(r))}async function Bi(r){let e=xt(r);for(;e!==Ai(e).root;)try{return await Tt(Te(e,"package.json")),e}catch{e=xt(e)}return null}async function At(r,e){let t=await _t(Te(r,e));if(!t.startsWith(r+Ti))throw new Error("Asset escapes package root");let i=await Tt(t);if(!i.isFile()||i.size>8*1024*1024)throw new Error("Plugin asset is not a regular file under 8 MB");return t}var z=class r{plugins;errors;extensionRoots;constructor(e,t,i){this.plugins=e,this.errors=t,this.extensionRoots=i}static async discover(e,t,i=ji()){let s=Ni.create(e,void 0,{projectTrusted:t}),o=new Ri({cwd:e,agentDir:Wi(),settingsManager:s}),l=await o.resolve(async()=>"skip"),u=i.length?await o.resolveExtensionSources(i,{temporary:!0}):{extensions:[]},f=new Set;for(let m of[...l.extensions,...u.extensions]){if(!m.enabled)continue;let k=await Bi(m.path);k&&f.add(k)}for(let m of i)Ci(m)&&f.add(m);let y=[],c=[],p=[],g=new Set;for(let m of f)try{let k=await _t(m),P=JSON.parse(await _e(Te(k,"package.json"),"utf8"));if(P.piWebapp===void 0)continue;if(typeof P.name!="string"||!P.name)throw new Error("Missing package name");if(!It(P.piWebapp))throw new Error("Unsupported piWebapp manifest or asset path");if(g.has(P.name))throw new Error(`Duplicate plugin id: ${P.name}`);let M=await At(k,P.piWebapp.client),h=P.piWebapp.style?await At(k,P.piWebapp.style):void 0;g.add(P.name),y.push({id:P.name,root:k,manifest:P.piWebapp,clientPath:M,stylePath:h,...await Ct(M,h)}),p.push(k)}catch(k){c.push(`${m}: ${k instanceof Error?k.message:String(k)}`)}return y.sort((m,k)=>m.id.localeCompare(k.id)),new r(y,c,p)}has(e){return this.plugins.some(t=>t.id===e)}ids(){return this.plugins.map(e=>e.id)}async refreshAssets(){for(let e of this.plugins)Object.assign(e,await Ct(e.clientPath,e.stylePath))}view(){return{plugins:this.plugins.map(e=>({id:e.id,client:`/plugins/${encodeURIComponent(e.id)}/client.js?v=${e.revision}`,...e.stylePath?{style:`/plugins/${encodeURIComponent(e.id)}/client.css?v=${e.revision}`}:{}})),errors:this.errors}}async asset(e){let t=new URL(e,"http://localhost"),i=/^\/plugins\/([^/]+)\/(client\.js|client\.css)$/.exec(t.pathname);if(!i)return null;let s;try{s=decodeURIComponent(i[1])}catch{return null}let o=this.plugins.find(u=>u.id===s);if(!o||t.searchParams.has("v")&&t.searchParams.get("v")!==o.revision)return null;let l=i[2]==="client.js"?o.clientBytes:o.styleBytes;return l?{bytes:l,type:i[2]==="client.js"?"text/javascript; charset=utf-8":"text/css; charset=utf-8"}:null}};import{realpath as Mt}from"node:fs/promises";import{SessionManager as Di}from"@earendil-works/pi-coding-agent";async function Q(r,e){let t=await Mt(r),i=e??await Di.listAll(),s=await Promise.all(i.map(async o=>o.cwd!==""&&await Mt(o.cwd).catch(()=>null)===t));return i.filter((o,l)=>s[l])}var G=class{tail=Promise.resolve();run(e){let t=this.tail.then(e);return this.tail=t.catch(()=>{}),t}wrap(e){return(...t)=>this.run(()=>e(...t))}},Rt=new WeakMap;function Wt(r,e,t,i=5e3,s=()=>{}){let o=Rt.get(r);if(o)return o;let l=(async()=>{let u;try{await Promise.race([r.extensionRunner.emit({type:"session_shutdown",reason:e}),new Promise((f,y)=>{u=setTimeout(()=>y(new Error("Plugin shutdown timed out")),i)})])}catch(f){t(f instanceof Error?f.message:String(f))}finally{clearTimeout(u);try{s()}finally{r.dispose()}}})();return Rt.set(r,l),l}function pe(r){let t=[...r].reverse().find(i=>i.role==="assistant")?.blocks.filter(i=>i.kind==="text").map(i=>i.text).join(`
19
+ `);return{customType:Se,display:!1,details:{action:"resume"},content:"The user clicked Continue for the interrupted turn. Continue the response to the latest user request from the interrupted point. Preserve completed work and do not repeat text already delivered. Check existing task progress when needed."+(t?`
20
20
  Already displayed assistant text (reference data):
21
- ${JSON.stringify(t)}`:"")}}import{createHash as Wi}from"node:crypto";import{readFile as Ni,writeFile as ji,unlink as Bi}from"node:fs/promises";import{basename as Di,dirname as Oi,extname as Li,join as $i}from"node:path";import{DefaultPackageManager as Vi,getAgentDir as Ui,SettingsManager as Fi}from"@earendil-works/pi-coding-agent";var ee=new Map;async function Wt(r,e){let i=await new Vi({cwd:r,agentDir:Ui(),settingsManager:Fi.create(r)}).resolveExtensionSources([...e],{temporary:!0}),n=[],o=[],l=async()=>{for(let u of n.splice(0)){let f=(ee.get(u)??1)-1;f?ee.set(u,f):(ee.delete(u),await Bi(u).catch(()=>{}))}};try{for(let u of i.extensions){if(!u.enabled)continue;let f=Li(u.path);if(![".js",".mjs"].includes(f)){o.push(u.path);continue}let y=await Ni(u.path),c=Wi("sha256").update(y).digest("hex"),p=$i(Oi(u.path),`.pi-web-runtime-${Di(u.path,f)}-${c}${f}`);await ji(p,y,{flag:"wx"}).catch(g=>{if(g.code!=="EEXIST")throw g}),ee.set(p,(ee.get(p)??0)+1),n.push(p),o.push(p)}return{paths:o,release:l}}catch(u){throw await l(),u}}var fe=class{telemetryVersion=1;active=null;queue=new G;generation=0;disposed=!1;publish;fallbackModel;isProjectTrusted;reportError;constructor(e,t,i=()=>!1,n=()=>{}){this.publish=e,this.fallbackModel=t,this.isProjectTrusted=i,this.reportError=n}get session(){return this.active?.session??null}get path(){return this.active?.cwd??null}get catalog(){return this.active?.catalog??null}open(e,t){return this.queue.run(async()=>{this.ensureAvailable();let i=await Nt(e),n;if(t==="new")n=ue.create(i);else if(t==="continue"){let o=(await Q(i))[0];n=o?ue.open(o.path):ue.create(i)}else n="sessionManager"in t?t.sessionManager:ue.open(t.sessionFile);if(await Nt(n.getCwd())!==i)throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");await this.replace(i,n,t==="new"?"new":"resume")})}reload(){return this.queue.run(async()=>{this.ensureAvailable();let e=this.active;if(!e)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A\u4F1A\u8BDD");await this.replace(e.cwd,e.session.sessionManager,"reload")})}ensureAvailable(){if(this.disposed)throw new Error("\u5DE5\u4F5C\u533A\u670D\u52A1\u5DF2\u5173\u95ED");if(this.active&&!this.active.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A")}diagnostic(e,t,i,n){let o=`plugin=${t} session=${e.session.sessionManager.getSessionId()} generation=${e.generation} stage=${i}: ${n}`;console.error(o),this.disposed||this.publish({type:"error",message:o})}async replace(e,t,i){let n=this.active,o=await z.discover(e,this.isProjectTrusted(e)),l=zi(),u=await Wt(e,o.extensionRoots),f=new Gi({cwd:e,agentDir:Ji(),noExtensions:!0,additionalExtensionPaths:u.paths,eventBus:l}),y=null;try{await f.reload();let c=f.getExtensions().errors;if(c.length)throw new Error(c.map(E=>`${E.path}: ${E.error}`).join("; "));let p=t.buildSessionProjection().model?void 0:n?.session.model??this.fallbackModel(),{session:g}=await Hi({cwd:e,sessionManager:t,model:p,resourceLoader:f}),m={session:g,cwd:e,catalog:o,bus:l,generation:++this.generation,closing:!1,waitController:new AbortController,interactions:null,detach:()=>{},releasePaths:u.release};y=m;let k=E=>{!this.disposed&&this.active===m&&!m.closing&&this.publish(E)};m.interactions=new q(l,E=>!m.closing&&E.sessionId===g.sessionManager.getSessionId()&&o.has(E.pluginId),()=>k({type:"snapshot",session:this.snapshotOf(m)}));let P=0,M=l.on(le,()=>k({type:"snapshot",session:this.snapshotOf(m)})),h=g.subscribe(E=>{if(this.active===m&&!m.closing){if(E.type==="message_end"&&E.message.role==="assistant"&&E.message.stopReason==="error"){m.agentErrorReported=!0;let x=this.reportError(new Error("Agent response failed"),{...m.operation,stage:"agent",code:"agent_failed",piVersion:Me});k({type:"error",message:E.message.errorMessage??"Agent response failed",errorCode:"unexpected_error",errorId:x,...m.operation})}E.type==="message_end"&&E.message.role==="toolResult"&&E.message.isError&&this.reportError(new Error("Tool execution failed"),{...m.operation,stage:"tool",code:"tool_failed",piVersion:Me}),E.type==="agent_settled"&&(m.operation=void 0)}E.type==="message_update"&&E.message.role==="assistant"&&Date.now()-P>=60&&(P=Date.now(),k({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(E.message.timestamp).toISOString(),blocks:H(E.message.content)}})),["message_end","agent_start","agent_settled","session_info_changed","entry_appended"].includes(E.type)&&(E.type==="message_end"&&E.message.role==="assistant"&&k({type:"stream",message:null}),k({type:"snapshot",session:this.snapshotOf(m)}))});m.detach=()=>{M(),h()};let d=[],C=!0;if(await g.bindExtensions({mode:"print",shutdownHandler:()=>{},onError:E=>{C&&d.push(E.error),this.diagnostic(m,o.plugins.find(x=>E.extensionPath.startsWith(x.root+"/"))?.id??E.extensionPath,E.event??"runtime",E.error)}}),C=!1,d.length)throw new Error(d.join("; "));if(this.ensureAvailable(),n&&await this.close(n,i),this.disposed)throw new Error("\u5DE5\u4F5C\u533A\u670D\u52A1\u5DF2\u5173\u95ED");this.active=m,y=null,this.publish({type:"stream",message:null}),this.publish({type:"snapshot",session:this.snapshot()})}catch(c){throw y?await this.close(y,"quit"):(l.clear(),await u.release()),c}}async close(e,t){e.closing||(e.closing=!0,e.waitController.abort(),e.interactions.dispose(),await Rt(e.session,t,i=>this.diagnostic(e,"host","shutdown",i),5e3,()=>{e.detach(),e.bus.clear()}),await e.releasePaths())}snapshotOf(e){let{session:t,cwd:i,catalog:n}=e,o=t.sessionManager.getBranch().flatMap(l=>{let u=xe(l);return u?[u]:[]});return{schemaVersion:1,sessionId:t.sessionManager.getSessionId(),cwd:i,name:Ce(t.sessionManager.getSessionName(),o),model:t.model?`${t.model.provider}/${t.model.id}`:null,thinkingLevel:t.thinkingLevel,thinkingLevels:t.getAvailableThinkingLevels(),idle:t.isIdle,paused:Z(t.sessionManager.getBranch()),contextUsage:t.getContextUsage()??null,messages:o,interactions:e.interactions.pending(t.sessionManager.getSessionId()),pluginEntries:Se(t.sessionManager.getBranch(),n.ids())}}snapshot(){if(!this.active)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A\u4F1A\u8BDD");return this.snapshotOf(this.active)}async invokePluginAction(e){let t=this.active;if(this.disposed||!t||t.closing||e.sessionId!==t.session.sessionManager.getSessionId())throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");if(!t.catalog.has(e.pluginId))throw new Error("\u63D2\u4EF6\u672A\u542F\u7528");let i=t.session.extensionRunner,n=await de(t.bus,e,15e3,t.waitController.signal);if(this.active!==t||t.closing||i!==t.session.extensionRunner)throw new Error("\u4F1A\u8BDD\u8FD0\u884C\u5B9E\u4F8B\u5DF2\u5207\u6362");return this.publish({type:"snapshot",session:this.snapshot()}),n}resolveInteraction(e,t,i,n){if(this.disposed||!this.active||this.active.closing)throw new Error("Interaction host unavailable");this.active.interactions.resolve(e,t,i,n)}async send(e,t=[],i){if(this.disposed||!this.session||!this.session.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let n=this.session,o=this.active;o.operation=i,o.agentErrorReported=!1;let l=!1,u,f,y=new Promise((c,p)=>{u=c,f=p});n.prompt(e,{images:t,preflightResult:c=>{c&&(l=!0,u())}}).then(()=>{l||u()}).catch(c=>{if(!l)f(c);else if(this.active===o&&!o.closing&&!o.agentErrorReported){let p=this.reportError(ae(c,"Agent response failed"),{...i,stage:"agent",code:"agent_failed",piVersion:Me});this.publish({type:"error",message:c instanceof Error?c.message:"Pi \u8BF7\u6C42\u5931\u8D25",errorCode:"unexpected_error",errorId:p,...i})}});try{await y}catch(c){throw o.operation=void 0,c}}async stop(){let e=this.active;!e||e.session.isIdle||(e.session.sessionManager.appendCustomEntry(X),await e.session.abort(),this.active===e&&!e.closing&&this.publish({type:"snapshot",session:this.snapshotOf(e)}))}async resume(){let e=this.active;if(this.disposed||!e||e.closing)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");let t=e.session;if(!t.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!Z(t.sessionManager.getBranch()))throw new Error("\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1");if(!t.model)throw new Error("\u8BF7\u5148\u9009\u62E9\u6A21\u578B");if(!(t.modelRuntime.hasConfiguredAuth(t.model.provider)||await t.modelRuntime.checkAuth(t.model.provider)!==void 0))throw new Error("\u8BF7\u5148\u8FDE\u63A5\u5F53\u524D\u6A21\u578B");if(this.active!==e||e.closing)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");if(!t.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!Z(t.sessionManager.getBranch()))throw new Error("\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1");let n=pe(this.snapshotOf(e).messages);t.sendCustomMessage(n,{triggerTurn:!0}).catch(o=>{this.active===e&&!e.closing&&this.publish({type:"error",message:o instanceof Error?o.message:"\u7EE7\u7EED\u5931\u8D25"})})}async models(){return(await this.session?.modelRuntime.getAvailable()??[]).map(t=>({provider:t.provider,id:t.id,name:t.name}))}async setModel(e,t){if(this.disposed||!this.session||!this.session.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let i=this.session.modelRuntime.getModel(e,t);if(!i)throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");await this.session.setModel(i),this.publish({type:"snapshot",session:this.snapshot()})}dispose(){return this.disposed=!0,this.queue.run(async()=>{let e=this.active;this.active=null,e&&await this.close(e,"quit")})}};import{basename as Re,dirname as qi}from"node:path";function jt(r,e){let t=i=>e[i].map(n=>({name:i==="skills"&&Re(n.path).toLowerCase()==="skill.md"?Re(qi(n.path)):Re(n.path),path:n.path,source:n.metadata.source,scope:n.metadata.scope,enabled:n.enabled}));return{packages:r.map(i=>({name:i.source,path:i.installedPath??"",source:i.source,scope:i.scope,enabled:!!i.installedPath})),extensions:t("extensions"),skills:t("skills")}}import{execFile as Yi}from"node:child_process";var Ki=(r,e)=>new Promise((t,i)=>{Yi(r,[...e],{windowsHide:!0},n=>{n?i(n):t()})});async function We(r,e=process.platform,t=process.env,i=Ki){if(t.SSH_CONNECTION||t.SSH_TTY||t.SSH_CLIENT||e==="linux"&&!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;let n=e==="darwin"?"open":e==="linux"?"xdg-open":e==="win32"?"explorer.exe":null;return n===null?!1:(await i(n,[r]),!0)}import{execFile as Xi}from"node:child_process";import{randomUUID as Zi}from"node:crypto";import{existsSync as Bt}from"node:fs";import{access as Qi,mkdir as es,readFile as Dt,rename as ts,rm as Ne,writeFile as Ot}from"node:fs/promises";import{join as j}from"node:path";import{promisify as rs}from"node:util";var is=rs(Xi),ge=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;function ss(r,e){let t=ge.exec(r),i=ge.exec(e);if(!t||!i)throw new Error("\u7248\u672C\u53F7\u65E0\u6548");for(let n=1;n<=3;n++){let o=Number(t[n])-Number(i[n]);if(o)return o}return!t[4]&&i[4]?1:t[4]&&!i[4]?-1:(t[4]??"").localeCompare(i[4]??"",void 0,{numeric:!0})}async function ns(r){try{let{stdout:e}=await is("npm",r,{timeout:18e4,maxBuffer:1048576,encoding:"utf8"});return e}catch(e){let t=e;throw new Error(t.stderr?.trim()||t.message)}}var me=class{agentDir;packageRoot;launcherNonce;runNpm;preparing=!1;restartPending=!1;constructor(e){this.agentDir=e.agentDir,this.packageRoot=e.packageRoot,this.launcherNonce=e.launcherNonce,this.runNpm=e.runNpm??ns}async current(){let e=JSON.parse(await Dt(j(this.packageRoot,"package.json"),"utf8"));if(e.name!=="pi-webapp"||typeof e.version!="string"||!ge.test(e.version))throw new Error("\u5F53\u524D pi-webapp \u7248\u672C\u65E0\u6548");return e.version}async runningVersion(){return this.current()}async check(){let e=await this.current(),t=Bt(j(this.packageRoot,".git")),i={current:e,latest:null,available:!1,canRestart:!!this.launcherNonce&&!t};t?i.reason="\u5F53\u524D\u4ECE\u6E90\u7801\u76EE\u5F55\u8FD0\u884C\u3002\u7F51\u9875\u5347\u7EA7\u4EC5\u652F\u6301 npm \u5B89\u88C5\u7684\u7248\u672C\uFF0C\u4EE5\u514D\u8986\u76D6\u672C\u5730\u4EE3\u7801\u3002":i.canRestart||(i.reason="\u5F53\u524D\u9875\u9762\u7531 Pi \u7EC8\u7AEF\u6253\u5F00\uFF0C\u65E0\u6CD5\u4ECE\u7F51\u9875\u81EA\u52A8\u91CD\u542F Pi\uFF1B\u8BF7\u4F7F\u7528 pi-webapp \u542F\u52A8\u5668\u3002");try{let n=JSON.parse((await this.runNpm(["view","pi-webapp","dist-tags.latest","--json","--prefer-online"])).trim());if(typeof n!="string"||!ge.test(n))throw new Error("npm \u8FD4\u56DE\u7684\u7248\u672C\u53F7\u65E0\u6548");i.latest=n,i.available=ss(n,e)>0}catch(n){throw new Error(`\u68C0\u67E5 npm \u66F4\u65B0\u5931\u8D25\uFF1A${n instanceof Error?n.message:String(n)}`)}return i}async prepare(){if(!this.launcherNonce)throw new Error("\u5F53\u524D\u9875\u9762\u65E0\u6CD5\u81EA\u52A8\u91CD\u542F Pi");if(Bt(j(this.packageRoot,".git")))throw new Error("\u6E90\u7801\u76EE\u5F55\u4E0D\u80FD\u901A\u8FC7\u7F51\u9875\u5347\u7EA7");if(this.restartPending)throw new Error("\u5347\u7EA7\u5DF2\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F");if(this.preparing)throw new Error("\u5347\u7EA7\u6B63\u5728\u8FDB\u884C\u4E2D");this.preparing=!0;try{let e=await this.check();if(!e.available||!e.latest)throw new Error("\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C");let t=j(this.agentDir,"pi-web","releases",e.latest);await Ne(t,{recursive:!0,force:!0}),await es(t,{recursive:!0});try{await this.runNpm(["install",`pi-webapp@${e.latest}`,"--prefix",t,"--ignore-scripts","--no-save","--no-audit","--no-fund"]);let i=j(t,"node_modules","pi-webapp"),n=JSON.parse(await Dt(j(i,"package.json"),"utf8"));if(n.name!=="pi-webapp"||n.version!==e.latest)throw new Error("\u4E0B\u8F7D\u7684\u5305\u4E0E\u76EE\u6807\u7248\u672C\u4E0D\u7B26");let o=j(i,"bin","pi-webapp.mjs");await Promise.all([o,j(i,"dist","extension.js"),j(i,"web","dist","index.html")].map(f=>Qi(f)));let l=j(this.agentDir,"pi-web"),u=j(l,`update.${Zi()}.tmp`);try{await Ot(u,JSON.stringify({version:e.latest,launcher:o}),{mode:384}),await ts(u,j(l,"update.json"))}finally{await Ne(u,{force:!0})}return this.restartPending=!0,{version:e.latest,launcher:o}}catch(i){throw await Ne(t,{recursive:!0,force:!0}),i}}finally{this.preparing=!1}}async requestRestart(e){if(!this.launcherNonce)throw new Error("\u5F53\u524D\u9875\u9762\u65E0\u6CD5\u81EA\u52A8\u91CD\u542F Pi");try{await Ot(j(this.agentDir,"pi-web","launcher.restart"),JSON.stringify({nonce:this.launcherNonce,launcher:e.launcher}),{mode:384})}catch(t){throw this.restartPending=!1,t}}};import{randomUUID as gs}from"node:crypto";var Lt=Be(as(ds(import.meta.url)),"../web/dist"),ms=Symbol.for(`pi-web.bridge-state:${import.meta.url}`),s=globalThis[ms]??={bridge:null,current:null,commandContext:null,pi:null,replacementContext:null,replacementSessionId:null,lastStreamAt:0,workspaces:null,workspaceSessions:null,selected:"tui",activeWorkspaceId:null,autoOpened:!1,tuiCatalog:null,stopPluginWatch:null,interactions:null,lifecycle:new G,tuiGeneration:0,stopChanged:null,tuiWaitController:new AbortController};s.lifecycle??=new G;s.tuiGeneration??=0;s.stopChanged??=null;s.tuiWaitController??=new AbortController;function te(){return s.selected==="sdk"?s.workspaceSessions?.catalog??null:s.tuiCatalog}var hs=null;function ws(){return hs??=ps.create({refreshOnCreate:!1})}var ye=new Map;async function Y(){let r=await ws(),e=s.selected==="tui"?s.current?.modelRegistry:void 0,t=new Set(e?.getRegisteredProviderIds()??[]);for(let i of ye.keys())t.has(i)||(r.unregisterProvider(i),ye.delete(i));for(let i of t){let n=e?.getRegisteredNativeProvider(i),o=e?.getRegisteredProviderConfig(i),l=n??o;!l||ye.get(i)===l||(n?r.registerNativeProvider(n):o&&r.registerProvider(i,o),ye.set(i,l))}return await r.refresh({allowNetwork:!1}),r}function T(){if(s.selected==="sdk")return s.workspaceSessions?.snapshot()??(()=>{throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD")})();if(s.current===null)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");return{...ht(s.current,s.current.sessionManager.getSessionName(),te()?.ids()??[]),interactions:s.interactions?.pending(s.current.sessionManager.getSessionId())??[]}}function A(r){if(T().sessionId!==r)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362")}async function Ut(){let r=s.workspaces?.list()??[],e=T(),t=await ve(e.cwd).catch(o=>(s.bridge?.reportError?.(o,{stage:"workspace_path"}),e.cwd)),i=await Vt.listAll(),n=(await Promise.all(r.map(async o=>{let u=(await Q(o.path,i).catch(f=>(s.bridge?.reportError?.(f,{stage:"workspace_sessions"}),[]))).map(f=>({id:f.id,workspaceId:o.id,path:f.path,name:f.name||f.firstMessage?.slice(0,50)||"\u5F53\u524D\u4F1A\u8BDD",modified:f.modified.toISOString()}));return o.path===t&&!u.some(f=>f.id===e.sessionId)&&u.unshift({id:e.sessionId,workspaceId:o.id,path:null,name:e.name,modified:new Date().toISOString()}),u}))).flat();return{items:r,activeId:s.activeWorkspaceId,sessions:n}}async function L(){try{s.bridge&&s.bridge.publish({type:"workspaces",value:await Ut()})}catch(r){s.bridge?.reportError?.(r,{stage:"workspace_list"})}}async function je(r,e=!1){let t=s.workspaces?.get(r);if(!t)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(await ve(t.path),!e&&s.current&&t.path===await ve(s.current.cwd)){if(s.selected==="sdk"&&s.workspaceSessions?.session&&!s.workspaceSessions.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A");s.selected="tui",s.activeWorkspaceId=r,s.bridge?.publish({type:"stream",message:null}),s.bridge?.publish({type:"snapshot",session:T()})}else{if(!s.workspaceSessions)throw new Error("Pi \u5DE5\u4F5C\u533A\u670D\u52A1\u4E0D\u53EF\u7528");await s.workspaceSessions.open(t.path,e?"new":"continue"),s.selected="sdk",s.activeWorkspaceId=r,s.bridge?.publish({type:"snapshot",session:T()})}await L()}function D(r){let e=s.current;if(e===null||e.sessionManager.getSessionId()!==r)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");return e}function _(r){s.current=r,s.selected==="tui"&&s.bridge?.publish({type:"snapshot",session:T()})}function Ft(){if(s.current===null)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let r=s.selected==="sdk"?s.workspaceSessions?.path:s.current.cwd;if(!r)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A");let e=s.selected==="tui"?s.current.isProjectTrusted():s.workspaceSessions?.session?.settingsManager.isProjectTrusted()??!1;return us.create(r,void 0,{projectTrusted:e})}async function Ht(){let r=Ft(),e=n=>({packages:(n.packages??[]).map(o=>typeof o=="string"?o:o.source),extensions:n.extensions??[],skills:n.skills??[]}),t=new $t({cwd:T().cwd,agentDir:J(),settingsManager:r}),i=jt(t.listConfiguredPackages(),await t.resolve(async()=>"skip"));return{projectTrusted:r.isProjectTrusted(),global:e(r.getGlobalSettings()),project:e(r.getProjectSettings()),installed:i}}async function ys(r){A(r.sessionId);let e=s.selected==="tui"?D(r.sessionId):null;if(e?!e.isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let t=Ft();if(r.scope==="project"&&!t.isProjectTrusted())throw new Error("\u5F53\u524D\u9879\u76EE\u5C1A\u672A\u53D7\u4FE1\u4EFB\uFF0C\u65E0\u6CD5\u4FEE\u6539\u9879\u76EE\u8BBE\u7F6E");let i=r.value.trim(),n=r.scope==="project"?t.getProjectSettings():t.getGlobalSettings();if(r.kind==="packages"){let o=new $t({cwd:T().cwd,agentDir:J(),settingsManager:t});r.action==="add"?await o.installAndPersist(i,{local:r.scope==="project"}):await o.removeAndPersist(i,{local:r.scope==="project"})}else if(r.kind==="extensions"){let o=n.extensions??[],l=r.action==="add"?[...new Set([...o,i])]:o.filter(u=>u!==i);r.scope==="project"?t.setProjectExtensionPaths(l):t.setExtensionPaths(l)}else{let o=n.skills??[],l=r.action==="add"?[...new Set([...o,i])]:o.filter(u=>u!==i);r.scope==="project"?t.setProjectSkillPaths(l):t.setSkillPaths(l)}return await t.flush(),s.selected==="tui"?(s.commandContext&&await s.commandContext.reload(),s.current&&_(s.current)):(await s.workspaceSessions?.reload(),s.bridge?.publish({type:"plugins_changed"})),await Ht()}function De(r,e=We){s.pi=r,s.interactions?.dispose(),s.interactions=new q(r.events,n=>!!s.bridge&&s.selected==="tui"&&n.sessionId===s.current?.sessionManager.getSessionId()&&!!s.tuiCatalog?.has(n.pluginId),()=>{s.current&&s.selected==="tui"&&_(s.current)});let t=()=>{s.stopChanged?.(),s.stopChanged=r.events.on(le,()=>{s.selected==="tui"&&s.current&&_(s.current)})};t(),r.on("session_start",async(n,o)=>{if(s.tuiWaitController.abort(),s.tuiWaitController=new AbortController,s.tuiGeneration++,t(),s.current=o,s.bridge){let l=await z.discover(o.cwd,o.isProjectTrusted?.()??!1);if(s.current!==o)return;s.tuiCatalog=l}s.replacementSessionId!==o.sessionManager.getSessionId()&&(s.replacementContext=null,s.replacementSessionId=null),_(o),s.bridge&&s.bridge.publish({type:"plugins_changed"}),s.selected==="tui"&&s.workspaces&&s.workspaces.add(o.cwd).then(async l=>{s.selected!=="tui"||s.current?.sessionManager.getSessionId()!==o.sessionManager.getSessionId()||(s.activeWorkspaceId=l.id,await L())}).catch(l=>{s.bridge?.publish({type:"error",message:l instanceof Error?l.message:"\u65E0\u6CD5\u6CE8\u518C\u5F53\u524D\u5DE5\u4F5C\u533A",errorCode:"unexpected_error",errorId:s.bridge.reportError?.(l,{stage:"workspace_register"})})}),process.env.PI_WEBAPP_AUTO_OPEN==="1"&&o.mode==="tui"&&!s.autoOpened&&(s.autoOpened=!0,i(o).catch(l=>{o.ui.notify(l instanceof Error?l.message:"Web \u542F\u52A8\u5931\u8D25","error")}))}),r.on("agent_start",(n,o)=>{s.bridge?.breadcrumb?.("agent_start",{...s.operation}),_(o)}),r.on("agent_end",(n,o)=>_(o)),r.on("agent_settled",(n,o)=>{s.bridge?.breadcrumb?.("agent_end",{...s.operation}),s.operation=void 0,_(o)}),r.on("model_select",(n,o)=>_(o)),r.on("thinking_level_select",(n,o)=>_(o)),r.on("message_end",(n,o)=>{if(s.selected==="tui"&&n.message.role==="assistant"&&n.message.stopReason==="error"){let l=s.bridge?.reportError?.(new Error("Agent response failed"),{...s.operation,stage:"agent",code:"agent_failed",piVersion:we});s.bridge?.publish({type:"error",message:n.message.errorMessage??"Agent response failed",errorCode:"unexpected_error",errorId:l,...s.operation})}s.selected==="tui"&&n.message.role==="toolResult"&&n.message.isError&&s.bridge?.reportError?.(new Error("Tool execution failed"),{...s.operation,stage:"tool",code:"tool_failed",piVersion:we}),s.selected==="tui"&&n.message.role==="assistant"&&s.bridge?.publish({type:"stream",message:null}),_(o),s.selected==="tui"&&L()}),r.on("session_info_changed",(n,o)=>_(o)),r.on("message_update",(n,o)=>{if(s.current=o,s.selected!=="tui"||n.message.role!=="assistant"||s.bridge===null)return;let l=Date.now();l-s.lastStreamAt<60||(s.lastStreamAt=l,s.bridge.publish({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(n.message.timestamp).toISOString(),blocks:H(n.message.content)}}))}),r.on("session_shutdown",async n=>{if(s.tuiWaitController.abort(),s.tuiGeneration++,s.stopChanged?.(),s.stopChanged=null,s.interactions?.cancelAll(),s.current=null,n.reason==="new"||n.reason==="resume"||n.reason==="fork"||n.reason==="reload")return;let o=s.bridge,l=s.telemetry;s.bridge=null,s.commandContext=null,s.replacementContext=null,s.replacementSessionId=null,s.pi=null;let u=s.workspaceSessions;s.workspaceSessions=null,await u?.dispose(),s.selected="tui",s.activeWorkspaceId=null,s.autoOpened=!1,s.tuiCatalog=null,s.stopPluginWatch?.(),s.stopPluginWatch=null,s.operation=void 0,s.telemetry=null,o?await o.close():await l?.close()});let i=async n=>{s.telemetry??=new F;try{s.current=n,s.commandContext="newSession"in n?n:null,s.pi=r,s.tuiCatalog=await z.discover(n.cwd,n.isProjectTrusted?.()??!1),s.workspaces===null&&(s.workspaces=new ce(Pt(J())),await s.workspaces.load());try{await s.workspaces.discover((await Vt.listAll()).map(u=>u.cwd))}catch(u){n.ui.notify(`\u65E0\u6CD5\u8BFB\u53D6\u90E8\u5206 Pi \u5386\u53F2\u5DE5\u4F5C\u533A\uFF1A${u instanceof Error?u.message:String(u)}`,"warning")}let o=await s.workspaces.add(n.cwd);if(s.selected==="tui"&&(s.activeWorkspaceId=o.id),s.bridge&&(s.bridge.protocolVersion!==7||s.bridge.buildId!==$||typeof s.bridge.reportError!="function")){let u=s.bridge;if(s.workspaceSessions&&s.workspaceSessions.telemetryVersion!==1&&s.workspaceSessions.session&&!s.workspaceSessions.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A");s.bridge=null,await u.close(),await s.telemetry.close(),s.telemetry=new F}if(s.bridge===null){let u=s.workspaceSessions?.telemetryVersion!==1?s.workspaceSessions:null,f=u?.session&&u.path?{path:u.path,sessionManager:u.session.sessionManager}:null;u&&(await u.dispose(),s.workspaceSessions=null),s.workspaceSessions??=new fe(c=>{s.selected==="sdk"&&(s.bridge?.publish(c),c.type==="snapshot"&&c.session.idle&&L())},()=>s.current?.model,c=>{try{return!!s.current&&cs(s.current.cwd)===c&&(s.current.isProjectTrusted?.()??!1)}catch{return!1}},(c,p)=>s.bridge?.reportError?.(c,p)),f&&await s.workspaceSessions.open(f.path,{sessionManager:f.sessionManager});let y={selfUpdate:new me({agentDir:J(),packageRoot:Be(Lt,"../.."),launcherNonce:process.env.PI_WEBAPP_LAUNCHER_NONCE}),snapshot:T,plugins:async()=>{let c=te();return await c?.refreshAssets(),c?.view()??{plugins:[],errors:[]}},pluginAsset:async c=>te()?.asset(c)??null,async invokePluginAction(c,p,g,m){if(A(c),!te()?.has(p))throw new Error("\u63D2\u4EF6\u672A\u542F\u7528");let k=s.selected,P=s.tuiGeneration,M=s.workspaceSessions?.session,h={requestId:gs(),sessionId:c,pluginId:p,action:g,input:m},d=s.selected==="sdk"?await s.workspaceSessions.invokePluginAction(h):await de(s.pi.events,h,15e3,s.tuiWaitController.signal);if(A(c),k!==s.selected||(k==="tui"?P!==s.tuiGeneration:M!==s.workspaceSessions?.session))throw new Error("\u4F1A\u8BDD\u8FD0\u884C\u5B9E\u4F8B\u5DF2\u5207\u6362");return s.selected==="tui"&&s.current&&_(s.current),d},async resolvePluginInteraction(c,p,g,m){if(A(c),!te()?.has(p))throw new Error("\u63D2\u4EF6\u672A\u542F\u7528");s.selected==="sdk"?s.workspaceSessions.resolveInteraction(c,p,g,m):s.interactions.resolve(c,p,g,m)},image(c,p,g){A(c);let k=(s.selected==="sdk"?s.workspaceSessions?.session?.sessionManager.getBranch():s.current?.sessionManager.getBranch())?.find(M=>M.id===p);if(k?.type!=="message"||k.message.role!=="user"||!Array.isArray(k.message.content))return null;let P=k.message.content[g];return P?.type!=="image"?null:{data:Buffer.from(P.data,"base64"),mimeType:P.mimeType}},async workspaces(){return Ut()},async addWorkspace(c,p){let g=await s.workspaces.add(c,p);try{await je(g.id,!0)}catch(m){throw await L(),m}},async selectWorkspace(c){await je(c)},async newSessionInWorkspace(c){await je(c,!0)},async removeWorkspace(c){if(c===s.activeWorkspaceId)throw new Error("\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A");await s.workspaces.remove(c),await L()},async selectSession(c,p,g){let m=s.workspaces?.get(c);if(!m)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(p===s.current?.sessionManager.getSessionId()&&m.path===await ve(s.current.cwd)){if(s.selected==="sdk"&&s.workspaceSessions?.session&&!s.workspaceSessions.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u4F1A\u8BDD");s.selected="tui",s.activeWorkspaceId=c,s.bridge?.publish({type:"snapshot",session:T()})}else{if(s.selected==="sdk"&&s.workspaceSessions?.session?.sessionManager.getSessionId()===p&&s.workspaceSessions.path===m.path)return;if(!(await Q(m.path)).some(P=>P.id===p&&P.path===g))throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");await s.workspaceSessions.open(m.path,{sessionFile:g}),s.selected="sdk",s.activeWorkspaceId=c,s.bridge?.publish({type:"snapshot",session:T()})}await L()},async models(){if(s.selected==="sdk")return s.workspaceSessions?.models()??[];let c=s.current;if(!c)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let p=c.scopedModels?.map(g=>`${g.model.provider}/${g.model.id}`)??[];return c.modelRegistry.getAvailable().filter(g=>p.length===0||p.includes(`${g.provider}/${g.id}`)).map(g=>({provider:g.provider,id:g.id,name:g.name}))},async providers(){let c=await Y(),p=new Set((await c.listCredentials()).map(g=>g.providerId));return c.getProviders().map(g=>({id:g.id,name:g.name,configured:c.getProviderAuthStatus(g.id).configured,storedCredential:p.has(g.id),methods:[g.auth.apiKey?.login?"api_key":null,g.auth.oauth?"oauth":null].filter(m=>m!==null)}))},async providerModels(c){let p=await Y();return rt(he(J(),"models.json"),c,p)},async updateProviderModel(c,p,g){if(A(c),s.selected==="tui"?!D(c).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let m=T().model;if(g.action==="remove"&&m===`${p}/${g.id}`)throw new Error("\u8BF7\u5148\u5207\u6362\u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B");if(g.action==="save"&&g.originalId&&g.originalId!==g.model.id&&m===`${p}/${g.originalId}`)throw new Error("\u8BF7\u5148\u5207\u6362\u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B");let k=await Y();await it(he(J(),"models.json"),p,g,k),await k.refresh({providers:[p],allowNetwork:!1}),await s.current?.modelRegistry.refresh({providers:[p],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[p],allowNetwork:!1});let P=g.action==="save"?g.model.id:g.action==="base_url"&&m?.startsWith(`${p}/`)?m.slice(p.length+1):null;if(P&&m===`${p}/${P}`)if(s.selected==="sdk")try{await s.workspaceSessions.setModel(p,P)}catch{throw new Error("\u6A21\u578B\u5DF2\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u8BE5\u6A21\u578B\u4EE5\u5E94\u7528\u65B0\u53C2\u6570")}else{let M=D(c),h=M.modelRegistry.find(p,P);if(!h||!s.pi||!await s.pi.setModel(h))throw new Error("\u6A21\u578B\u5DF2\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u8BE5\u6A21\u578B\u4EE5\u5E94\u7528\u65B0\u53C2\u6570");_(M)}},async logoutProvider(c,p){if(A(c),s.selected==="tui"?!D(c).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let g=await Y();if(!(await g.listCredentials()).some(m=>m.providerId===p))throw new Error("\u8BE5\u63D0\u4F9B\u65B9\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u8BA4\u8BC1");await g.logout(p),await s.current?.modelRegistry.refresh({providers:[p],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[p],allowNetwork:!1})},async loginProvider(c,p,g){let m=await Y();await m.login(c,p,Ke(c,p,g)),await m.refresh({providers:[c],allowNetwork:!1}),await s.current?.modelRegistry.refresh({providers:[c],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[c],allowNetwork:!1})},async addCustomProvider(c,p){if(A(c),s.selected==="tui"?!D(c).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let g=await Y();if(g.getProvider(p.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");await Xe(he(J(),"models.json"),p),await g.refresh({allowNetwork:!1}),await s.current?.modelRegistry.refresh({allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({allowNetwork:!1})},commands(){return s.selected==="tui"?(s.pi?.getCommands()??[]).filter(c=>c.name!=="web"&&c.name!=="web-dev-reload").map(c=>({name:c.name,description:c.description})):[]},async compact(c){if(A(c),s.selected==="sdk"){let g=s.workspaceSessions?.session;if(!g||!g.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");await g.compact(),s.bridge?.publish({type:"snapshot",session:T()});return}let p=D(c);if(!p.isIdle())throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");p.compact()},async setModel(c,p,g){if(A(c),s.selected==="sdk"){await s.workspaceSessions.setModel(p,g);return}let m=D(c);if(!m.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let k=m.modelRegistry.find(p,g);if(!k||!m.modelRegistry.getAvailable().some(P=>P.provider===p&&P.id===g))throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");if(!s.pi||!await s.pi.setModel(k))throw new Error("\u6A21\u578B\u63D0\u4F9B\u65B9\u672A\u914D\u7F6E\u8BA4\u8BC1");_(m)},async setThinkingLevel(c,p){if(A(c),!["off","minimal","low","medium","high","xhigh"].includes(p))throw new Error("\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548");if(s.selected==="sdk"){let k=s.workspaceSessions?.session;if(!k||!k.isIdle||!k.getAvailableThinkingLevels().includes(p))throw new Error("\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6");k.setThinkingLevel(p),s.bridge?.publish({type:"snapshot",session:T()});return}let m=D(c);if(!m.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!m.model||!fs(m.model).includes(p))throw new Error("\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6");if(!s.pi)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");s.pi.setThinkingLevel(p),_(m)},config:Ht,updateConfig:ys,async send(c,p,g=[],m){if(A(c),s.selected==="sdk"){await s.workspaceSessions.send(p,g,m);return}if(!D(c).isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");s.operation=m;try{if(s.bridge?.breadcrumb?.("send",{...m,piVersion:we}),s.replacementContext!==null&&s.replacementSessionId===c){await s.replacementContext.sendUserMessage(g.length?[{type:"text",text:p},...g]:p,{expandPromptTemplates:!0});return}if(s.pi===null)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");s.pi.sendUserMessage(g.length?[{type:"text",text:p},...g]:p,{expandPromptTemplates:!0})}catch(P){throw s.operation=void 0,P}},async abort(c){if(A(c),s.selected==="sdk")await s.workspaceSessions.stop();else{let p=D(c);if(p.isIdle())return;if(!s.pi)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");s.pi.appendEntry(X),p.abort()}},async resume(c){if(A(c),s.selected==="sdk"){await s.workspaceSessions.resume();return}let p=D(c);if(!p.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!p.model||!s.pi)throw new Error("\u8BF7\u5148\u9009\u62E9\u6A21\u578B");if(!p.modelRegistry.hasConfiguredAuth(p.model))throw new Error("\u8BF7\u5148\u8FDE\u63A5\u5F53\u524D\u6A21\u578B");s.pi.sendMessage(pe(T().messages),{triggerTurn:!0})},async newSession(c){if(A(c),s.selected==="sdk"){let m=s.workspaces?.get(s.activeWorkspaceId??"");if(!m)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");await s.workspaceSessions.open(m.path,"new"),await L();return}let p=D(c);if(!p.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(s.commandContext===null){await s.workspaceSessions.open(p.cwd,"new"),s.selected="sdk",s.bridge?.publish({type:"snapshot",session:T()}),await L();return}if((await s.commandContext.newSession({withSession:async m=>{s.commandContext=m,s.replacementContext=m,s.replacementSessionId=m.sessionManager.getSessionId(),s.current=m}})).cancelled)throw new Error("\u65B0\u4F1A\u8BDD\u5DF2\u53D6\u6D88");await L()}};y.addWorkspace=s.lifecycle.wrap(y.addWorkspace),y.selectWorkspace=s.lifecycle.wrap(y.selectWorkspace),y.newSessionInWorkspace=s.lifecycle.wrap(y.newSessionInWorkspace),y.removeWorkspace=s.lifecycle.wrap(y.removeWorkspace),y.selectSession=s.lifecycle.wrap(y.selectSession),y.newSession=s.lifecycle.wrap(y.newSession),y.updateConfig=s.lifecycle.wrap(y.updateConfig),s.bridge=await gt(y,Lt,s.telemetry)}if(s.stopPluginWatch===null&&process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS){let u=[],f=null;for(let y of(process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS??"").split(os).filter(Boolean))try{u.push(ls(he(Be(y),"dist"),(c,p)=>{let g=String(p??"");["client.js","client.css"].includes(g)&&(f&&clearTimeout(f),f=setTimeout(()=>s.bridge?.publish({type:"plugins_changed"}),180))}))}catch(c){s.bridge?.publish({type:"error",message:`\u63D2\u4EF6\u76D1\u542C\u5931\u8D25\uFF1A${y}: ${String(c)}`})}s.stopPluginWatch=()=>{for(let y of u)y.close();f&&clearTimeout(f)}}let l=await e(s.bridge.url).catch(()=>!1);n.ui.notify(`pi-webapp: ${s.bridge.url}`,l?"info":"warning"),n.ui.setStatus("pi-webapp","Web \u5DF2\u542F\u52A8 \xB7 /web \u91CD\u65B0\u6253\u5F00")}catch(o){throw s.telemetry?.capture(o,{stage:"open_web",piVersion:we}),s.bridge||(await s.telemetry?.close(),s.telemetry=null),o}};r.registerCommand("web",{description:"Open the current Pi session in a local web interface",handler:async(n,o)=>i(o)}),r.registerCommand("web-dev-reload",{description:"Reload local pi-webapp plugins during development",handler:async(n,o)=>{process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS&&(await o.waitForIdle(),await s.lifecycle.run(async()=>{let l=s.workspaceSessions?.session;l&&(await l.waitForIdle(),await s.workspaceSessions.reload()),await o.reload()}))}})}var Uo=De;export{Uo as default};
21
+ ${JSON.stringify(t)}`:"")}}import{createHash as Oi}from"node:crypto";import{readFile as Li,writeFile as $i,unlink as Vi}from"node:fs/promises";import{basename as Ui,dirname as Fi,extname as Hi,join as zi}from"node:path";import{DefaultPackageManager as Gi,getAgentDir as Ji,SettingsManager as qi}from"@earendil-works/pi-coding-agent";var ee=new Map;async function Nt(r,e){let i=await new Gi({cwd:r,agentDir:Ji(),settingsManager:qi.create(r)}).resolveExtensionSources([...e],{temporary:!0}),s=[],o=[],l=async()=>{for(let u of s.splice(0)){let f=(ee.get(u)??1)-1;f?ee.set(u,f):(ee.delete(u),await Vi(u).catch(()=>{}))}};try{for(let u of i.extensions){if(!u.enabled)continue;let f=Hi(u.path);if(![".js",".mjs"].includes(f)){o.push(u.path);continue}let y=await Li(u.path),c=Oi("sha256").update(y).digest("hex"),p=zi(Fi(u.path),`.pi-web-runtime-${Ui(u.path,f)}-${c}${f}`);await $i(p,y,{flag:"wx"}).catch(g=>{if(g.code!=="EEXIST")throw g}),ee.set(p,(ee.get(p)??0)+1),s.push(p),o.push(p)}return{paths:o,release:l}}catch(u){throw await l(),u}}var fe=class{telemetryVersion=1;active=null;queue=new G;generation=0;disposed=!1;publish;fallbackModel;isProjectTrusted;reportError;constructor(e,t,i=()=>!1,s=()=>{}){this.publish=e,this.fallbackModel=t,this.isProjectTrusted=i,this.reportError=s}get session(){return this.active?.session??null}get path(){return this.active?.cwd??null}get catalog(){return this.active?.catalog??null}open(e,t){return this.queue.run(async()=>{this.ensureAvailable();let i=await jt(e),s;if(t==="new")s=ue.create(i);else if(t==="continue"){let o=(await Q(i))[0];s=o?ue.open(o.path):ue.create(i)}else s="sessionManager"in t?t.sessionManager:ue.open(t.sessionFile);if(await jt(s.getCwd())!==i)throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");await this.replace(i,s,t==="new"?"new":"resume")})}reload(){return this.queue.run(async()=>{this.ensureAvailable();let e=this.active;if(!e)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A\u4F1A\u8BDD");await this.replace(e.cwd,e.session.sessionManager,"reload")})}ensureAvailable(){if(this.disposed)throw new Error("\u5DE5\u4F5C\u533A\u670D\u52A1\u5DF2\u5173\u95ED");if(this.active&&!this.active.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A")}diagnostic(e,t,i,s){let o=`plugin=${t} session=${e.session.sessionManager.getSessionId()} generation=${e.generation} stage=${i}: ${s}`;console.error(o),this.disposed||this.publish({type:"error",message:o})}async replace(e,t,i){let s=this.active,o=await z.discover(e,this.isProjectTrusted(e)),l=Ki(),u=await Nt(e,o.extensionRoots),f=new Xi({cwd:e,agentDir:Zi(),noExtensions:!0,additionalExtensionPaths:u.paths,eventBus:l}),y=null;try{await f.reload();let c=f.getExtensions().errors;if(c.length)throw new Error(c.map(E=>`${E.path}: ${E.error}`).join("; "));let p=t.buildSessionProjection().model?void 0:s?.session.model??this.fallbackModel(),{session:g}=await Yi({cwd:e,sessionManager:t,model:p,resourceLoader:f}),m={session:g,cwd:e,catalog:o,bus:l,generation:++this.generation,closing:!1,waitController:new AbortController,interactions:null,detach:()=>{},releasePaths:u.release};y=m;let k=E=>{!this.disposed&&this.active===m&&!m.closing&&this.publish(E)};m.interactions=new q(l,E=>!m.closing&&E.sessionId===g.sessionManager.getSessionId()&&o.has(E.pluginId),()=>k({type:"snapshot",session:this.snapshotOf(m)}));let P=0,M=l.on(le,()=>k({type:"snapshot",session:this.snapshotOf(m)})),h=g.subscribe(E=>{if(this.active===m&&!m.closing){if(E.type==="message_end"&&E.message.role==="assistant"&&E.message.stopReason==="error"){m.agentErrorReported=!0;let x=this.reportError(new Error("Agent response failed"),{...m.operation,stage:"agent",code:"agent_failed",piVersion:Me});k({type:"error",message:E.message.errorMessage??"Agent response failed",errorCode:"unexpected_error",errorId:x,...m.operation})}E.type==="message_end"&&E.message.role==="toolResult"&&E.message.isError&&this.reportError(new Error("Tool execution failed"),{...m.operation,stage:"tool",code:"tool_failed",piVersion:Me}),E.type==="agent_settled"&&(m.operation=void 0)}E.type==="message_update"&&E.message.role==="assistant"&&Date.now()-P>=60&&(P=Date.now(),k({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(E.message.timestamp).toISOString(),blocks:H(E.message.content)}})),["message_end","agent_start","agent_settled","session_info_changed","entry_appended"].includes(E.type)&&(E.type==="message_end"&&E.message.role==="assistant"&&k({type:"stream",message:null}),k({type:"snapshot",session:this.snapshotOf(m)}))});m.detach=()=>{M(),h()};let d=[],C=!0;if(await g.bindExtensions({mode:"print",shutdownHandler:()=>{},onError:E=>{C&&d.push(E.error),this.diagnostic(m,o.plugins.find(x=>E.extensionPath.startsWith(x.root+"/"))?.id??E.extensionPath,E.event??"runtime",E.error)}}),C=!1,d.length)throw new Error(d.join("; "));if(this.ensureAvailable(),s&&await this.close(s,i),this.disposed)throw new Error("\u5DE5\u4F5C\u533A\u670D\u52A1\u5DF2\u5173\u95ED");this.active=m,y=null,this.publish({type:"stream",message:null}),this.publish({type:"snapshot",session:this.snapshot()})}catch(c){throw y?await this.close(y,"quit"):(l.clear(),await u.release()),c}}async close(e,t){e.closing||(e.closing=!0,e.waitController.abort(),e.interactions.dispose(),await Wt(e.session,t,i=>this.diagnostic(e,"host","shutdown",i),5e3,()=>{e.detach(),e.bus.clear()}),await e.releasePaths())}snapshotOf(e){let{session:t,cwd:i,catalog:s}=e,o=t.sessionManager.getBranch().flatMap(l=>{let u=xe(l);return u?[u]:[]});return{schemaVersion:1,sessionId:t.sessionManager.getSessionId(),cwd:i,name:Ce(t.sessionManager.getSessionName(),o),model:t.model?`${t.model.provider}/${t.model.id}`:null,thinkingLevel:t.thinkingLevel,thinkingLevels:t.getAvailableThinkingLevels(),idle:t.isIdle,paused:Z(t.sessionManager.getBranch()),contextUsage:t.getContextUsage()??null,messages:o,interactions:e.interactions.pending(t.sessionManager.getSessionId()),pluginEntries:Ie(t.sessionManager.getBranch(),s.ids())}}snapshot(){if(!this.active)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A\u4F1A\u8BDD");return this.snapshotOf(this.active)}async invokePluginAction(e){let t=this.active;if(this.disposed||!t||t.closing||e.sessionId!==t.session.sessionManager.getSessionId())throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");if(!t.catalog.has(e.pluginId))throw new Error("\u63D2\u4EF6\u672A\u542F\u7528");let i=t.session.extensionRunner,s=await de(t.bus,e,15e3,t.waitController.signal);if(this.active!==t||t.closing||i!==t.session.extensionRunner)throw new Error("\u4F1A\u8BDD\u8FD0\u884C\u5B9E\u4F8B\u5DF2\u5207\u6362");return this.publish({type:"snapshot",session:this.snapshot()}),s}resolveInteraction(e,t,i,s){if(this.disposed||!this.active||this.active.closing)throw new Error("Interaction host unavailable");this.active.interactions.resolve(e,t,i,s)}async send(e,t=[],i){if(this.disposed||!this.session||!this.session.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let s=this.session,o=this.active;o.operation=i,o.agentErrorReported=!1;let l=!1,u,f,y=new Promise((c,p)=>{u=c,f=p});s.prompt(e,{images:t,preflightResult:c=>{c&&(l=!0,u())}}).then(()=>{l||u()}).catch(c=>{if(!l)f(c);else if(this.active===o&&!o.closing&&!o.agentErrorReported){let p=this.reportError(ae(c,"Agent response failed"),{...i,stage:"agent",code:"agent_failed",piVersion:Me});this.publish({type:"error",message:c instanceof Error?c.message:"Pi \u8BF7\u6C42\u5931\u8D25",errorCode:"unexpected_error",errorId:p,...i})}});try{await y}catch(c){throw o.operation=void 0,c}}async stop(){let e=this.active;!e||e.session.isIdle||(e.session.sessionManager.appendCustomEntry(X),await e.session.abort(),this.active===e&&!e.closing&&this.publish({type:"snapshot",session:this.snapshotOf(e)}))}async resume(){let e=this.active;if(this.disposed||!e||e.closing)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");let t=e.session;if(!t.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!Z(t.sessionManager.getBranch()))throw new Error("\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1");if(!t.model)throw new Error("\u8BF7\u5148\u9009\u62E9\u6A21\u578B");if(!(t.modelRuntime.hasConfiguredAuth(t.model.provider)||await t.modelRuntime.checkAuth(t.model.provider)!==void 0))throw new Error("\u8BF7\u5148\u8FDE\u63A5\u5F53\u524D\u6A21\u578B");if(this.active!==e||e.closing)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");if(!t.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!Z(t.sessionManager.getBranch()))throw new Error("\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u6682\u505C\u7684\u4EFB\u52A1");let s=pe(this.snapshotOf(e).messages);t.sendCustomMessage(s,{triggerTurn:!0}).catch(o=>{this.active===e&&!e.closing&&this.publish({type:"error",message:o instanceof Error?o.message:"\u7EE7\u7EED\u5931\u8D25"})})}async models(){return(await this.session?.modelRuntime.getAvailable()??[]).map(t=>({provider:t.provider,id:t.id,name:t.name}))}async setModel(e,t){if(this.disposed||!this.session||!this.session.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let i=this.session.modelRuntime.getModel(e,t);if(!i)throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");await this.session.setModel(i),this.publish({type:"snapshot",session:this.snapshot()})}dispose(){return this.disposed=!0,this.queue.run(async()=>{let e=this.active;this.active=null,e&&await this.close(e,"quit")})}};import{basename as Re,dirname as Qi}from"node:path";function Bt(r,e){let t=i=>e[i].map(s=>({name:i==="skills"&&Re(s.path).toLowerCase()==="skill.md"?Re(Qi(s.path)):Re(s.path),path:s.path,source:s.metadata.source,scope:s.metadata.scope,enabled:s.enabled}));return{packages:r.map(i=>({name:i.source,path:i.installedPath??"",source:i.source,scope:i.scope,enabled:!!i.installedPath})),extensions:t("extensions"),skills:t("skills")}}import{execFile as en}from"node:child_process";var tn=(r,e)=>new Promise((t,i)=>{en(r,[...e],{windowsHide:!0},s=>{s?i(s):t()})});async function We(r,e=process.platform,t=process.env,i=tn){if(t.SSH_CONNECTION||t.SSH_TTY||t.SSH_CLIENT||e==="linux"&&!t.DISPLAY&&!t.WAYLAND_DISPLAY)return!1;let s=e==="darwin"?"open":e==="linux"?"xdg-open":e==="win32"?"explorer.exe":null;return s===null?!1:(await i(s,[r]),!0)}import{execFile as cn}from"node:child_process";import{randomUUID as ln}from"node:crypto";import{existsSync as Vt}from"node:fs";import{access as dn,mkdir as pn,readFile as Ut,rename as un,rm as je,writeFile as Ft}from"node:fs/promises";import{join as j}from"node:path";import{promisify as fn}from"node:util";import{realpathSync as Lt,statSync as rn}from"node:fs";import{basename as nn,delimiter as sn,dirname as Dt,join as Ne,resolve as on}from"node:path";function Ot(r){if(!r)return null;try{let e=Lt(r);return nn(e)==="npm-cli.js"&&rn(e).isFile()?e:null}catch{return null}}function an({execPath:r=process.execPath,env:e=process.env}={}){let t=Ot(e.npm_execpath);if(t)return t;let i=new Set([Dt(r)]);try{i.add(Dt(Lt(r)))}catch{}let s=Object.entries(e).find(([o])=>o.toLowerCase()==="path")?.[1]??"";for(let o of s.split(sn).filter(Boolean))i.add(on(o));for(let o of i)for(let l of[Ne(o,"node_modules","npm","bin","npm-cli.js"),Ne(o,"..","lib","node_modules","npm","bin","npm-cli.js"),Ne(o,"npm")]){let u=Ot(l);if(u)return u}throw new Error("\u627E\u4E0D\u5230 npm \u5165\u53E3 npm-cli.js\uFF1B\u8BF7\u5B89\u88C5\u5305\u542B npm \u7684 Node.js\uFF0C\u6216\u5C06 npm \u6240\u5728\u76EE\u5F55\u52A0\u5165 PATH \u540E\u91CD\u542F\u670D\u52A1\u3002")}function $t(r){return{file:process.execPath,args:[an(),...r]}}var gn=fn(cn),ge=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;function mn(r,e){let t=ge.exec(r),i=ge.exec(e);if(!t||!i)throw new Error("\u7248\u672C\u53F7\u65E0\u6548");for(let s=1;s<=3;s++){let o=Number(t[s])-Number(i[s]);if(o)return o}return!t[4]&&i[4]?1:t[4]&&!i[4]?-1:(t[4]??"").localeCompare(i[4]??"",void 0,{numeric:!0})}async function hn(r){try{let e=$t(r),{stdout:t}=await gn(e.file,e.args,{timeout:18e4,maxBuffer:1024*1024,encoding:"utf8",windowsHide:!0});return t}catch(e){let t=e;throw new Error(t.stderr?.trim()||t.message)}}var me=class{agentDir;packageRoot;launcherNonce;runNpm;preparing=!1;restartPending=!1;constructor(e){this.agentDir=e.agentDir,this.packageRoot=e.packageRoot,this.launcherNonce=e.launcherNonce,this.runNpm=e.runNpm??hn}async current(){let e=JSON.parse(await Ut(j(this.packageRoot,"package.json"),"utf8"));if(e.name!=="pi-webapp"||typeof e.version!="string"||!ge.test(e.version))throw new Error("\u5F53\u524D pi-webapp \u7248\u672C\u65E0\u6548");return e.version}async runningVersion(){return this.current()}async check(){let e=await this.current(),t=Vt(j(this.packageRoot,".git")),i={current:e,latest:null,available:!1,canRestart:!!this.launcherNonce&&!t};t?i.reason="\u5F53\u524D\u4ECE\u6E90\u7801\u76EE\u5F55\u8FD0\u884C\u3002\u7F51\u9875\u5347\u7EA7\u4EC5\u652F\u6301 npm \u5B89\u88C5\u7684\u7248\u672C\uFF0C\u4EE5\u514D\u8986\u76D6\u672C\u5730\u4EE3\u7801\u3002":i.canRestart||(i.reason="\u5F53\u524D\u9875\u9762\u7531 Pi \u7EC8\u7AEF\u6253\u5F00\uFF0C\u65E0\u6CD5\u4ECE\u7F51\u9875\u81EA\u52A8\u91CD\u542F Pi\uFF1B\u8BF7\u4F7F\u7528 pi-webapp \u542F\u52A8\u5668\u3002");try{let s=JSON.parse((await this.runNpm(["view","pi-webapp","dist-tags.latest","--json","--prefer-online"])).trim());if(typeof s!="string"||!ge.test(s))throw new Error("npm \u8FD4\u56DE\u7684\u7248\u672C\u53F7\u65E0\u6548");i.latest=s,i.available=mn(s,e)>0}catch(s){throw new Error(`\u68C0\u67E5 npm \u66F4\u65B0\u5931\u8D25\uFF1A${s instanceof Error?s.message:String(s)}`)}return i}async prepare(){if(!this.launcherNonce)throw new Error("\u5F53\u524D\u9875\u9762\u65E0\u6CD5\u81EA\u52A8\u91CD\u542F Pi");if(Vt(j(this.packageRoot,".git")))throw new Error("\u6E90\u7801\u76EE\u5F55\u4E0D\u80FD\u901A\u8FC7\u7F51\u9875\u5347\u7EA7");if(this.restartPending)throw new Error("\u5347\u7EA7\u5DF2\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F");if(this.preparing)throw new Error("\u5347\u7EA7\u6B63\u5728\u8FDB\u884C\u4E2D");this.preparing=!0;try{let e=await this.check();if(!e.available||!e.latest)throw new Error("\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C");let t=j(this.agentDir,"pi-web","releases",e.latest);await je(t,{recursive:!0,force:!0}),await pn(t,{recursive:!0});try{await this.runNpm(["install",`pi-webapp@${e.latest}`,"--prefix",t,"--ignore-scripts","--no-save","--no-audit","--no-fund"]);let i=j(t,"node_modules","pi-webapp"),s=JSON.parse(await Ut(j(i,"package.json"),"utf8"));if(s.name!=="pi-webapp"||s.version!==e.latest)throw new Error("\u4E0B\u8F7D\u7684\u5305\u4E0E\u76EE\u6807\u7248\u672C\u4E0D\u7B26");let o=j(i,"bin","pi-webapp.mjs");await Promise.all([o,j(i,"dist","extension.js"),j(i,"web","dist","index.html")].map(f=>dn(f)));let l=j(this.agentDir,"pi-web"),u=j(l,`update.${ln()}.tmp`);try{await Ft(u,JSON.stringify({version:e.latest,launcher:o}),{mode:384}),await un(u,j(l,"update.json"))}finally{await je(u,{force:!0})}return this.restartPending=!0,{version:e.latest,launcher:o}}catch(i){throw await je(t,{recursive:!0,force:!0}),i}}finally{this.preparing=!1}}async requestRestart(e){if(!this.launcherNonce)throw new Error("\u5F53\u524D\u9875\u9762\u65E0\u6CD5\u81EA\u52A8\u91CD\u542F Pi");try{await Ft(j(this.agentDir,"pi-web","launcher.restart"),JSON.stringify({nonce:this.launcherNonce,launcher:e.launcher}),{mode:384})}catch(t){throw this.restartPending=!1,t}}};import{randomUUID as In}from"node:crypto";var Ht=De(yn(kn(import.meta.url)),"../web/dist"),xn=Symbol.for(`pi-web.bridge-state:${import.meta.url}`),n=globalThis[xn]??={bridge:null,current:null,commandContext:null,pi:null,replacementContext:null,replacementSessionId:null,lastStreamAt:0,workspaces:null,workspaceSessions:null,selected:"tui",activeWorkspaceId:null,autoOpened:!1,tuiCatalog:null,stopPluginWatch:null,interactions:null,lifecycle:new G,tuiGeneration:0,stopChanged:null,tuiWaitController:new AbortController};n.lifecycle??=new G;n.tuiGeneration??=0;n.stopChanged??=null;n.tuiWaitController??=new AbortController;function te(){return n.selected==="sdk"?n.workspaceSessions?.catalog??null:n.tuiCatalog}var Cn=null;function An(){return Cn??=Pn.create({refreshOnCreate:!1})}var ye=new Map;async function Y(){let r=await An(),e=n.selected==="tui"?n.current?.modelRegistry:void 0,t=new Set(e?.getRegisteredProviderIds()??[]);for(let i of ye.keys())t.has(i)||(r.unregisterProvider(i),ye.delete(i));for(let i of t){let s=e?.getRegisteredNativeProvider(i),o=e?.getRegisteredProviderConfig(i),l=s??o;!l||ye.get(i)===l||(s?r.registerNativeProvider(s):o&&r.registerProvider(i,o),ye.set(i,l))}return await r.refresh({allowNetwork:!1}),r}function T(){if(n.selected==="sdk")return n.workspaceSessions?.snapshot()??(()=>{throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD")})();if(n.current===null)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");return{...wt(n.current,n.current.sessionManager.getSessionName(),te()?.ids()??[]),interactions:n.interactions?.pending(n.current.sessionManager.getSessionId())??[]}}function A(r){if(T().sessionId!==r)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362")}async function Jt(){let r=n.workspaces?.list()??[],e=T(),t=await ve(e.cwd).catch(o=>(n.bridge?.reportError?.(o,{stage:"workspace_path"}),e.cwd)),i=await Gt.listAll(),s=(await Promise.all(r.map(async o=>{let u=(await Q(o.path,i).catch(f=>(n.bridge?.reportError?.(f,{stage:"workspace_sessions"}),[]))).map(f=>({id:f.id,workspaceId:o.id,path:f.path,name:f.name||f.firstMessage?.slice(0,50)||"\u5F53\u524D\u4F1A\u8BDD",modified:f.modified.toISOString()}));return o.path===t&&!u.some(f=>f.id===e.sessionId)&&u.unshift({id:e.sessionId,workspaceId:o.id,path:null,name:e.name,modified:new Date().toISOString()}),u}))).flat();return{items:r,activeId:n.activeWorkspaceId,sessions:s}}async function L(){try{n.bridge&&n.bridge.publish({type:"workspaces",value:await Jt()})}catch(r){n.bridge?.reportError?.(r,{stage:"workspace_list"})}}async function Be(r,e=!1){let t=n.workspaces?.get(r);if(!t)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(await ve(t.path),!e&&n.current&&t.path===await ve(n.current.cwd)){if(n.selected==="sdk"&&n.workspaceSessions?.session&&!n.workspaceSessions.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A");n.selected="tui",n.activeWorkspaceId=r,n.bridge?.publish({type:"stream",message:null}),n.bridge?.publish({type:"snapshot",session:T()})}else{if(!n.workspaceSessions)throw new Error("Pi \u5DE5\u4F5C\u533A\u670D\u52A1\u4E0D\u53EF\u7528");await n.workspaceSessions.open(t.path,e?"new":"continue"),n.selected="sdk",n.activeWorkspaceId=r,n.bridge?.publish({type:"snapshot",session:T()})}await L()}function D(r){let e=n.current;if(e===null||e.sessionManager.getSessionId()!==r)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");return e}function _(r){n.current=r,n.selected==="tui"&&n.bridge?.publish({type:"snapshot",session:T()})}function qt(){if(n.current===null)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let r=n.selected==="sdk"?n.workspaceSessions?.path:n.current.cwd;if(!r)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A");let e=n.selected==="tui"?n.current.isProjectTrusted():n.workspaceSessions?.session?.settingsManager.isProjectTrusted()??!1;return En.create(r,void 0,{projectTrusted:e})}async function Yt(){let r=qt(),e=s=>({packages:(s.packages??[]).map(o=>typeof o=="string"?o:o.source),extensions:s.extensions??[],skills:s.skills??[]}),t=new zt({cwd:T().cwd,agentDir:J(),settingsManager:r}),i=Bt(t.listConfiguredPackages(),await t.resolve(async()=>"skip"));return{projectTrusted:r.isProjectTrusted(),global:e(r.getGlobalSettings()),project:e(r.getProjectSettings()),installed:i}}async function _n(r){A(r.sessionId);let e=n.selected==="tui"?D(r.sessionId):null;if(e?!e.isIdle():!n.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let t=qt();if(r.scope==="project"&&!t.isProjectTrusted())throw new Error("\u5F53\u524D\u9879\u76EE\u5C1A\u672A\u53D7\u4FE1\u4EFB\uFF0C\u65E0\u6CD5\u4FEE\u6539\u9879\u76EE\u8BBE\u7F6E");let i=r.value.trim(),s=r.scope==="project"?t.getProjectSettings():t.getGlobalSettings();if(r.kind==="packages"){let o=new zt({cwd:T().cwd,agentDir:J(),settingsManager:t});r.action==="add"?await o.installAndPersist(i,{local:r.scope==="project"}):await o.removeAndPersist(i,{local:r.scope==="project"})}else if(r.kind==="extensions"){let o=s.extensions??[],l=r.action==="add"?[...new Set([...o,i])]:o.filter(u=>u!==i);r.scope==="project"?t.setProjectExtensionPaths(l):t.setExtensionPaths(l)}else{let o=s.skills??[],l=r.action==="add"?[...new Set([...o,i])]:o.filter(u=>u!==i);r.scope==="project"?t.setProjectSkillPaths(l):t.setSkillPaths(l)}return await t.flush(),n.selected==="tui"?(n.commandContext&&await n.commandContext.reload(),n.current&&_(n.current)):(await n.workspaceSessions?.reload(),n.bridge?.publish({type:"plugins_changed"})),await Yt()}function Oe(r,e=We){n.pi=r,n.interactions?.dispose(),n.interactions=new q(r.events,s=>!!n.bridge&&n.selected==="tui"&&s.sessionId===n.current?.sessionManager.getSessionId()&&!!n.tuiCatalog?.has(s.pluginId),()=>{n.current&&n.selected==="tui"&&_(n.current)});let t=()=>{n.stopChanged?.(),n.stopChanged=r.events.on(le,()=>{n.selected==="tui"&&n.current&&_(n.current)})};t(),r.on("session_start",async(s,o)=>{if(n.tuiWaitController.abort(),n.tuiWaitController=new AbortController,n.tuiGeneration++,t(),n.current=o,n.bridge){let l=await z.discover(o.cwd,o.isProjectTrusted?.()??!1);if(n.current!==o)return;n.tuiCatalog=l}n.replacementSessionId!==o.sessionManager.getSessionId()&&(n.replacementContext=null,n.replacementSessionId=null),_(o),n.bridge&&n.bridge.publish({type:"plugins_changed"}),n.selected==="tui"&&n.workspaces&&n.workspaces.add(o.cwd).then(async l=>{n.selected!=="tui"||n.current?.sessionManager.getSessionId()!==o.sessionManager.getSessionId()||(n.activeWorkspaceId=l.id,await L())}).catch(l=>{n.bridge?.publish({type:"error",message:l instanceof Error?l.message:"\u65E0\u6CD5\u6CE8\u518C\u5F53\u524D\u5DE5\u4F5C\u533A",errorCode:"unexpected_error",errorId:n.bridge.reportError?.(l,{stage:"workspace_register"})})}),process.env.PI_WEBAPP_AUTO_OPEN==="1"&&o.mode==="tui"&&!n.autoOpened&&(n.autoOpened=!0,i(o).catch(l=>{o.ui.notify(l instanceof Error?l.message:"Web \u542F\u52A8\u5931\u8D25","error")}))}),r.on("agent_start",(s,o)=>{n.bridge?.breadcrumb?.("agent_start",{...n.operation}),_(o)}),r.on("agent_end",(s,o)=>_(o)),r.on("agent_settled",(s,o)=>{n.bridge?.breadcrumb?.("agent_end",{...n.operation}),n.operation=void 0,_(o)}),r.on("model_select",(s,o)=>_(o)),r.on("thinking_level_select",(s,o)=>_(o)),r.on("message_end",(s,o)=>{if(n.selected==="tui"&&s.message.role==="assistant"&&s.message.stopReason==="error"){let l=n.bridge?.reportError?.(new Error("Agent response failed"),{...n.operation,stage:"agent",code:"agent_failed",piVersion:we});n.bridge?.publish({type:"error",message:s.message.errorMessage??"Agent response failed",errorCode:"unexpected_error",errorId:l,...n.operation})}n.selected==="tui"&&s.message.role==="toolResult"&&s.message.isError&&n.bridge?.reportError?.(new Error("Tool execution failed"),{...n.operation,stage:"tool",code:"tool_failed",piVersion:we}),n.selected==="tui"&&s.message.role==="assistant"&&n.bridge?.publish({type:"stream",message:null}),_(o),n.selected==="tui"&&L()}),r.on("session_info_changed",(s,o)=>_(o)),r.on("message_update",(s,o)=>{if(n.current=o,n.selected!=="tui"||s.message.role!=="assistant"||n.bridge===null)return;let l=Date.now();l-n.lastStreamAt<60||(n.lastStreamAt=l,n.bridge.publish({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(s.message.timestamp).toISOString(),blocks:H(s.message.content)}}))}),r.on("session_shutdown",async s=>{if(n.tuiWaitController.abort(),n.tuiGeneration++,n.stopChanged?.(),n.stopChanged=null,n.interactions?.cancelAll(),n.current=null,s.reason==="new"||s.reason==="resume"||s.reason==="fork"||s.reason==="reload")return;let o=n.bridge,l=n.telemetry;n.bridge=null,n.commandContext=null,n.replacementContext=null,n.replacementSessionId=null,n.pi=null;let u=n.workspaceSessions;n.workspaceSessions=null,await u?.dispose(),n.selected="tui",n.activeWorkspaceId=null,n.autoOpened=!1,n.tuiCatalog=null,n.stopPluginWatch?.(),n.stopPluginWatch=null,n.operation=void 0,n.telemetry=null,o?await o.close():await l?.close()});let i=async s=>{n.telemetry??=new F;try{n.current=s,n.commandContext="newSession"in s?s:null,n.pi=r,n.tuiCatalog=await z.discover(s.cwd,s.isProjectTrusted?.()??!1),n.workspaces===null&&(n.workspaces=new ce(Et(J())),await n.workspaces.load());try{await n.workspaces.discover((await Gt.listAll()).map(u=>u.cwd))}catch(u){s.ui.notify(`\u65E0\u6CD5\u8BFB\u53D6\u90E8\u5206 Pi \u5386\u53F2\u5DE5\u4F5C\u533A\uFF1A${u instanceof Error?u.message:String(u)}`,"warning")}let o=await n.workspaces.add(s.cwd);if(n.selected==="tui"&&(n.activeWorkspaceId=o.id),n.bridge&&(n.bridge.protocolVersion!==7||n.bridge.buildId!==$||typeof n.bridge.reportError!="function")){let u=n.bridge;if(n.workspaceSessions&&n.workspaceSessions.telemetryVersion!==1&&n.workspaceSessions.session&&!n.workspaceSessions.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A");n.bridge=null,await u.close(),await n.telemetry.close(),n.telemetry=new F}if(n.bridge===null){let u=n.workspaceSessions?.telemetryVersion!==1?n.workspaceSessions:null,f=u?.session&&u.path?{path:u.path,sessionManager:u.session.sessionManager}:null;u&&(await u.dispose(),n.workspaceSessions=null),n.workspaceSessions??=new fe(c=>{n.selected==="sdk"&&(n.bridge?.publish(c),c.type==="snapshot"&&c.session.idle&&L())},()=>n.current?.model,c=>{try{return!!n.current&&vn(n.current.cwd)===c&&(n.current.isProjectTrusted?.()??!1)}catch{return!1}},(c,p)=>n.bridge?.reportError?.(c,p)),f&&await n.workspaceSessions.open(f.path,{sessionManager:f.sessionManager});let y={selfUpdate:new me({agentDir:J(),packageRoot:De(Ht,"../.."),launcherNonce:process.env.PI_WEBAPP_LAUNCHER_NONCE}),snapshot:T,plugins:async()=>{let c=te();return await c?.refreshAssets(),c?.view()??{plugins:[],errors:[]}},pluginAsset:async c=>te()?.asset(c)??null,async invokePluginAction(c,p,g,m){if(A(c),!te()?.has(p))throw new Error("\u63D2\u4EF6\u672A\u542F\u7528");let k=n.selected,P=n.tuiGeneration,M=n.workspaceSessions?.session,h={requestId:In(),sessionId:c,pluginId:p,action:g,input:m},d=n.selected==="sdk"?await n.workspaceSessions.invokePluginAction(h):await de(n.pi.events,h,15e3,n.tuiWaitController.signal);if(A(c),k!==n.selected||(k==="tui"?P!==n.tuiGeneration:M!==n.workspaceSessions?.session))throw new Error("\u4F1A\u8BDD\u8FD0\u884C\u5B9E\u4F8B\u5DF2\u5207\u6362");return n.selected==="tui"&&n.current&&_(n.current),d},async resolvePluginInteraction(c,p,g,m){if(A(c),!te()?.has(p))throw new Error("\u63D2\u4EF6\u672A\u542F\u7528");n.selected==="sdk"?n.workspaceSessions.resolveInteraction(c,p,g,m):n.interactions.resolve(c,p,g,m)},image(c,p,g){A(c);let k=(n.selected==="sdk"?n.workspaceSessions?.session?.sessionManager.getBranch():n.current?.sessionManager.getBranch())?.find(M=>M.id===p);if(k?.type!=="message"||k.message.role!=="user"||!Array.isArray(k.message.content))return null;let P=k.message.content[g];return P?.type!=="image"?null:{data:Buffer.from(P.data,"base64"),mimeType:P.mimeType}},async workspaces(){return Jt()},async addWorkspace(c,p){let g=await n.workspaces.add(c,p);try{await Be(g.id,!0)}catch(m){throw await L(),m}},async selectWorkspace(c){await Be(c)},async newSessionInWorkspace(c){await Be(c,!0)},async removeWorkspace(c){if(c===n.activeWorkspaceId)throw new Error("\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A");await n.workspaces.remove(c),await L()},async selectSession(c,p,g){let m=n.workspaces?.get(c);if(!m)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(p===n.current?.sessionManager.getSessionId()&&m.path===await ve(n.current.cwd)){if(n.selected==="sdk"&&n.workspaceSessions?.session&&!n.workspaceSessions.session.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u4F1A\u8BDD");n.selected="tui",n.activeWorkspaceId=c,n.bridge?.publish({type:"snapshot",session:T()})}else{if(n.selected==="sdk"&&n.workspaceSessions?.session?.sessionManager.getSessionId()===p&&n.workspaceSessions.path===m.path)return;if(!(await Q(m.path)).some(P=>P.id===p&&P.path===g))throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");await n.workspaceSessions.open(m.path,{sessionFile:g}),n.selected="sdk",n.activeWorkspaceId=c,n.bridge?.publish({type:"snapshot",session:T()})}await L()},async models(){if(n.selected==="sdk")return n.workspaceSessions?.models()??[];let c=n.current;if(!c)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let p=c.scopedModels?.map(g=>`${g.model.provider}/${g.model.id}`)??[];return c.modelRegistry.getAvailable().filter(g=>p.length===0||p.includes(`${g.provider}/${g.id}`)).map(g=>({provider:g.provider,id:g.id,name:g.name}))},async providers(){let c=await Y(),p=new Set((await c.listCredentials()).map(g=>g.providerId));return c.getProviders().map(g=>({id:g.id,name:g.name,configured:c.getProviderAuthStatus(g.id).configured,storedCredential:p.has(g.id),methods:[g.auth.apiKey?.login?"api_key":null,g.auth.oauth?"oauth":null].filter(m=>m!==null)}))},async providerModels(c){let p=await Y();return it(he(J(),"models.json"),c,p)},async updateProviderModel(c,p,g){if(A(c),n.selected==="tui"?!D(c).isIdle():!n.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let m=T().model;if(g.action==="remove"&&m===`${p}/${g.id}`)throw new Error("\u8BF7\u5148\u5207\u6362\u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B");if(g.action==="save"&&g.originalId&&g.originalId!==g.model.id&&m===`${p}/${g.originalId}`)throw new Error("\u8BF7\u5148\u5207\u6362\u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B");let k=await Y();await nt(he(J(),"models.json"),p,g,k),await k.refresh({providers:[p],allowNetwork:!1}),await n.current?.modelRegistry.refresh({providers:[p],allowNetwork:!1}),await n.workspaceSessions?.session?.modelRuntime.refresh({providers:[p],allowNetwork:!1});let P=g.action==="save"?g.model.id:g.action==="base_url"&&m?.startsWith(`${p}/`)?m.slice(p.length+1):null;if(P&&m===`${p}/${P}`)if(n.selected==="sdk")try{await n.workspaceSessions.setModel(p,P)}catch{throw new Error("\u6A21\u578B\u5DF2\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u8BE5\u6A21\u578B\u4EE5\u5E94\u7528\u65B0\u53C2\u6570")}else{let M=D(c),h=M.modelRegistry.find(p,P);if(!h||!n.pi||!await n.pi.setModel(h))throw new Error("\u6A21\u578B\u5DF2\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u8BE5\u6A21\u578B\u4EE5\u5E94\u7528\u65B0\u53C2\u6570");_(M)}},async logoutProvider(c,p){if(A(c),n.selected==="tui"?!D(c).isIdle():!n.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let g=await Y();if(!(await g.listCredentials()).some(m=>m.providerId===p))throw new Error("\u8BE5\u63D0\u4F9B\u65B9\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u8BA4\u8BC1");await g.logout(p),await n.current?.modelRegistry.refresh({providers:[p],allowNetwork:!1}),await n.workspaceSessions?.session?.modelRuntime.refresh({providers:[p],allowNetwork:!1})},async loginProvider(c,p,g){let m=await Y();await m.login(c,p,Xe(c,p,g)),await m.refresh({providers:[c],allowNetwork:!1}),await n.current?.modelRegistry.refresh({providers:[c],allowNetwork:!1}),await n.workspaceSessions?.session?.modelRuntime.refresh({providers:[c],allowNetwork:!1})},async addCustomProvider(c,p){if(A(c),n.selected==="tui"?!D(c).isIdle():!n.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let g=await Y();if(g.getProvider(p.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");await Ze(he(J(),"models.json"),p),await g.refresh({allowNetwork:!1}),await n.current?.modelRegistry.refresh({allowNetwork:!1}),await n.workspaceSessions?.session?.modelRuntime.refresh({allowNetwork:!1})},commands(){return n.selected==="tui"?(n.pi?.getCommands()??[]).filter(c=>c.name!=="web"&&c.name!=="web-dev-reload").map(c=>({name:c.name,description:c.description})):[]},async compact(c){if(A(c),n.selected==="sdk"){let g=n.workspaceSessions?.session;if(!g||!g.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");await g.compact(),n.bridge?.publish({type:"snapshot",session:T()});return}let p=D(c);if(!p.isIdle())throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");p.compact()},async setModel(c,p,g){if(A(c),n.selected==="sdk"){await n.workspaceSessions.setModel(p,g);return}let m=D(c);if(!m.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let k=m.modelRegistry.find(p,g);if(!k||!m.modelRegistry.getAvailable().some(P=>P.provider===p&&P.id===g))throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");if(!n.pi||!await n.pi.setModel(k))throw new Error("\u6A21\u578B\u63D0\u4F9B\u65B9\u672A\u914D\u7F6E\u8BA4\u8BC1");_(m)},async setThinkingLevel(c,p){if(A(c),!["off","minimal","low","medium","high","xhigh"].includes(p))throw new Error("\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548");if(n.selected==="sdk"){let k=n.workspaceSessions?.session;if(!k||!k.isIdle||!k.getAvailableThinkingLevels().includes(p))throw new Error("\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6");k.setThinkingLevel(p),n.bridge?.publish({type:"snapshot",session:T()});return}let m=D(c);if(!m.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!m.model||!Sn(m.model).includes(p))throw new Error("\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6");if(!n.pi)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");n.pi.setThinkingLevel(p),_(m)},config:Yt,updateConfig:_n,async send(c,p,g=[],m){if(A(c),n.selected==="sdk"){await n.workspaceSessions.send(p,g,m);return}if(!D(c).isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");n.operation=m;try{if(n.bridge?.breadcrumb?.("send",{...m,piVersion:we}),n.replacementContext!==null&&n.replacementSessionId===c){await n.replacementContext.sendUserMessage(g.length?[{type:"text",text:p},...g]:p,{expandPromptTemplates:!0});return}if(n.pi===null)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");n.pi.sendUserMessage(g.length?[{type:"text",text:p},...g]:p,{expandPromptTemplates:!0})}catch(P){throw n.operation=void 0,P}},async abort(c){if(A(c),n.selected==="sdk")await n.workspaceSessions.stop();else{let p=D(c);if(p.isIdle())return;if(!n.pi)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");n.pi.appendEntry(X),p.abort()}},async resume(c){if(A(c),n.selected==="sdk"){await n.workspaceSessions.resume();return}let p=D(c);if(!p.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!p.model||!n.pi)throw new Error("\u8BF7\u5148\u9009\u62E9\u6A21\u578B");if(!p.modelRegistry.hasConfiguredAuth(p.model))throw new Error("\u8BF7\u5148\u8FDE\u63A5\u5F53\u524D\u6A21\u578B");n.pi.sendMessage(pe(T().messages),{triggerTurn:!0})},async newSession(c){if(A(c),n.selected==="sdk"){let m=n.workspaces?.get(n.activeWorkspaceId??"");if(!m)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");await n.workspaceSessions.open(m.path,"new"),await L();return}let p=D(c);if(!p.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(n.commandContext===null){await n.workspaceSessions.open(p.cwd,"new"),n.selected="sdk",n.bridge?.publish({type:"snapshot",session:T()}),await L();return}if((await n.commandContext.newSession({withSession:async m=>{n.commandContext=m,n.replacementContext=m,n.replacementSessionId=m.sessionManager.getSessionId(),n.current=m}})).cancelled)throw new Error("\u65B0\u4F1A\u8BDD\u5DF2\u53D6\u6D88");await L()}};y.addWorkspace=n.lifecycle.wrap(y.addWorkspace),y.selectWorkspace=n.lifecycle.wrap(y.selectWorkspace),y.newSessionInWorkspace=n.lifecycle.wrap(y.newSessionInWorkspace),y.removeWorkspace=n.lifecycle.wrap(y.removeWorkspace),y.selectSession=n.lifecycle.wrap(y.selectSession),y.newSession=n.lifecycle.wrap(y.newSession),y.updateConfig=n.lifecycle.wrap(y.updateConfig),n.bridge=await mt(y,Ht,n.telemetry)}if(n.stopPluginWatch===null&&process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS){let u=[],f=null;for(let y of(process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS??"").split(wn).filter(Boolean))try{u.push(bn(he(De(y),"dist"),(c,p)=>{let g=String(p??"");["client.js","client.css"].includes(g)&&(f&&clearTimeout(f),f=setTimeout(()=>n.bridge?.publish({type:"plugins_changed"}),180))}))}catch(c){n.bridge?.publish({type:"error",message:`\u63D2\u4EF6\u76D1\u542C\u5931\u8D25\uFF1A${y}: ${String(c)}`})}n.stopPluginWatch=()=>{for(let y of u)y.close();f&&clearTimeout(f)}}let l=await e(n.bridge.url).catch(()=>!1);s.ui.notify(`pi-webapp: ${n.bridge.url}`,l?"info":"warning"),s.ui.setStatus("pi-webapp","Web \u5DF2\u542F\u52A8 \xB7 /web \u91CD\u65B0\u6253\u5F00")}catch(o){throw n.telemetry?.capture(o,{stage:"open_web",piVersion:we}),n.bridge||(await n.telemetry?.close(),n.telemetry=null),o}};r.registerCommand("web",{description:"Open the current Pi session in a local web interface",handler:async(s,o)=>i(o)}),r.registerCommand("web-dev-reload",{description:"Reload local pi-webapp plugins during development",handler:async(s,o)=>{process.env.PI_WEBAPP_PLUGIN_DEV_ROOTS&&(await o.waitForIdle(),await n.lifecycle.run(async()=>{let l=n.workspaceSessions?.session;l&&(await l.waitForIdle(),await n.workspaceSessions.reload()),await o.reload()}))}})}var ra=Oe;export{ra as default};
22
22
 
23
- //# debugId=449b6114-32dc-4dde-9b3e-7a3c77caffc8
23
+ //# debugId=f1a698c3-8c0a-43a0-b699-ccd098cbfcec
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-webapp",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "A browser interface for Pi with live chat, workspaces, models, and attachments",
6
6
  "repository": {
@@ -15,7 +15,7 @@
15
15
  "pi-webapp": "./bin/pi-webapp.mjs"
16
16
  },
17
17
  "pi": {
18
- "image": "https://cdn.jsdelivr.net/npm/pi-webapp@0.1.8/assets/cover-webapp.png",
18
+ "image": "https://cdn.jsdelivr.net/npm/pi-webapp@0.1.9/assets/cover-webapp.png",
19
19
  "extensions": [
20
20
  "./dist/extension.js"
21
21
  ]
@@ -28,7 +28,7 @@
28
28
  "README.md",
29
29
  "README.zh-CN.md",
30
30
  "LICENSE",
31
- "THIRD_PARTY_LICENSE.txt",
31
+ "web/src/ui/shared/LICENSE.txt",
32
32
  "docs/sentry.md"
33
33
  ],
34
34
  "scripts": {
@@ -1,10 +1,10 @@
1
- var C=Object.defineProperty;var T=(e,t,s)=>t in e?C(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var c=(e,t,s)=>T(e,typeof t!="symbol"?t+"":t,s);(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},t=new e.Error().stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="24924569-10a6-4646-9ec7-d6a3314160ba",e._sentryDebugIdIdentifier="sentry-dbid-24924569-10a6-4646-9ec7-d6a3314160ba")}catch{}})();(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const o of a.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function s(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(i){if(i.ep)return;i.ep=!0;const a=s(i);fetch(i.href,a)}})();const B="modulepreload",O=function(e){return"/"+e},S={},$=function(t,s,r){let i=Promise.resolve();if(s&&s.length>0){let o=function(l){return Promise.all(l.map(h=>Promise.resolve(h).then(y=>({status:"fulfilled",value:y}),y=>({status:"rejected",reason:y}))))};document.getElementsByTagName("link");const n=document.querySelector("meta[property=csp-nonce]"),p=(n==null?void 0:n.nonce)||(n==null?void 0:n.getAttribute("nonce"));i=o(s.map(l=>{if(l=O(l),l in S)return;S[l]=!0;const h=l.endsWith(".css"),y=h?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${l}"]${y}`))return;const f=document.createElement("link");if(f.rel=h?"stylesheet":B,h||(f.as="script"),f.crossOrigin="",f.href=l,p&&f.setAttribute("nonce",p),document.head.appendChild(f),h)return new Promise((P,x)=>{f.addEventListener("load",P),f.addEventListener("error",()=>x(new Error(`Unable to preload CSS for ${l}`)))})}))}function a(o){const n=new Event("vite:preloadError",{cancelable:!0});if(n.payload=o,window.dispatchEvent(n),!n.defaultPrevented)throw o}return i.then(o=>{for(const n of o||[])n.status==="rejected"&&a(n.reason);return t().catch(a)})},J={userInfo:!1,cookies:!1,httpHeaders:!1,httpBodies:[],urlQueryParams:!1,genAI:{inputs:!1,outputs:!1},graphQL:{document:!1,variables:!1},databaseQueryData:!1,queues:!1,stackFrameVariables:!1,frameContextLines:0},j=new Set(["stage","route","method","status","durationMs","connection","idle","model","thinkingLevel","messageCount","attachmentCount","session","requestId","operationId","errorId","repeats","dropped","componentStack","eventType","sequence","nodeVersion","piVersion","platform","browser","buildId","code"]),D=new Set(["/api/plugins","/api/plugin-action","/api/plugin-interaction","/api/resume","/api/update","/api/update/version","/api/provider/models","/api/provider/logout","/api/provider/login/active","/api/telemetry/config","/api/image","/api/attachment","/api/attachment/remove","/api/session","/api/providers","/api/models","/api/config","/api/workspaces","/api/commands","/api/events","/api/message","/api/abort","/api/compact","/api/new-session","/api/model","/api/thinking-level","/api/provider/login","/api/provider/login/respond","/api/provider/login/cancel","/api/provider/custom","/api/workspace/add","/api/workspace/select","/api/workspace/new-session","/api/workspace/remove","/api/session/select","/api/directory/capability","/api/directory/list","/api/directory/create","/api/directory/pick"]);function K(e){return e==="/api/message"||e.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(e)}function d(e){return e.slice(0,8192).replace(/(?:Bearer\s+\S+|(?:api[_-]?key|token|password|secret|authorization)\s*[=:]\s*\S+)/gi,"[redacted]").replace(/\b(?:sk-|sntrys_|eyJ)[A-Za-z0-9_.-]+/g,"[redacted]").replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,"[email]").replace(/https?:\/\/[^\s)]+/gi,"[url]").replace(/(?:file:\/\/)?(?:\/[\w.~-]+){2,}(?::\d+(?::\d+)?)?/g,"[path]").replace(/[A-Za-z]:\\[^\s)]+/g,"[path]").replace(/(["'`])[^\n]*?\1/g,"[quoted]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function m(e){const t={};for(const s of j){const r=e[s];s==="route"&&typeof r=="string"?t[s]=D.has(r.split("?")[0])?r.split("?")[0]:"[route]":typeof r=="string"?t[s]=["requestId","operationId","errorId","session","buildId"].includes(s)&&/^[\w-]{1,80}$/.test(r)?r:d(r):(typeof r=="boolean"||typeof r=="number"&&Number.isFinite(r)||r===null)&&(t[s]=r)}return t}function k(e){var r;const t=e.replace(/\\/g,"/").split(/[?#]/)[0];return t.startsWith("node:")?t.slice(0,150):`app:///${(((r=t.match(/(?:^|\/)((?:web\/src|extension|shared|dist|assets)\/[^\s:)]+)$/))==null?void 0:r[1])??t.split("/").pop()??"unknown").replace(/[^\w./-]/g,"_").slice(-200)}`}function I(e,t=0){const s=e instanceof Error?e:new Error(typeof e=="string"?e:"Non-Error rejection"),r=new Error(d(s.message));if(r.name=d(s.name).slice(0,100),s.stack){const i=s.stack.split(`
1
+ var C=Object.defineProperty;var T=(e,t,s)=>t in e?C(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var c=(e,t,s)=>T(e,typeof t!="symbol"?t+"":t,s);(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},t=new e.Error().stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="749eda8a-cdd4-43f0-b47f-e3dc26f792a7",e._sentryDebugIdIdentifier="sentry-dbid-749eda8a-cdd4-43f0-b47f-e3dc26f792a7")}catch{}})();(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const o of a.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function s(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(i){if(i.ep)return;i.ep=!0;const a=s(i);fetch(i.href,a)}})();const B="modulepreload",O=function(e){return"/"+e},S={},$=function(t,s,r){let i=Promise.resolve();if(s&&s.length>0){let o=function(l){return Promise.all(l.map(h=>Promise.resolve(h).then(y=>({status:"fulfilled",value:y}),y=>({status:"rejected",reason:y}))))};document.getElementsByTagName("link");const n=document.querySelector("meta[property=csp-nonce]"),p=(n==null?void 0:n.nonce)||(n==null?void 0:n.getAttribute("nonce"));i=o(s.map(l=>{if(l=O(l),l in S)return;S[l]=!0;const h=l.endsWith(".css"),y=h?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${l}"]${y}`))return;const f=document.createElement("link");if(f.rel=h?"stylesheet":B,h||(f.as="script"),f.crossOrigin="",f.href=l,p&&f.setAttribute("nonce",p),document.head.appendChild(f),h)return new Promise((P,x)=>{f.addEventListener("load",P),f.addEventListener("error",()=>x(new Error(`Unable to preload CSS for ${l}`)))})}))}function a(o){const n=new Event("vite:preloadError",{cancelable:!0});if(n.payload=o,window.dispatchEvent(n),!n.defaultPrevented)throw o}return i.then(o=>{for(const n of o||[])n.status==="rejected"&&a(n.reason);return t().catch(a)})},J={userInfo:!1,cookies:!1,httpHeaders:!1,httpBodies:[],urlQueryParams:!1,genAI:{inputs:!1,outputs:!1},graphQL:{document:!1,variables:!1},databaseQueryData:!1,queues:!1,stackFrameVariables:!1,frameContextLines:0},j=new Set(["stage","route","method","status","durationMs","connection","idle","model","thinkingLevel","messageCount","attachmentCount","session","requestId","operationId","errorId","repeats","dropped","componentStack","eventType","sequence","nodeVersion","piVersion","platform","browser","buildId","code"]),D=new Set(["/api/plugins","/api/plugin-action","/api/plugin-interaction","/api/resume","/api/update","/api/update/version","/api/provider/models","/api/provider/logout","/api/provider/login/active","/api/telemetry/config","/api/image","/api/attachment","/api/attachment/remove","/api/session","/api/providers","/api/models","/api/config","/api/workspaces","/api/commands","/api/events","/api/message","/api/abort","/api/compact","/api/new-session","/api/model","/api/thinking-level","/api/provider/login","/api/provider/login/respond","/api/provider/login/cancel","/api/provider/custom","/api/workspace/add","/api/workspace/select","/api/workspace/new-session","/api/workspace/remove","/api/session/select","/api/directory/capability","/api/directory/list","/api/directory/create","/api/directory/pick"]);function K(e){return e==="/api/message"||e.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(e)}function d(e){return e.slice(0,8192).replace(/(?:Bearer\s+\S+|(?:api[_-]?key|token|password|secret|authorization)\s*[=:]\s*\S+)/gi,"[redacted]").replace(/\b(?:sk-|sntrys_|eyJ)[A-Za-z0-9_.-]+/g,"[redacted]").replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,"[email]").replace(/https?:\/\/[^\s)]+/gi,"[url]").replace(/(?:file:\/\/)?(?:\/[\w.~-]+){2,}(?::\d+(?::\d+)?)?/g,"[path]").replace(/[A-Za-z]:\\[^\s)]+/g,"[path]").replace(/(["'`])[^\n]*?\1/g,"[quoted]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function m(e){const t={};for(const s of j){const r=e[s];s==="route"&&typeof r=="string"?t[s]=D.has(r.split("?")[0])?r.split("?")[0]:"[route]":typeof r=="string"?t[s]=["requestId","operationId","errorId","session","buildId"].includes(s)&&/^[\w-]{1,80}$/.test(r)?r:d(r):(typeof r=="boolean"||typeof r=="number"&&Number.isFinite(r)||r===null)&&(t[s]=r)}return t}function k(e){var r;const t=e.replace(/\\/g,"/").split(/[?#]/)[0];return t.startsWith("node:")?t.slice(0,150):`app:///${(((r=t.match(/(?:^|\/)((?:web\/src|extension|shared|dist|assets)\/[^\s:)]+)$/))==null?void 0:r[1])??t.split("/").pop()??"unknown").replace(/[^\w./-]/g,"_").slice(-200)}`}function I(e,t=0){const s=e instanceof Error?e:new Error(typeof e=="string"?e:"Non-Error rejection"),r=new Error(d(s.message));if(r.name=d(s.name).slice(0,100),s.stack){const i=s.stack.split(`
2
2
  `).slice(1,31).map(a=>{const o=a.match(/((?:file:\/\/|https?:\/\/|\/|[A-Za-z]:\\)[^\s()]+):(\d+):(\d+)(\)?)$/);return o?`${d(a.slice(0,o.index))}${o[1]}:${o[2]}:${o[3]}${o[4]}`:d(a)});r.stack=`${r.name}: ${r.message}
3
3
  ${i.join(`
4
4
  `)}`}return t<3&&s.cause!==void 0&&(r.cause=I(s.cause,t+1)),r}function G(e,t){const s=new Error(t);return e instanceof Error&&(s.name=e.name,e.stack&&(s.stack=`${s.name}: ${t}
5
5
  ${e.stack.split(`
6
6
  `).slice(1).join(`
7
7
  `)}`)),s}function q(e){return{...e.filename?{filename:k(e.filename)}:{},...e.abs_path?{abs_path:k(e.abs_path)}:{},...e.function?{function:d(e.function)}:{},lineno:e.lineno,colno:e.colno,in_app:e.in_app}}function F(e){var t,s,r,i,a,o;return{event_id:e.event_id,timestamp:e.timestamp,platform:e.platform,level:e.level,release:e.release,dist:e.dist,environment:d(e.environment??"production"),...e.message?{message:d(e.message)}:{},exception:e.exception?{values:(t=e.exception.values)==null?void 0:t.slice(0,4).map(n=>{var p;return{type:d(n.type??"Error"),value:d(n.value??""),...n.stacktrace?{stacktrace:{frames:(p=n.stacktrace.frames)==null?void 0:p.slice(-30).map(q)}}:{},...n.mechanism?{mechanism:{type:n.mechanism.type,handled:n.mechanism.handled}}:{}}})}:void 0,tags:{side:(s=e.tags)==null?void 0:s.side,buildId:(r=e.tags)==null?void 0:r.buildId},contexts:{diagnostic:m(((i=e.contexts)==null?void 0:i.diagnostic)??{})},breadcrumbs:(a=e.breadcrumbs)==null?void 0:a.slice(-100).map(n=>({timestamp:n.timestamp,category:d(n.category??"app"),data:m(n.data??{})})),debug_meta:e.debug_meta?{images:(o=e.debug_meta.images)==null?void 0:o.slice(0,10).map(n=>({type:n.type,debug_id:n.debug_id,...n.code_file?{code_file:k(n.code_file)}:{}}))}:void 0}}function X(e,t){return t.attachments=[],F(e)}class R{constructor(){c(this,"items",[]);c(this,"bytes",0);c(this,"encoder",new TextEncoder)}add(t,s={}){const r={timestamp:Date.now()/1e3,category:d(t),data:m(s)},i=this.encoder.encode(JSON.stringify(r)).byteLength+1;for(this.items.push({item:r,size:i}),this.bytes+=i;this.items.length>100||this.bytes>64*1024-2;)this.bytes-=this.items.shift().size}snapshot(){return this.items.map(({item:t})=>t)}}class Z{constructor(){c(this,"windowAt",-1);c(this,"total",0);c(this,"seen",new Map)}take(t,s=Date.now()){(this.windowAt<0||s-this.windowAt>=6e4)&&(this.windowAt=s,this.total=0);const r=this.seen.get(t);if(r&&s-r.at<6e4){r.repeats++;return}if(!(this.total>=20))return this.total++,this.seen.size>=64&&!r&&this.seen.delete(this.seen.keys().next().value),this.seen.set(t,{at:s,repeats:0}),{repeats:(r==null?void 0:r.repeats)??0}}}const V=new Set(["会话已切换","Pi 正在运行,请等待当前回复结束","请等待当前回复结束","请等待当前回复结束再切换工作区","请等待当前回复结束再切换会话","请先切换到其他工作区","新会话已取消","已有登录正在进行","模型不可用","模型提供方未配置认证","当前模型不支持此推理强度","其他提供方的登录正在进行,请先完成或取消当前登录","当前会话没有暂停的任务","请先完成当前交互或审批","请先选择模型","请先连接当前模型","插件未启用","会话运行实例已切换","提供方已存在","文件超过 20 MB","请求内容过大","会话不属于该工作区","推理强度无效"]);function L(e){return e instanceof Error&&(e.name==="AbortError"||V.has(e.message))}class Y{constructor(t,s,r,i,a=new R){c(this,"budget",new Z);c(this,"breadcrumbs");c(this,"scopeClass");c(this,"seen",new WeakSet);c(this,"state",{});c(this,"client");c(this,"side");c(this,"buildId");this.client=t,this.side=s,this.buildId=r,this.scopeClass=i.Scope,this.breadcrumbs=a,t.addIntegration(i.linkedErrorsIntegration({limit:4}))}setState(t){this.state=m(t)}capture(t,s={},r){var i;try{if(L(t))return;if(typeof t=="object"&&t!==null){if(this.seen.has(t))return;this.seen.add(t)}const a=I(t),o=`${a.name}:${a.message}:${((i=a.stack)==null?void 0:i.split(`
8
- `)[1])??""}:${s.stage??""}`,n=this.budget.take(o);if(!n)return;const p=new this.scopeClass;p.setClient(this.client),p.setTags({side:this.side,buildId:this.buildId}),p.setContext("diagnostic",m({...this.state,...s,repeats:n.repeats}));for(const l of this.breadcrumbs.snapshot())p.addBreadcrumb(l,100);return p.captureException(a,r?{event_id:r}:void 0)}catch{return}}ignore(t){this.seen.add(t)}}function ee(e,t){return e({...t,bufferSize:20},async({body:s})=>{const r=await fetch(t.url,{method:"POST",body:s,signal:AbortSignal.timeout(3e3),credentials:"omit",referrerPolicy:"no-referrer",redirect:"error",headers:{"Content-Type":"application/x-sentry-envelope"}});return{statusCode:r.status,headers:{"x-sentry-rate-limits":r.headers.get("x-sentry-rate-limits"),"retry-after":r.headers.get("retry-after")}}})}let w;function M(){if(w!==void 0)return w;const e=location.hash.slice(1);try{w=e||sessionStorage.getItem("pi-web-token"),e&&sessionStorage.setItem("pi-web-token",e)}catch{w=e||null}return e&&history.replaceState(null,"",location.pathname),w}const N="pi-webapp@0.1.8+d80a7230908decf48708",U="d80a7230908decf48708";let u,z=!0,A=!1,_=[];const v=new WeakSet,g=new Map;let b={};function E(e,t={}){try{if(L(e))return;if(typeof e=="object"&&e!==null){if(v.has(e))return;v.add(e)}if(u)return u.capture(e,t);z&&_.length<20&&_.push({error:I(e),context:m(t)})}catch{}}function te(e){v.add(e)}function re(e,t={}){u==null||u.breadcrumbs.add(e,t)}function se(e){e.sessionId&&(g.has(e.sessionId)||(g.size>=32&&g.delete(g.keys().next().value),g.set(e.sessionId,crypto.randomUUID())),e={...e,session:g.get(e.sessionId)}),b=m({...b,...e}),u==null||u.setState(b)}function W(){A||(A=!0,window.addEventListener("error",e=>{e instanceof ErrorEvent?E(e.error??new Error(e.message),{stage:"global"}):(e.target instanceof HTMLScriptElement||e.target instanceof HTMLLinkElement)&&E(new Error("Application resource failed to load"),{stage:"resource"})},!0),window.addEventListener("unhandledrejection",e=>E(e.reason,{stage:"unhandled_rejection"})),H())}async function H(){var e;try{const t=M();if(!t)return;const s=await fetch("/api/telemetry/config",{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(1e3)});if(!s.ok)return;const r=await s.json();if(!r.enabled||!r.dsn)return;const{createBrowserReporter:i}=await $(async()=>{const{createBrowserReporter:o}=await import("./telemetry-client-BUyFe34_.js");return{createBrowserReporter:o}},[]);u=i({...r,buildId:U,release:N});const a=((e=navigator.userAgent.match(/(?:Firefox|Edg|Chrome|Version)\/[\d.]+/))==null?void 0:e[0])??"unknown";u.setState({...b,browser:a,platform:navigator.platform}),b={...b,browser:a,platform:navigator.platform};for(const o of _)u.capture(o.error,o.context)}catch{}finally{_=[],z=!1}}W();$(()=>import("./app-B2Ac56ic.js").then(e=>e.a),[]).catch(e=>E(e,{stage:"startup"}));export{Y as E,$ as _,K as a,re as b,M as c,X as d,ee as e,te as i,G as o,J as p,E as r,se as s};
8
+ `)[1])??""}:${s.stage??""}`,n=this.budget.take(o);if(!n)return;const p=new this.scopeClass;p.setClient(this.client),p.setTags({side:this.side,buildId:this.buildId}),p.setContext("diagnostic",m({...this.state,...s,repeats:n.repeats}));for(const l of this.breadcrumbs.snapshot())p.addBreadcrumb(l,100);return p.captureException(a,r?{event_id:r}:void 0)}catch{return}}ignore(t){this.seen.add(t)}}function ee(e,t){return e({...t,bufferSize:20},async({body:s})=>{const r=await fetch(t.url,{method:"POST",body:s,signal:AbortSignal.timeout(3e3),credentials:"omit",referrerPolicy:"no-referrer",redirect:"error",headers:{"Content-Type":"application/x-sentry-envelope"}});return{statusCode:r.status,headers:{"x-sentry-rate-limits":r.headers.get("x-sentry-rate-limits"),"retry-after":r.headers.get("retry-after")}}})}let w;function M(){if(w!==void 0)return w;const e=location.hash.slice(1);try{w=e||sessionStorage.getItem("pi-web-token"),e&&sessionStorage.setItem("pi-web-token",e)}catch{w=e||null}return e&&history.replaceState(null,"",location.pathname),w}const N="pi-webapp@0.1.9+4e474e01cb4c03bcacf2",U="4e474e01cb4c03bcacf2";let u,z=!0,A=!1,_=[];const v=new WeakSet,g=new Map;let b={};function E(e,t={}){try{if(L(e))return;if(typeof e=="object"&&e!==null){if(v.has(e))return;v.add(e)}if(u)return u.capture(e,t);z&&_.length<20&&_.push({error:I(e),context:m(t)})}catch{}}function te(e){v.add(e)}function re(e,t={}){u==null||u.breadcrumbs.add(e,t)}function se(e){e.sessionId&&(g.has(e.sessionId)||(g.size>=32&&g.delete(g.keys().next().value),g.set(e.sessionId,crypto.randomUUID())),e={...e,session:g.get(e.sessionId)}),b=m({...b,...e}),u==null||u.setState(b)}function W(){A||(A=!0,window.addEventListener("error",e=>{e instanceof ErrorEvent?E(e.error??new Error(e.message),{stage:"global"}):(e.target instanceof HTMLScriptElement||e.target instanceof HTMLLinkElement)&&E(new Error("Application resource failed to load"),{stage:"resource"})},!0),window.addEventListener("unhandledrejection",e=>E(e.reason,{stage:"unhandled_rejection"})),H())}async function H(){var e;try{const t=M();if(!t)return;const s=await fetch("/api/telemetry/config",{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(1e3)});if(!s.ok)return;const r=await s.json();if(!r.enabled||!r.dsn)return;const{createBrowserReporter:i}=await $(async()=>{const{createBrowserReporter:o}=await import("./telemetry-client-BUyFe34_.js");return{createBrowserReporter:o}},[]);u=i({...r,buildId:U,release:N});const a=((e=navigator.userAgent.match(/(?:Firefox|Edg|Chrome|Version)\/[\d.]+/))==null?void 0:e[0])??"unknown";u.setState({...b,browser:a,platform:navigator.platform}),b={...b,browser:a,platform:navigator.platform};for(const o of _)u.capture(o.error,o.context)}catch{}finally{_=[],z=!1}}W();$(()=>import("./app-B2Ac56ic.js").then(e=>e.a),[]).catch(e=>E(e,{stage:"startup"}));export{Y as E,$ as _,K as a,re as b,M as c,X as d,ee as e,te as i,G as o,J as p,E as r,se as s};
9
9
 
10
- //# debugId=24924569-10a6-4646-9ec7-d6a3314160ba
10
+ //# debugId=749eda8a-cdd4-43f0-b47f-e3dc26f792a7
@@ -0,0 +1,15 @@
1
+ # UI modules
2
+
3
+ `web/src/ui/` contains pi-webapp's layout, conversation, sidebar, workspace, settings, attachment, trace, icon, and theme components. `web/src/PiApp.tsx`, `web/src/PiConversation.tsx`, and `web/src/PiWorkspaceBrowser.tsx` connect these components to Pi session data.
4
+
5
+ - `conversation/`: conversation container, composer, model selection, and attachments.
6
+ - `chat/`: messages, reasoning, tool calls, and usage.
7
+ - `trajectory/`: trace table, timeline, and toolbar.
8
+ - `workspace/` and `sidebar/`: workspaces, sessions, and navigation.
9
+ - `settings/`: appearance, resources, and models.
10
+ - `primitives/` and `theme/`: shared components, icons, and theme values.
11
+ - `shared/`: docking, Markdown rendering, composer editing, and supporting presentation components; source attribution and license are kept alongside the code.
12
+
13
+ The settings dialog and appearance selector follow the existing DSH component structure. The models page adapts DSH's connected-provider list, expandable model rows, and decimal K/M capacity inputs to Pi authentication and `models.json`. Pi's own model runtime supplies the catalog and saves built-in edits as `modelOverrides`.
14
+
15
+ Edit these source files directly, then run `npm run check`, `npm run test`, and `npm run build` from the project root.
@@ -1,6 +1,3 @@
1
- DSH presentation components are derived from DeepSeek Harness, commit
2
- 477b4f420553e8a52c2fbccc464d7561b239c443.
3
-
4
1
  MIT License
5
2
 
6
3
  Copyright (c) 2026 DeepSeek
@@ -0,0 +1,25 @@
1
+ # Shared UI presentation sources
2
+
3
+ Source: DeepSeek Harness, https://github.com/deepseek-ai/deepseek-harness
4
+ Commit: 477b4f420553e8a52c2fbccc464d7561b239c443
5
+ Copyright (c) 2026 DeepSeek. MIT license: LICENSE.txt.
6
+
7
+ - `dockkit/`: `packages/client/ui-dockkit/src`. Original engine, gestures, tab strips, tab menus, floating windows and CSS. Only primitive imports and the type-only brand alias are adapted.
8
+ - `primitives/`: `packages/client/ui-primitives/src`. Original MarkdownText and its local dependency graph, tooltip, button and menu material. No Cordis or DSH server services are imported.
9
+ - `sidebar/SidebarRight.module.css`, `ExpandButton.module.css`, `locales.ts`: originals from `packages/client/ui-sidebar-right/src/client`.
10
+ - `sidebar/PanelChrome.tsx`: original glyphs/JSX extracted from `shell/SidebarRight.tsx`, with its injected service types replaced by props.
11
+ - `sidebar/labels.ts`: original projection with local type-only contracts.
12
+ - Theme CSS: original base/radius, focus, color, typography/elevation and Shiki sheets. `--dsh-content-font-size` aliases Pi's existing font preference.
13
+ - `shiki.css`: original `packages/client/ui-theme/src/styles/shiki.css`.
14
+
15
+ `../../PluginPanel.tsx` is the Pi-specific adapter. It keeps a docking controller per session, binds each tab to a plugin panel identity and localizes the original chrome. The generic start tab provides a Pi-local hint; DSH file/terminal/browser service implementations are not included. `../conversation/ConversationRoot.module.css` supplies aliases for the original DSH takeover width variables.
16
+
17
+ The full syntax highlighter adds lazy grammar chunks and KaTeX fonts. The bridge serves only the compiled asset inventory; no arbitrary filesystem paths are exposed. The plugin preview uses this original Markdown renderer; other chat messages keep their existing renderer.
18
+
19
+ CodeBlock uses DSH's original React token rendering arm for settled code too, to preserve syntax colors under Pi's strict CSP without permitting inline HTML styles.
20
+
21
+ KaTeX's generated style attributes are parsed as temporary data attributes, then assigned by the original React conversion, so even inert parsing respects that CSP. On narrow screens, exiting the automatic fullscreen preview returns to the conversation.
22
+
23
+ Host popovers reuse the same source revision: `primitives/MenuSurface.tsx` and its CSS are verbatim originals; `../chat/stat-dialog.module.css` is the original usage surface including backdrop filtering; `../conversation/MenuView.module.css` is the original command menu with only scrollbar variable names mapped to Pi. Pi command and model selectors render through `MenuSurface`, whose separate material layer preserves nested popup positioning. Sticky provider headers use DSH's menu group header fill token.
24
+
25
+ `composer/ComposerContentEditable.tsx` and `composer/claim-decor.ts` are verbatim originals from `packages/client/ui-conversation/src/client/input/editor`. `../conversation/PiComposerEditor.tsx` binds those originals to Pi's draft state with the same Lexical 0.49.0 plain text/history stack; it replaces the unstyled textarea. Input, ghost hint and placeholder CSS are copied from the original `skeleton/InputBar.module.css`. The command menu also retains original row markup (icon, localized label, alias, description, section title) from `ui-input-trigger/MenuView.tsx`; command routing and availability come from Pi's catalog and plugin declarations.