pi-webapp 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/pi-webapp.mjs CHANGED
@@ -131,26 +131,43 @@ async function serve(pi, args) {
131
131
  let runningUrl = null;
132
132
  let buffer = "";
133
133
  let killTimer;
134
+ let stopReason;
135
+ let forceStopRequested = false;
136
+ const instanceId = randomUUID();
137
+ const startedAt = performance.now();
138
+ const lifecycle = (event, fields = {}) => {
139
+ try {
140
+ console.error(JSON.stringify({ timestamp: new Date().toISOString(), event,
141
+ level: event === "pi_process_exit" && (!stopping || failed) ? "error" : "info",
142
+ instanceId, pid: process.pid, piPid: child.pid, uptimeMs: Math.round(performance.now() - startedAt), ...fields }));
143
+ } catch { /* Diagnostics must not interrupt process supervision. */ }
144
+ };
134
145
  const devWatchers = [];
135
146
  let devReloadTimer;
136
147
  let devReloadCount = 0;
137
148
  let devReloadCommand;
138
- const shutdown = () => {
149
+ const shutdown = (reason) => {
139
150
  if (stopping) return;
140
151
  stopping = true;
152
+ stopReason = reason;
153
+ lifecycle("launcher_stop_requested", { reason });
141
154
  child.stdin?.end();
142
- killTimer = setTimeout(() => child.kill("SIGTERM"), 5000);
155
+ killTimer = setTimeout(() => {
156
+ forceStopRequested = true;
157
+ lifecycle("pi_force_stop", { reason, signal: "SIGTERM" });
158
+ child.kill("SIGTERM");
159
+ }, 5000);
143
160
  killTimer.unref();
144
161
  };
145
162
  const fail = (message) => {
146
163
  if (failed || ready) return;
147
164
  failed = true;
148
165
  notifyParent({ type: "error", message });
149
- shutdown();
166
+ shutdown("startup_failure");
150
167
  };
151
168
  const startupTimer = setTimeout(() => fail(`Pi 启动超时。日志:${logPath}`), 60000);
152
169
  const stopTimer = setInterval(async () => {
153
- try { if ((await readFile(stopPath, "utf8")).trim() === nonce) shutdown(); }
170
+ try { if ((await readFile(stopPath, "utf8")).trim() === nonce) shutdown("stop_request"); }
154
171
  catch { /* No stop request. */ }
155
172
  if (stopping) return;
156
173
  try {
@@ -158,12 +175,12 @@ async function serve(pi, args) {
158
175
  const prepared = JSON.parse(await readFile(updatePath, "utf8"));
159
176
  if (request.nonce === nonce && request.launcher === prepared.launcher && existsSync(request.launcher)) {
160
177
  restartRequest = request;
161
- shutdown();
178
+ shutdown("restart_request");
162
179
  }
163
180
  } catch { /* No valid restart request. */ }
164
181
  }, 400);
165
- process.on("SIGTERM", shutdown);
166
- process.on("SIGINT", shutdown);
182
+ process.on("SIGTERM", () => shutdown("signal_sigterm"));
183
+ process.on("SIGINT", () => shutdown("signal_sigint"));
167
184
  child.stdout?.on("data", (chunk) => {
168
185
  if (failed) return;
169
186
  buffer += chunk.toString("utf8");
@@ -210,6 +227,7 @@ async function serve(pi, args) {
210
227
  if (closed || failed) return;
211
228
  ready = true;
212
229
  clearTimeout(startupTimer);
230
+ lifecycle("launcher_ready", { port: Number(url.port) });
213
231
  notifyParent({ type: "ready", pid: process.pid, url: url.href });
214
232
  for (const root of pluginRoots) {
215
233
  try {
@@ -233,8 +251,11 @@ async function serve(pi, args) {
233
251
  child.stdin?.write(JSON.stringify({ id: "list-commands", type: "get_commands" }) + "\n");
234
252
  await new Promise((resolveExit) => {
235
253
  child.once("error", (error) => { fail(`无法启动 Pi:${error.message}`); resolveExit(); });
236
- child.once("close", (code) => {
254
+ child.once("close", (code, signal) => {
237
255
  closed = true;
256
+ lifecycle("pi_process_exit", { ready, exitCode: code, signal,
257
+ reason: stopReason ?? (ready ? "unexpected_exit" : "startup_failure"), forceStopRequested,
258
+ port: runningUrl ? Number(new URL(runningUrl).port) : null });
238
259
  if (!ready) fail(`Pi 提前退出(代码 ${code ?? "未知"})。日志:${logPath}`);
239
260
  resolveExit();
240
261
  });
package/dist/extension.js CHANGED
@@ -1,9 +1,9 @@
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]="3043920c-83fe-4998-ac8b-a5bb77649c1d",r._sentryDebugIdIdentifier="sentry-dbid-3043920c-83fe-4998-ac8b-a5bb77649c1d")}catch{}})();import{delimiter as Ri,dirname as Ni,join as xe,resolve as Je}from"node:path";import{realpathSync as Wi,watch as Di}from"node:fs";import{fileURLToPath as ji}from"node:url";import{DefaultPackageManager as er,getAgentDir as q,ModelRuntime as Oi,SessionManager as tr,SettingsManager as $i,VERSION as Ie}from"@earendil-works/pi-coding-agent";import{getSupportedThinkingLevels as Bi}from"@earendil-works/pi-ai";import{randomBytes as pn,randomUUID as Re,timingSafeEqual as un}from"node:crypto";import{readFile as fn,readdir as gn}from"node:fs/promises";import{createServer as mn}from"node:http";import{join as xt}from"node:path";import{mkdir as or,opendir as ar,stat as lr}from"node:fs/promises";import{homedir as cr}from"node:os";import{basename as dr,dirname as Ye,join as Xe,posix as pr,resolve as Ze,win32 as ur}from"node:path";function Qe(r){return process.platform==="win32"?ur.isAbsolute(r)&&/^(?:[A-Za-z]:[\\/]|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)/.test(r):pr.isAbsolute(r)}function fr(r,e,t){if(r.length===t&&e.name.localeCompare(r[r.length-1].name)>=0)return!0;let n=0,s=r.length;for(;n<s;){let o=n+s>>>1;e.name.localeCompare(r[o].name)<0?s=o:n=o+1}return r.splice(n,0,e),r.length<=t?!1:(r.pop(),!0)}async function et(r){if(r!==void 0&&!Qe(r))throw new Error("\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");let e=cr(),t=Ze(r??e),n=[];for(let d=t;;d=Ye(d)){let y=Ye(d);if(n.unshift({name:y===d?d:dr(d),path:d,hidden:!1}),y===d)break}let s=[],o=!1,a=await ar(t);for await(let d of a)!d.isDirectory()&&!d.isSymbolicLink()||fr(s,{name:d.name,isDirectory:d.isDirectory(),isSymbolicLink:d.isSymbolicLink()},1001)&&(o=!0);let u=[];for(let d of s){let y=Xe(t,d.name);if(!d.isDirectory&&d.isSymbolicLink)try{if(!(await lr(y)).isDirectory())continue}catch{continue}if(u.length===1e3){o=!0;break}u.push({name:d.name,path:y,hidden:d.name.startsWith(".")})}return{path:t,home:e,crumbs:n,entries:u,truncated:o}}async function tt(r,e){if(!Qe(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=Xe(Ze(r),e);return await or(t),t}import{execFile as gr}from"node:child_process";import{accessSync as mr,constants as hr}from"node:fs";import{delimiter as wr,join as yr}from"node:path";var br=(r,e,t)=>new Promise((n,s)=>{gr(r,[...e],{encoding:"utf8",signal:t,windowsHide:!0},(o,a,u)=>{o?s(Object.assign(new Error(o.message,{cause:o}),{code:o.code,stdout:a,stderr:u})):n({stdout:a,stderr:u})})});function vr(r){for(let e of(r??"").split(wr))if(e)for(let t of["zenity","kdialog"])try{return mr(yr(e,t),hr.X_OK),!0}catch{}return!1}function rt(r=process.platform,e=process.env){return e.SSH_CONNECTION||e.SSH_TTY?"browse":r==="darwin"||r==="linux"&&(e.DISPLAY||e.WAYLAND_DISPLAY)&&vr(e.PATH)?"native":"browse"}function ce(r){if(!(typeof r!="object"||r===null||!("code"in r)))return typeof r.code=="string"||typeof r.code=="number"?r.code:void 0}function kr(r){return typeof r=="object"&&r!==null&&"stderr"in r&&typeof r.stderr=="string"?r.stderr:""}function _e(r){return r.replace(/[\r\n]+$/,"")||null}async function nt(r,e=process.platform,t=br){if(e==="darwin")try{let n=await t("osascript",["-e",'set selectedFolder to choose folder with prompt "Select Workspace Directory"',"-e","POSIX path of selectedFolder"],r);return _e(n.stdout)}catch(n){if(!r.aborted&&ce(n)===1&&/(?:User canceled|-128)/i.test(kr(n)))return null;throw n}if(e==="linux"){try{return _e((await t("zenity",["--file-selection","--directory","--title=Select Workspace Directory"],r)).stdout)}catch(n){if(r.aborted)throw n;if(ce(n)===1)return null;if(ce(n)!=="ENOENT")throw n}try{return _e((await t("kdialog",["--getexistingdirectory",".","--title","Select Workspace Directory"],r)).stdout)}catch(n){if(r.aborted)throw n;if(ce(n)===1)return null;throw n}}throw new Error(`\u5F53\u524D\u7CFB\u7EDF\u4E0D\u652F\u6301\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\uFF1A${e}`)}import{createHash as Er,randomUUID as Pr}from"node:crypto";import{mkdir as xr,readFile as Ir,writeFile as Sr}from"node:fs/promises";import{join as it}from"node:path";import{getAgentDir as Cr}from"@earendil-works/pi-coding-agent";var de=20*1024*1024,st=20,_r=/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu;function Tr(r){let e=r.indexOf("."),t=(e<0?r:r.slice(0,e)).replace(/[. ]+$/u,"");return _r.test(t)}function Ar(r,e){let t=0,n="";for(let s of Buffer.from(r).toString("utf8")){let o=Buffer.byteLength(s);if(t+o>e)break;n+=s,t+=o}return n}function Mr(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 Tr(t)&&(t=`_${t}`),t=Ar(t,255).replace(/[. ]+$/u,""),t===""||t==="."||t===".."?"file":t}function Rr(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 ot(r,e,t,n){if(n.byteLength===0||n.byteLength>de)throw new Error("\u6587\u4EF6\u4E3A\u7A7A\u6216\u8D85\u8FC7 20 MB");let s=Mr(e),o=Er("sha256").update(n).digest("hex"),a=it(Cr(),"pi-web","attachments",o);await xr(a,{recursive:!0});let u=it(a,s);try{await Sr(u,n,{flag:"wx",mode:384})}catch(d){if(!(d instanceof Error&&"code"in d&&d.code==="EEXIST"))throw d}return{id:Pr(),name:s,bytes:n.byteLength,path:u,mediaType:Rr(n)??t.replace(/^image\//,"application/"),sessionId:r}}async function at(r){return{type:"image",data:(await Ir(r.path)).toString("base64"),mimeType:r.mediaType}}import{randomBytes as Nr}from"node:crypto";function lt(r,e,t){return r!=="openai-codex"||e!=="oauth"?t:{...t,prompt:n=>n.type==="select"&&n.options.some(s=>s.id==="browser")&&n.options.some(s=>s.id==="device_code")?Promise.resolve("browser"):t.prompt(n)}}var pe=class{flows=new Map;reportError;constructor(e=()=>{}){this.reportError=e}start(e,t,n,s,o){let a=this.getActive();if(a){if(a.providerId===e&&a.method===t&&s===void 0)return a;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=Nr(18).toString("base64url"),d={view:{id:u,providerId:e,method:t,status:"running"},controller:new AbortController};return this.flows.set(u,d),n(e,t,{signal:d.controller.signal,notify:y=>{d.view={...d.view,event:y,...y.type==="auth_url"||y.type==="device_code"?{authorization:y}:{}}},prompt:y=>{if(y.type==="secret"&&s!==void 0){let h=s;return s=void 0,Promise.resolve(h)}return new Promise((h,c)=>{let{signal:p,...g}=y;d.answer=h,d.reject=c,d.view={...d.view,status:"waiting",prompt:g},p?.aborted?c(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")):p?.addEventListener("abort",()=>c(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")),{once:!0})})}}).then(()=>{d.view.status!=="cancelled"&&(d.view={id:u,providerId:e,method:t,status:"done"})}).catch(y=>{if(d.view.status!=="cancelled"){let h=new Error("Provider login failed");y instanceof Error&&y.stack&&(h.stack=`${h.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]="04e37c1f-8757-4953-a834-c0cc5f374c80",r._sentryDebugIdIdentifier="sentry-dbid-04e37c1f-8757-4953-a834-c0cc5f374c80")}catch{}})();import{delimiter as Ri,dirname as Ni,join as xe,resolve as Je}from"node:path";import{realpathSync as Wi,watch as Di}from"node:fs";import{fileURLToPath as ji}from"node:url";import{DefaultPackageManager as er,getAgentDir as q,ModelRuntime as Oi,SessionManager as tr,SettingsManager as $i,VERSION as Ie}from"@earendil-works/pi-coding-agent";import{getSupportedThinkingLevels as Bi}from"@earendil-works/pi-ai";import{randomBytes as pn,randomUUID as Re,timingSafeEqual as un}from"node:crypto";import{readFile as fn,readdir as gn}from"node:fs/promises";import{createServer as mn}from"node:http";import{join as xt}from"node:path";import{mkdir as or,opendir as ar,stat as lr}from"node:fs/promises";import{homedir as cr}from"node:os";import{basename as dr,dirname as Ye,join as Xe,posix as pr,resolve as Ze,win32 as ur}from"node:path";function Qe(r){return process.platform==="win32"?ur.isAbsolute(r)&&/^(?:[A-Za-z]:[\\/]|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)/.test(r):pr.isAbsolute(r)}function fr(r,e,t){if(r.length===t&&e.name.localeCompare(r[r.length-1].name)>=0)return!0;let n=0,s=r.length;for(;n<s;){let o=n+s>>>1;e.name.localeCompare(r[o].name)<0?s=o:n=o+1}return r.splice(n,0,e),r.length<=t?!1:(r.pop(),!0)}async function et(r){if(r!==void 0&&!Qe(r))throw new Error("\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");let e=cr(),t=Ze(r??e),n=[];for(let d=t;;d=Ye(d)){let y=Ye(d);if(n.unshift({name:y===d?d:dr(d),path:d,hidden:!1}),y===d)break}let s=[],o=!1,a=await ar(t);for await(let d of a)!d.isDirectory()&&!d.isSymbolicLink()||fr(s,{name:d.name,isDirectory:d.isDirectory(),isSymbolicLink:d.isSymbolicLink()},1001)&&(o=!0);let u=[];for(let d of s){let y=Xe(t,d.name);if(!d.isDirectory&&d.isSymbolicLink)try{if(!(await lr(y)).isDirectory())continue}catch{continue}if(u.length===1e3){o=!0;break}u.push({name:d.name,path:y,hidden:d.name.startsWith(".")})}return{path:t,home:e,crumbs:n,entries:u,truncated:o}}async function tt(r,e){if(!Qe(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=Xe(Ze(r),e);return await or(t),t}import{execFile as gr}from"node:child_process";import{accessSync as mr,constants as hr}from"node:fs";import{delimiter as wr,join as yr}from"node:path";var br=(r,e,t)=>new Promise((n,s)=>{gr(r,[...e],{encoding:"utf8",signal:t,windowsHide:!0},(o,a,u)=>{o?s(Object.assign(new Error(o.message,{cause:o}),{code:o.code,stdout:a,stderr:u})):n({stdout:a,stderr:u})})});function vr(r){for(let e of(r??"").split(wr))if(e)for(let t of["zenity","kdialog"])try{return mr(yr(e,t),hr.X_OK),!0}catch{}return!1}function rt(r=process.platform,e=process.env){return e.SSH_CONNECTION||e.SSH_TTY?"browse":r==="darwin"||r==="linux"&&(e.DISPLAY||e.WAYLAND_DISPLAY)&&vr(e.PATH)?"native":"browse"}function ce(r){if(!(typeof r!="object"||r===null||!("code"in r)))return typeof r.code=="string"||typeof r.code=="number"?r.code:void 0}function kr(r){return typeof r=="object"&&r!==null&&"stderr"in r&&typeof r.stderr=="string"?r.stderr:""}function _e(r){return r.replace(/[\r\n]+$/,"")||null}async function nt(r,e=process.platform,t=br){if(e==="darwin")try{let n=await t("osascript",["-e",'set selectedFolder to choose folder with prompt "Select Workspace Directory"',"-e","POSIX path of selectedFolder"],r);return _e(n.stdout)}catch(n){if(!r.aborted&&ce(n)===1&&/(?:User canceled|-128)/i.test(kr(n)))return null;throw n}if(e==="linux"){try{return _e((await t("zenity",["--file-selection","--directory","--title=Select Workspace Directory"],r)).stdout)}catch(n){if(r.aborted)throw n;if(ce(n)===1)return null;if(ce(n)!=="ENOENT")throw n}try{return _e((await t("kdialog",["--getexistingdirectory",".","--title","Select Workspace Directory"],r)).stdout)}catch(n){if(r.aborted)throw n;if(ce(n)===1)return null;throw n}}throw new Error(`\u5F53\u524D\u7CFB\u7EDF\u4E0D\u652F\u6301\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\uFF1A${e}`)}import{createHash as Er,randomUUID as Pr}from"node:crypto";import{mkdir as xr,readFile as Ir,writeFile as Sr}from"node:fs/promises";import{join as it}from"node:path";import{getAgentDir as Cr}from"@earendil-works/pi-coding-agent";var de=20*1024*1024,st=20,_r=/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu;function Tr(r){let e=r.indexOf("."),t=(e<0?r:r.slice(0,e)).replace(/[. ]+$/u,"");return _r.test(t)}function Ar(r,e){let t=0,n="";for(let s of Buffer.from(r).toString("utf8")){let o=Buffer.byteLength(s);if(t+o>e)break;n+=s,t+=o}return n}function Mr(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 Tr(t)&&(t=`_${t}`),t=Ar(t,255).replace(/[. ]+$/u,""),t===""||t==="."||t===".."?"file":t}function Rr(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 ot(r,e,t,n){if(n.byteLength===0||n.byteLength>de)throw new Error("\u6587\u4EF6\u4E3A\u7A7A\u6216\u8D85\u8FC7 20 MB");let s=Mr(e),o=Er("sha256").update(n).digest("hex"),a=it(Cr(),"pi-web","attachments",o);await xr(a,{recursive:!0});let u=it(a,s);try{await Sr(u,n,{flag:"wx",mode:384})}catch(d){if(!(d instanceof Error&&"code"in d&&d.code==="EEXIST"))throw d}return{id:Pr(),name:s,bytes:n.byteLength,path:u,mediaType:Rr(n)??t.replace(/^image\//,"application/"),sessionId:r}}async function at(r){return{type:"image",data:(await Ir(r.path)).toString("base64"),mimeType:r.mediaType}}import{randomBytes as Nr}from"node:crypto";function lt(r,e,t){return r!=="openai-codex"||e!=="oauth"?t:{...t,prompt:n=>n.type==="select"&&n.options.some(s=>s.id==="browser")&&n.options.some(s=>s.id==="device_code")?Promise.resolve("browser"):t.prompt(n)}}var pe=class{flows=new Map;reportError;constructor(e=()=>{}){this.reportError=e}start(e,t,n,s,o){let a=this.getActive();if(a){if(a.providerId===e&&a.method===t&&s===void 0)return a;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=Nr(18).toString("base64url"),d={view:{id:u,providerId:e,method:t,status:"running"},controller:new AbortController};return this.flows.set(u,d),n(e,t,{signal:d.controller.signal,notify:y=>{d.view={...d.view,event:y,...y.type==="auth_url"||y.type==="device_code"?{authorization:y}:{}}},prompt:y=>{if(y.type==="secret"&&s!==void 0){let h=s;return s=void 0,Promise.resolve(h)}return new Promise((h,c)=>{let{signal:p,...g}=y;d.answer=h,d.reject=c,d.view={...d.view,status:"waiting",prompt:g},p?.aborted?c(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")):p?.addEventListener("abort",()=>c(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")),{once:!0})})}}).then(()=>{d.view.status!=="cancelled"&&(d.view={id:u,providerId:e,method:t,status:"done"})}).catch(y=>{if(d.view.status!=="cancelled"){let h=new Error("Provider login failed");y instanceof Error&&y.stack&&(h.stack=`${h.message}
2
2
  ${y.stack.split(`
3
3
  `).slice(1).join(`
4
4
  `)}`);let c=this.reportError(h,{...o,stage:"provider_login"});d.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:c}}}),{...d.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 n=this.flows.get(e);if(!n?.answer||n.view.status!=="waiting"||n.view.prompt?.type==="select"&&!n.view.prompt.options.some(o=>o.id===t))return!1;let s=n.answer;return n.answer=void 0,n.reject=void 0,n.view={...n.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 Wr}from"node:crypto";import{readFile as Dr,rename as jr,rm as Or,stat as $r,writeFile as Br,mkdir as Fr}from"node:fs/promises";import{dirname as Lr}from"node:path";var Vr=["openai-completions","openai-responses","anthropic-messages"];function Te(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||!Vr.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 ct(r,e){if(!Te(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 Dr(r,"utf8")}catch(u){if(u.code!=="ENOENT")throw u}let n;if(t===void 0)n={providers:{}};else{try{n=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(!n||typeof n!="object"||!n.providers||typeof n.providers!="object"||Array.isArray(n.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548")}if(Object.hasOwn(n.providers,e.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");let s={...n,providers:{...n.providers,[e.id]:{name:e.name.trim(),baseUrl:e.baseUrl,api:e.api,models:[{id:e.modelId.trim()}]}}};await Fr(Lr(r),{recursive:!0});let o=t===void 0?384:(await $r(r)).mode&511,a=`${r}.pi-web-${Wr(6).toString("hex")}.tmp`;try{await Br(a,`${JSON.stringify(s,null,2)}
5
5
  `,{mode:o,flag:"wx"}),await jr(a,r)}finally{await Or(a,{force:!0})}}import{randomBytes as Ur}from"node:crypto";import{mkdir as zr,readFile as Hr,rename as Kr,rm as Gr,stat as Jr,writeFile as qr}from"node:fs/promises";import{dirname as Yr}from"node:path";function dt(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 pt(r){if(!r||typeof r!="object")return!1;let e=r;return e.action==="save"?(e.originalId===void 0||typeof e.originalId=="string")&&ut(e.model):e.action==="base_url"?e.baseUrl===null||typeof e.baseUrl=="string"&&dt(e.baseUrl):e.action==="remove"&&typeof e.id=="string"&&e.id.length>0&&e.id.length<=200}function ut(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 ft(r){let e;try{e=await Hr(r,"utf8")}catch(n){if(n.code!=="ENOENT")throw n}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 Xr(r,e,t){await zr(Yr(r),{recursive:!0});let n=t===void 0?384:(await Jr(r)).mode&511,s=`${r}.pi-web-${Ur(6).toString("hex")}.tmp`;try{await qr(s,`${JSON.stringify(e,null,2)}
6
- `,{mode:n,flag:"wx"}),await Kr(s,r)}finally{await Gr(s,{force:!0})}}async function gt(r,e,t){if(!t.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:n}=await ft(r),s=n.providers[e],o=new Set(s?.models?.map(a=>a.id)??[]);return{providerId:e,baseUrl:s?.baseUrl,models:t.getModels(e).map(a=>({id:a.id,name:a.name,contextWindow:a.contextWindow,maxTokens:a.maxTokens,input:[...a.input],source:o.has(a.id)?"custom":"builtin",overridden:!!s?.modelOverrides?.[a.id]}))}}async function mt(r,e,t,n){if(!n.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:s,existing:o}=await ft(r),a={...s.providers[e]??{}},u=[...a.models??[]],d={...a.modelOverrides??{}};if(t.action==="base_url"){if(t.baseUrl!==null&&!dt(t.baseUrl))throw new Error("API \u5730\u5740\u65E0\u6548");t.baseUrl===null?delete a.baseUrl:a.baseUrl=t.baseUrl}else if(t.action==="save"){if(!ut(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}},h=t.originalId,c=h===void 0?-1:u.findIndex(p=>p.id===h);if(h===void 0&&(u.some(p=>p.id===y.id)||n.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");if(c>=0){if(y.id!==h&&(u.some(g=>g.id===y.id)||n.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");let p={...u[c],...y};for(let g of["name","contextWindow","maxTokens","input"])y[g]===void 0&&delete p[g];u[c]=p}else if(h!==void 0&&n.getModel(e,h)){if(y.id!==h)throw new Error("\u5185\u7F6E\u6A21\u578B ID \u4E0D\u53EF\u4FEE\u6539");let{id:p,...g}=y;d[h]={...d[h],...g};for(let m of["name","contextWindow","maxTokens","input"])y[m]===void 0&&delete d[h][m]}else{if(h!==void 0)throw new Error("\u6A21\u578B\u4E0D\u5B58\u5728");u.push(y)}}else{let y=u.findIndex(h=>h.id===t.id);if(y>=0)u.splice(y,1);else if(Object.hasOwn(d,t.id))delete d[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?a.models=u:delete a.models,Object.keys(d).length?a.modelOverrides=d:delete a.modelOverrides,Object.keys(a).length?s.providers[e]=a:delete s.providers[e],await Xr(r,s,o)}function ht(r){return/^(?:npm:|git:|https?:\/\/|ssh:\/\/|git@)/i.test(r.trim())}import{randomBytes as Et,createHash as sn}from"node:crypto";import{fileURLToPath as on}from"node:url";var ue="pi-webapp@0.1.12+17af25c649a02416e3a0",B="17af25c649a02416e3a0";var ge=new Set(["bash","powershell","read","write","edit","grep","find","ls"]),Zr=new Set(["cancelled","blocked","validation","not_found","permission","timeout","process_exit","unknown"]),wt={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},Qr=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","toolName","toolId","toolCallId","failureKind","errorCode","exitCode","timeoutMs","diagnosticSource","originalStackAvailable","errorSummary","summaryOmitted","summaryOmittedReason","level"]),en=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 yt(r){return r==="/api/message"||r.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(r)}function W(r){return r.slice(0,8192).replace(/-----BEGIN [^-\n]+-----[\s\S]*?(?:-----END [^-\n]+-----|$)/g,"[redacted]").replace(/(["'`])[\s\S]*?\1/g,"[quoted]").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(/(?:^|\s)(?:\.\.?[\\/]|~[\\/])[^\s)]+/g," [path]").replace(/\b(?:[\w.-]+[\\/])+[\w.-]+/g,"[path]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function $(r){let e={};for(let t of Qr){let n=r[t];t==="toolName"?typeof n=="string"&&(ge.has(n)||n==="custom")&&(e[t]=n):t==="failureKind"?Zr.has(n)&&(e[t]=n):t==="level"?(n==="warning"||n==="error")&&(e[t]=n):t==="diagnosticSource"?(n==="tool_execution_end"||n==="message_end")&&(e[t]=n):t==="errorCode"?typeof n=="string"&&/^(?:E[A-Z0-9]{1,20}|nonzero_exit|timeout|cancelled|blocked|invalid_arguments|tool_not_found|unknown)$/.test(n)&&(e[t]=n):t==="toolId"?typeof n=="string"&&/^[a-f0-9]{16}$/.test(n)&&(e[t]=n):t==="route"&&typeof n=="string"?e[t]=en.has(n.split("?")[0])?n.split("?")[0]:"[route]":t==="model"&&typeof n=="string"&&/^[\w.-]+\/[\w.-]+$/.test(n)?e[t]=n.split("/").map(W).join("/"):typeof n=="string"?e[t]=["requestId","operationId","errorId","session","buildId","toolId","toolCallId"].includes(t)&&/^[\w-]{1,80}$/.test(n)?n:W(n).slice(0,t==="errorSummary"?512:1024):(typeof n=="boolean"||typeof n=="number"&&Number.isFinite(n)||n===null)&&(e[t]=n)}return e}function Ae(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 Y(r,e=0){let t=r instanceof Error?r:new Error(typeof r=="string"?r:"Non-Error rejection"),n=new Error(W(t.message));if(n.name=W(t.name).slice(0,100),t.stack){let s=t.stack.split(`
6
+ `,{mode:n,flag:"wx"}),await Kr(s,r)}finally{await Gr(s,{force:!0})}}async function gt(r,e,t){if(!t.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:n}=await ft(r),s=n.providers[e],o=new Set(s?.models?.map(a=>a.id)??[]);return{providerId:e,baseUrl:s?.baseUrl,models:t.getModels(e).map(a=>({id:a.id,name:a.name,contextWindow:a.contextWindow,maxTokens:a.maxTokens,input:[...a.input],source:o.has(a.id)?"custom":"builtin",overridden:!!s?.modelOverrides?.[a.id]}))}}async function mt(r,e,t,n){if(!n.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:s,existing:o}=await ft(r),a={...s.providers[e]??{}},u=[...a.models??[]],d={...a.modelOverrides??{}};if(t.action==="base_url"){if(t.baseUrl!==null&&!dt(t.baseUrl))throw new Error("API \u5730\u5740\u65E0\u6548");t.baseUrl===null?delete a.baseUrl:a.baseUrl=t.baseUrl}else if(t.action==="save"){if(!ut(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}},h=t.originalId,c=h===void 0?-1:u.findIndex(p=>p.id===h);if(h===void 0&&(u.some(p=>p.id===y.id)||n.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");if(c>=0){if(y.id!==h&&(u.some(g=>g.id===y.id)||n.getModel(e,y.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");let p={...u[c],...y};for(let g of["name","contextWindow","maxTokens","input"])y[g]===void 0&&delete p[g];u[c]=p}else if(h!==void 0&&n.getModel(e,h)){if(y.id!==h)throw new Error("\u5185\u7F6E\u6A21\u578B ID \u4E0D\u53EF\u4FEE\u6539");let{id:p,...g}=y;d[h]={...d[h],...g};for(let m of["name","contextWindow","maxTokens","input"])y[m]===void 0&&delete d[h][m]}else{if(h!==void 0)throw new Error("\u6A21\u578B\u4E0D\u5B58\u5728");u.push(y)}}else{let y=u.findIndex(h=>h.id===t.id);if(y>=0)u.splice(y,1);else if(Object.hasOwn(d,t.id))delete d[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?a.models=u:delete a.models,Object.keys(d).length?a.modelOverrides=d:delete a.modelOverrides,Object.keys(a).length?s.providers[e]=a:delete s.providers[e],await Xr(r,s,o)}function ht(r){return/^(?:npm:|git:|https?:\/\/|ssh:\/\/|git@)/i.test(r.trim())}import{randomBytes as Et,createHash as sn}from"node:crypto";import{fileURLToPath as on}from"node:url";var ue="pi-webapp@0.1.13+47b0cab9b46d97bbc98c",B="47b0cab9b46d97bbc98c";var ge=new Set(["bash","powershell","read","write","edit","grep","find","ls"]),Zr=new Set(["cancelled","blocked","validation","not_found","permission","timeout","process_exit","unknown"]),wt={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},Qr=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","toolName","toolId","toolCallId","failureKind","errorCode","exitCode","timeoutMs","diagnosticSource","originalStackAvailable","errorSummary","summaryOmitted","summaryOmittedReason","level"]),en=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 yt(r){return r==="/api/message"||r.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(r)}function W(r){return r.slice(0,8192).replace(/-----BEGIN [^-\n]+-----[\s\S]*?(?:-----END [^-\n]+-----|$)/g,"[redacted]").replace(/(["'`])[\s\S]*?\1/g,"[quoted]").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(/(?:^|\s)(?:\.\.?[\\/]|~[\\/])[^\s)]+/g," [path]").replace(/\b(?:[\w.-]+[\\/])+[\w.-]+/g,"[path]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function $(r){let e={};for(let t of Qr){let n=r[t];t==="toolName"?typeof n=="string"&&(ge.has(n)||n==="custom")&&(e[t]=n):t==="failureKind"?Zr.has(n)&&(e[t]=n):t==="level"?(n==="warning"||n==="error")&&(e[t]=n):t==="diagnosticSource"?(n==="tool_execution_end"||n==="message_end")&&(e[t]=n):t==="errorCode"?typeof n=="string"&&/^(?:E[A-Z0-9]{1,20}|nonzero_exit|timeout|cancelled|blocked|invalid_arguments|tool_not_found|unknown)$/.test(n)&&(e[t]=n):t==="toolId"?typeof n=="string"&&/^[a-f0-9]{16}$/.test(n)&&(e[t]=n):t==="route"&&typeof n=="string"?e[t]=en.has(n.split("?")[0])?n.split("?")[0]:"[route]":t==="model"&&typeof n=="string"&&/^[\w.-]+\/[\w.-]+$/.test(n)?e[t]=n.split("/").map(W).join("/"):typeof n=="string"?e[t]=["requestId","operationId","errorId","session","buildId","toolId","toolCallId"].includes(t)&&/^[\w-]{1,80}$/.test(n)?n:W(n).slice(0,t==="errorSummary"?512:1024):(typeof n=="boolean"||typeof n=="number"&&Number.isFinite(n)||n===null)&&(e[t]=n)}return e}function Ae(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 Y(r,e=0){let t=r instanceof Error?r:new Error(typeof r=="string"?r:"Non-Error rejection"),n=new Error(W(t.message));if(n.name=W(t.name).slice(0,100),t.stack){let s=t.stack.split(`
7
7
  `).slice(1,31).map(o=>{let a=o.match(/((?:file:\/\/|https?:\/\/|\/|[A-Za-z]:\\)[^\s()]+):(\d+):(\d+)(\)?)$/);return a?`${W(o.slice(0,a.index))}${a[1]}:${a[2]}:${a[3]}${a[4]}`:W(o)});n.stack=`${n.name}: ${n.message}
8
8
  ${s.join(`
9
9
  `)}`}else n.stack=void 0;return e<3&&t.cause!==void 0&&(n.cause=Y(t.cause,e+1)),n}function te(r,e){let t=new Error(e);return r instanceof Error&&(t.name=r.name,r.stack&&(t.stack=`${t.name}: ${e}
package/docs/sentry.md CHANGED
@@ -55,6 +55,10 @@ Filter Sentry by `side:node`, `toolName`, `failureKind` and `errorCode`, then in
55
55
 
56
56
  ## Performance and reliability
57
57
 
58
+ The background launcher's local `launcher.log` records JSON lifecycle events: `launcher_ready`, `launcher_stop_requested`, `pi_force_stop`, and `pi_process_exit`. The default location is `~/.pi/agent/pi-web/launcher.log` (`%USERPROFILE%\.pi\agent\pi-web\launcher.log` on Windows); `PI_CODING_AGENT_DIR` overrides the agent directory. These records are local diagnostics, not Sentry events.
59
+
60
+ Each run has a separate random `instanceId`, UTC `timestamp`, process IDs, and monotonic `uptimeMs`. Readiness and exit include the listening port without the URL or access token. Exit records include `ready`, `exitCode`, `signal`, `forceStopRequested`, and a reason: `unexpected_exit`, `stop_request`, `restart_request`, `signal_sigterm`, `signal_sigint`, or `startup_failure`. Use the instance ID and timestamps to distinguish an unexpected Pi exit from a requested stop or upgrade; a stop request does not prove which cause ultimately terminated the process, so inspect the exit code and signal as well. The correlation ID is independent of the launcher control nonce. These lifecycle records omit arguments, paths, credentials, and arbitrary child output. If the launcher itself is forcibly terminated, it may not be able to record the child's exit.
61
+
58
62
  After an accepted update, browser version polling retains temporary network failures as `request_failed` breadcrumbs while waiting for the restarted service. If the target version is still unavailable after 60 seconds, it stops polling and reports one `stage=update_restart`, `code=update_restart_timeout` error, even if a request is still pending. Closing settings cancels the pending request and deadline. HTTP and response parsing failures, and network failures from other requests, retain normal reporting.
59
63
 
60
64
  Each side sends at most 20 events/minute and one event per fingerprint/minute. Repetition counts appear on the next retained event. Startup and transport queues are bounded to 20 events. Transport requests time out after 3 seconds, do not persist offline, and do not retry indefinitely. Rate-limited/dropped events are intentionally lossy. Browser configuration has a 1-second timeout and never gates rendering; SDKs load only when reporting is enabled. No tracing, profiling, automatic console/DOM instrumentation or token-by-token logging is enabled.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-webapp",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
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.12/assets/cover-webapp.png",
18
+ "image": "https://cdn.jsdelivr.net/npm/pi-webapp@0.1.13/assets/cover-webapp.png",
19
19
  "extensions": [
20
20
  "./dist/extension.js"
21
21
  ]
@@ -1,8 +1,8 @@
1
- var O=Object.defineProperty;var B=(e,t,i)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var d=(e,t,i)=>B(e,typeof t!="symbol"?t+"":t,i);(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]="1a9feef9-fa2b-4a78-82e2-078b59ad53c5",e._sentryDebugIdIdentifier="sentry-dbid-1a9feef9-fa2b-4a78-82e2-078b59ad53c5")}catch{}})();(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const a of n.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function i(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=i(s);fetch(s.href,n)}})();const x="modulepreload",j=function(e){return"/"+e},I={},A=function(t,i,r){let s=Promise.resolve();if(i&&i.length>0){let a=function(o){return Promise.all(o.map(c=>Promise.resolve(c).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const l=document.querySelector("meta[property=csp-nonce]"),m=(l==null?void 0:l.nonce)||(l==null?void 0:l.getAttribute("nonce"));s=a(i.map(o=>{if(o=j(o),o in I)return;I[o]=!0;const c=o.endsWith(".css"),g=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${g}`))return;const f=document.createElement("link");if(f.rel=c?"stylesheet":x,c||(f.as="script"),f.crossOrigin="",f.href=o,m&&f.setAttribute("nonce",m),document.head.appendChild(f),c)return new Promise((T,N)=>{f.addEventListener("load",T),f.addEventListener("error",()=>N(new Error(`Unable to preload CSS for ${o}`)))})}))}function n(a){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=a,window.dispatchEvent(l),!l.defaultPrevented)throw a}return s.then(a=>{for(const l of a||[])l.status==="rejected"&&n(l.reason);return t().catch(n)})},D=new Set(["bash","powershell","read","write","edit","grep","find","ls"]),q=new Set(["cancelled","blocked","validation","not_found","permission","timeout","process_exit","unknown"]),Y={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},F=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","toolName","toolId","toolCallId","failureKind","errorCode","exitCode","timeoutMs","diagnosticSource","originalStackAvailable","errorSummary","summaryOmitted","summaryOmittedReason","level"]),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 ee(e){return e==="/api/message"||e.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(e)}function p(e){return e.slice(0,8192).replace(/-----BEGIN [^-\n]+-----[\s\S]*?(?:-----END [^-\n]+-----|$)/g,"[redacted]").replace(/(["'`])[\s\S]*?\1/g,"[quoted]").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(/(?:^|\s)(?:\.\.?[\\/]|~[\\/])[^\s)]+/g," [path]").replace(/\b(?:[\w.-]+[\\/])+[\w.-]+/g,"[path]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function h(e){const t={};for(const i of F){const r=e[i];i==="toolName"?typeof r=="string"&&(D.has(r)||r==="custom")&&(t[i]=r):i==="failureKind"?q.has(r)&&(t[i]=r):i==="level"?(r==="warning"||r==="error")&&(t[i]=r):i==="diagnosticSource"?(r==="tool_execution_end"||r==="message_end")&&(t[i]=r):i==="errorCode"?typeof r=="string"&&/^(?:E[A-Z0-9]{1,20}|nonzero_exit|timeout|cancelled|blocked|invalid_arguments|tool_not_found|unknown)$/.test(r)&&(t[i]=r):i==="toolId"?typeof r=="string"&&/^[a-f0-9]{16}$/.test(r)&&(t[i]=r):i==="route"&&typeof r=="string"?t[i]=R.has(r.split("?")[0])?r.split("?")[0]:"[route]":i==="model"&&typeof r=="string"&&/^[\w.-]+\/[\w.-]+$/.test(r)?t[i]=r.split("/").map(p).join("/"):typeof r=="string"?t[i]=["requestId","operationId","errorId","session","buildId","toolId","toolCallId"].includes(i)&&/^[\w-]{1,80}$/.test(r)?r:p(r).slice(0,i==="errorSummary"?512:1024):(typeof r=="boolean"||typeof r=="number"&&Number.isFinite(r)||r===null)&&(t[i]=r)}return t}function E(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 S(e,t=0){const i=e instanceof Error?e:new Error(typeof e=="string"?e:"Non-Error rejection"),r=new Error(p(i.message));if(r.name=p(i.name).slice(0,100),i.stack){const s=i.stack.split(`
1
+ var O=Object.defineProperty;var B=(e,t,i)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var d=(e,t,i)=>B(e,typeof t!="symbol"?t+"":t,i);(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]="e8ca6826-5cde-4082-9c73-e69cc3ddc9d9",e._sentryDebugIdIdentifier="sentry-dbid-e8ca6826-5cde-4082-9c73-e69cc3ddc9d9")}catch{}})();(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const a of n.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function i(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=i(s);fetch(s.href,n)}})();const x="modulepreload",j=function(e){return"/"+e},I={},A=function(t,i,r){let s=Promise.resolve();if(i&&i.length>0){let a=function(o){return Promise.all(o.map(l=>Promise.resolve(l).then(g=>({status:"fulfilled",value:g}),g=>({status:"rejected",reason:g}))))};document.getElementsByTagName("link");const c=document.querySelector("meta[property=csp-nonce]"),m=(c==null?void 0:c.nonce)||(c==null?void 0:c.getAttribute("nonce"));s=a(i.map(o=>{if(o=j(o),o in I)return;I[o]=!0;const l=o.endsWith(".css"),g=l?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${g}`))return;const f=document.createElement("link");if(f.rel=l?"stylesheet":x,l||(f.as="script"),f.crossOrigin="",f.href=o,m&&f.setAttribute("nonce",m),document.head.appendChild(f),l)return new Promise((T,N)=>{f.addEventListener("load",T),f.addEventListener("error",()=>N(new Error(`Unable to preload CSS for ${o}`)))})}))}function n(a){const c=new Event("vite:preloadError",{cancelable:!0});if(c.payload=a,window.dispatchEvent(c),!c.defaultPrevented)throw a}return s.then(a=>{for(const c of a||[])c.status==="rejected"&&n(c.reason);return t().catch(n)})},D=new Set(["bash","powershell","read","write","edit","grep","find","ls"]),q=new Set(["cancelled","blocked","validation","not_found","permission","timeout","process_exit","unknown"]),Y={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},F=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","toolName","toolId","toolCallId","failureKind","errorCode","exitCode","timeoutMs","diagnosticSource","originalStackAvailable","errorSummary","summaryOmitted","summaryOmittedReason","level"]),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 ee(e){return e==="/api/message"||e.startsWith("/api/provider/")||["/api/plugin-action","/api/plugin-interaction","/api/resume","/api/compact"].includes(e)}function p(e){return e.slice(0,8192).replace(/-----BEGIN [^-\n]+-----[\s\S]*?(?:-----END [^-\n]+-----|$)/g,"[redacted]").replace(/(["'`])[\s\S]*?\1/g,"[quoted]").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(/(?:^|\s)(?:\.\.?[\\/]|~[\\/])[^\s)]+/g," [path]").replace(/\b(?:[\w.-]+[\\/])+[\w.-]+/g,"[path]").replace(/\{[^\n]*\}/g,"[object]").replace(/\b[A-Za-z0-9_-]{24,}\b/g,"[redacted]").slice(0,1024)}function h(e){const t={};for(const i of F){const r=e[i];i==="toolName"?typeof r=="string"&&(D.has(r)||r==="custom")&&(t[i]=r):i==="failureKind"?q.has(r)&&(t[i]=r):i==="level"?(r==="warning"||r==="error")&&(t[i]=r):i==="diagnosticSource"?(r==="tool_execution_end"||r==="message_end")&&(t[i]=r):i==="errorCode"?typeof r=="string"&&/^(?:E[A-Z0-9]{1,20}|nonzero_exit|timeout|cancelled|blocked|invalid_arguments|tool_not_found|unknown)$/.test(r)&&(t[i]=r):i==="toolId"?typeof r=="string"&&/^[a-f0-9]{16}$/.test(r)&&(t[i]=r):i==="route"&&typeof r=="string"?t[i]=R.has(r.split("?")[0])?r.split("?")[0]:"[route]":i==="model"&&typeof r=="string"&&/^[\w.-]+\/[\w.-]+$/.test(r)?t[i]=r.split("/").map(p).join("/"):typeof r=="string"?t[i]=["requestId","operationId","errorId","session","buildId","toolId","toolCallId"].includes(i)&&/^[\w-]{1,80}$/.test(r)?r:p(r).slice(0,i==="errorSummary"?512:1024):(typeof r=="boolean"||typeof r=="number"&&Number.isFinite(r)||r===null)&&(t[i]=r)}return t}function E(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 S(e,t=0){const i=e instanceof Error?e:new Error(typeof e=="string"?e:"Non-Error rejection"),r=new Error(p(i.message));if(r.name=p(i.name).slice(0,100),i.stack){const s=i.stack.split(`
2
2
  `).slice(1,31).map(n=>{const a=n.match(/((?:file:\/\/|https?:\/\/|\/|[A-Za-z]:\\)[^\s()]+):(\d+):(\d+)(\)?)$/);return a?`${p(n.slice(0,a.index))}${a[1]}:${a[2]}:${a[3]}${a[4]}`:p(n)});r.stack=`${r.name}: ${r.message}
3
3
  ${s.join(`
4
4
  `)}`}else r.stack=void 0;return t<3&&i.cause!==void 0&&(r.cause=S(i.cause,t+1)),r}function te(e,t){const i=new Error(t);return e instanceof Error&&(i.name=e.name,e.stack&&(i.stack=`${i.name}: ${t}
5
5
  ${e.stack.split(`
6
6
  `).slice(1).join(`
7
- `)}`)),i}function K(e){return{...e.filename?{filename:E(e.filename)}:{},...e.abs_path?{abs_path:E(e.abs_path)}:{},...e.function?{function:p(e.function)}:{},lineno:e.lineno,colno:e.colno,in_app:e.in_app}}function Z(e){var r,s,n,a,l,m;const t=h(((r=e.contexts)==null?void 0:r.diagnostic)??{}),i=C(t);return{event_id:e.event_id,timestamp:e.timestamp,platform:e.platform,level:e.level,release:e.release,dist:e.dist,environment:p(e.environment??"production"),...e.message?{message:p(e.message)}:{},exception:e.exception?{values:(s=e.exception.values)==null?void 0:s.slice(0,4).map(o=>{var c;return{type:p(o.type??"Error"),value:p(o.value??""),...o.stacktrace?{stacktrace:{frames:(c=o.stacktrace.frames)==null?void 0:c.slice(-30).map(K)}}:{},...o.mechanism?{mechanism:{type:o.mechanism.type,handled:o.mechanism.handled}}:{}}})}:void 0,tags:{side:(n=e.tags)==null?void 0:n.side,buildId:(a=e.tags)==null?void 0:a.buildId,...t.toolName?{toolName:t.toolName}:{},...t.failureKind?{failureKind:t.failureKind}:{},...t.errorCode?{errorCode:t.errorCode}:{}},...i?{fingerprint:i}:{},contexts:{diagnostic:t},breadcrumbs:(l=e.breadcrumbs)==null?void 0:l.slice(-100).map(o=>({timestamp:o.timestamp,category:p(o.category??"app"),data:h(o.data??{})})),debug_meta:e.debug_meta?{images:(m=e.debug_meta.images)==null?void 0:m.slice(0,10).map(o=>({type:o.type,debug_id:o.debug_id,...o.code_file?{code_file:E(o.code_file)}:{}}))}:void 0}}function C(e){if(!(e.stage!=="tool"||e.originalStackAvailable!==!1||!e.toolName||!e.failureKind))return["pi-webapp-tool-result",String(e.toolName),String(e.toolId??"builtin"),String(e.failureKind),String(e.errorCode??"unknown")]}function re(e,t){return t.attachments=[],Z(e)}class M{constructor(){d(this,"items",[]);d(this,"bytes",0);d(this,"encoder",new TextEncoder)}add(t,i={}){const r={timestamp:Date.now()/1e3,category:p(t),data:h(i)},s=this.encoder.encode(JSON.stringify(r)).byteLength+1;for(this.items.push({item:r,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:t})=>t)}}class U{constructor(){d(this,"windowAt",-1);d(this,"total",0);d(this,"seen",new Map)}take(t,i=Date.now()){(this.windowAt<0||i-this.windowAt>=6e4)&&(this.windowAt=i,this.total=0);const r=this.seen.get(t);if(r&&i-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:i,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 ie{constructor(t,i,r,s,n=new M){d(this,"budget",new U);d(this,"breadcrumbs");d(this,"scopeClass");d(this,"seen",new WeakSet);d(this,"state",{});d(this,"client");d(this,"side");d(this,"buildId");this.client=t,this.side=i,this.buildId=r,this.scopeClass=s.Scope,this.breadcrumbs=n,t.addIntegration(s.linkedErrorsIntegration({limit:4}))}setState(t){this.state=h(t)}capture(t,i={},r){var s;try{if(L(t))return;if(typeof t=="object"&&t!==null){if(this.seen.has(t))return;this.seen.add(t)}const n=S(t),a=h({...this.state,...i}),l=C(a),m=l?JSON.stringify(l):`${n.name}:${n.message}:${((s=n.stack)==null?void 0:s.split(`
8
- `)[1])??""}:${i.stage??""}`,o=this.budget.take(m);if(!o)return;const c=new this.scopeClass;c.setClient(this.client),c.setTags({side:this.side,buildId:this.buildId}),a.level==="warning"&&c.setLevel("warning"),l&&c.setFingerprint(l),c.setContext("diagnostic",{...a,repeats:o.repeats});for(const g of this.breadcrumbs.snapshot())c.addBreadcrumb(g,100);return c.captureException(n,r?{event_id:r}:void 0)}catch{return}}ignore(t){this.seen.add(t)}}function se(e,t){return e({...t,bufferSize:20},async({body:i})=>{const r=await fetch(t.url,{method:"POST",body:i,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 W(){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 H="pi-webapp@0.1.12+17af25c649a02416e3a0",J="17af25c649a02416e3a0";let u,z=!0,$=!1,P=!1,v=[];const k=new WeakSet,b=new Map;let y={};function _(e,t={}){try{if(L(e))return;if(typeof e=="object"&&e!==null){if(k.has(e))return;k.add(e)}if(u)return u.capture(e,t);z&&v.length<20&&v.push({error:S(e),context:h(t)})}catch{}}function ne(e){k.add(e)}function oe(e,t={}){u==null||u.breadcrumbs.add(e,t)}function ae(e){e.sessionId&&(b.has(e.sessionId)||(b.size>=32&&b.delete(b.keys().next().value),b.set(e.sessionId,crypto.randomUUID())),e={...e,session:b.get(e.sessionId)}),y=h({...y,...e}),u==null||u.setState(y)}function Q(){$||($=!0,P=new URL(location.href).searchParams.get("sentry_release_probe")==="1",window.addEventListener("error",e=>{e instanceof ErrorEvent?_(e.error??new Error(e.message),{stage:"global"}):(e.target instanceof HTMLScriptElement||e.target instanceof HTMLLinkElement)&&_(new Error("Application resource failed to load"),{stage:"resource"})},!0),window.addEventListener("unhandledrejection",e=>_(e.reason,{stage:"unhandled_rejection"})),G())}async function G(){var e;try{const t=W();if(!t)return;const i=await fetch("/api/telemetry/config",{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(1e3)});if(!i.ok)return;const r=await i.json();if(!r.enabled||!r.dsn)return;const{createBrowserReporter:s}=await A(async()=>{const{createBrowserReporter:a}=await import("./telemetry-client-BUyFe34_.js");return{createBrowserReporter:a}},[]);u=s({...r,buildId:J,release:H});const n=((e=navigator.userAgent.match(/(?:Firefox|Edg|Chrome|Version)\/[\d.]+/))==null?void 0:e[0])??"unknown";u.setState({...y,browser:n,platform:navigator.platform}),y={...y,browser:n,platform:navigator.platform};for(const a of v)u.capture(a.error,a.context);r.environment==="sentry-verification"&&P&&u.capture(new Error("Sentry browser release verification"),{stage:"release_verification",code:"sentry_release_probe"})}catch{}finally{v=[],z=!1}}Q();A(()=>import("./app-Boh5DRzv.js").then(e=>e.a),[]).catch(e=>_(e,{stage:"startup"}));export{ie as E,A as _,ee as a,oe as b,W as c,re as d,se as e,ne as i,te as o,Y as p,_ as r,ae as s};
7
+ `)}`)),i}function K(e){return{...e.filename?{filename:E(e.filename)}:{},...e.abs_path?{abs_path:E(e.abs_path)}:{},...e.function?{function:p(e.function)}:{},lineno:e.lineno,colno:e.colno,in_app:e.in_app}}function Z(e){var r,s,n,a,c,m;const t=h(((r=e.contexts)==null?void 0:r.diagnostic)??{}),i=C(t);return{event_id:e.event_id,timestamp:e.timestamp,platform:e.platform,level:e.level,release:e.release,dist:e.dist,environment:p(e.environment??"production"),...e.message?{message:p(e.message)}:{},exception:e.exception?{values:(s=e.exception.values)==null?void 0:s.slice(0,4).map(o=>{var l;return{type:p(o.type??"Error"),value:p(o.value??""),...o.stacktrace?{stacktrace:{frames:(l=o.stacktrace.frames)==null?void 0:l.slice(-30).map(K)}}:{},...o.mechanism?{mechanism:{type:o.mechanism.type,handled:o.mechanism.handled}}:{}}})}:void 0,tags:{side:(n=e.tags)==null?void 0:n.side,buildId:(a=e.tags)==null?void 0:a.buildId,...t.toolName?{toolName:t.toolName}:{},...t.failureKind?{failureKind:t.failureKind}:{},...t.errorCode?{errorCode:t.errorCode}:{}},...i?{fingerprint:i}:{},contexts:{diagnostic:t},breadcrumbs:(c=e.breadcrumbs)==null?void 0:c.slice(-100).map(o=>({timestamp:o.timestamp,category:p(o.category??"app"),data:h(o.data??{})})),debug_meta:e.debug_meta?{images:(m=e.debug_meta.images)==null?void 0:m.slice(0,10).map(o=>({type:o.type,debug_id:o.debug_id,...o.code_file?{code_file:E(o.code_file)}:{}}))}:void 0}}function C(e){if(!(e.stage!=="tool"||e.originalStackAvailable!==!1||!e.toolName||!e.failureKind))return["pi-webapp-tool-result",String(e.toolName),String(e.toolId??"builtin"),String(e.failureKind),String(e.errorCode??"unknown")]}function re(e,t){return t.attachments=[],Z(e)}class M{constructor(){d(this,"items",[]);d(this,"bytes",0);d(this,"encoder",new TextEncoder)}add(t,i={}){const r={timestamp:Date.now()/1e3,category:p(t),data:h(i)},s=this.encoder.encode(JSON.stringify(r)).byteLength+1;for(this.items.push({item:r,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:t})=>t)}}class U{constructor(){d(this,"windowAt",-1);d(this,"total",0);d(this,"seen",new Map)}take(t,i=Date.now()){(this.windowAt<0||i-this.windowAt>=6e4)&&(this.windowAt=i,this.total=0);const r=this.seen.get(t);if(r&&i-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:i,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 ie{constructor(t,i,r,s,n=new M){d(this,"budget",new U);d(this,"breadcrumbs");d(this,"scopeClass");d(this,"seen",new WeakSet);d(this,"state",{});d(this,"client");d(this,"side");d(this,"buildId");this.client=t,this.side=i,this.buildId=r,this.scopeClass=s.Scope,this.breadcrumbs=n,t.addIntegration(s.linkedErrorsIntegration({limit:4}))}setState(t){this.state=h(t)}capture(t,i={},r){var s;try{if(L(t))return;if(typeof t=="object"&&t!==null){if(this.seen.has(t))return;this.seen.add(t)}const n=S(t),a=h({...this.state,...i}),c=C(a),m=c?JSON.stringify(c):`${n.name}:${n.message}:${((s=n.stack)==null?void 0:s.split(`
8
+ `)[1])??""}:${i.stage??""}`,o=this.budget.take(m);if(!o)return;const l=new this.scopeClass;l.setClient(this.client),l.setTags({side:this.side,buildId:this.buildId}),a.level==="warning"&&l.setLevel("warning"),c&&l.setFingerprint(c),l.setContext("diagnostic",{...a,repeats:o.repeats});for(const g of this.breadcrumbs.snapshot())l.addBreadcrumb(g,100);return l.captureException(n,r?{event_id:r}:void 0)}catch{return}}ignore(t){this.seen.add(t)}}function se(e,t){return e({...t,bufferSize:20},async({body:i})=>{const r=await fetch(t.url,{method:"POST",body:i,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 W(){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 H="pi-webapp@0.1.13+47b0cab9b46d97bbc98c",J="47b0cab9b46d97bbc98c";let u,z=!0,$=!1,P=!1,v=[];const k=new WeakSet,b=new Map;let y={};function _(e,t={}){try{if(L(e))return;if(typeof e=="object"&&e!==null){if(k.has(e))return;k.add(e)}if(u)return u.capture(e,t);z&&v.length<20&&v.push({error:S(e),context:h(t)})}catch{}}function ne(e){k.add(e)}function oe(e,t={}){u==null||u.breadcrumbs.add(e,t)}function ae(e){e.sessionId&&(b.has(e.sessionId)||(b.size>=32&&b.delete(b.keys().next().value),b.set(e.sessionId,crypto.randomUUID())),e={...e,session:b.get(e.sessionId)}),y=h({...y,...e}),u==null||u.setState(y)}function Q(){$||($=!0,P=new URL(location.href).searchParams.get("sentry_release_probe")==="1",window.addEventListener("error",e=>{e instanceof ErrorEvent?_(e.error??new Error(e.message),{stage:"global"}):(e.target instanceof HTMLScriptElement||e.target instanceof HTMLLinkElement)&&_(new Error("Application resource failed to load"),{stage:"resource"})},!0),window.addEventListener("unhandledrejection",e=>_(e.reason,{stage:"unhandled_rejection"})),G())}async function G(){var e;try{const t=W();if(!t)return;const i=await fetch("/api/telemetry/config",{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(1e3)});if(!i.ok)return;const r=await i.json();if(!r.enabled||!r.dsn)return;const{createBrowserReporter:s}=await A(async()=>{const{createBrowserReporter:a}=await import("./telemetry-client-BUyFe34_.js");return{createBrowserReporter:a}},[]);u=s({...r,buildId:J,release:H});const n=((e=navigator.userAgent.match(/(?:Firefox|Edg|Chrome|Version)\/[\d.]+/))==null?void 0:e[0])??"unknown";u.setState({...y,browser:n,platform:navigator.platform}),y={...y,browser:n,platform:navigator.platform};for(const a of v)u.capture(a.error,a.context);r.environment==="sentry-verification"&&P&&u.capture(new Error("Sentry browser release verification"),{stage:"release_verification",code:"sentry_release_probe"})}catch{}finally{v=[],z=!1}}Q();A(()=>import("./app-Boh5DRzv.js").then(e=>e.a),[]).catch(e=>_(e,{stage:"startup"}));export{ie as E,A as _,ee as a,oe as b,W as c,re as d,se as e,ne as i,te as o,Y as p,_ as r,ae as s};