pi-webapp 0.1.2 → 0.1.3
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/README.md +25 -6
- package/README.zh-CN.md +25 -6
- package/bin/open-web-page.d.mts +2 -0
- package/bin/open-web-page.mjs +18 -0
- package/bin/pi-webapp.mjs +294 -0
- package/dist/extension.js +6 -5
- package/package.json +11 -3
- package/web/dist/assets/app.js +49 -49
- package/web/dist/assets/style.css +1 -1
- package/web/dist/index.html +1 -1
package/dist/extension.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import{dirname as
|
|
2
|
-
`,{mode:p,flag:"wx"}),await
|
|
3
|
-
|
|
1
|
+
import{dirname as Xt,join as K,resolve as Qt}from"node:path";import{realpath as O}from"node:fs/promises";import{fileURLToPath as Zt}from"node:url";import{DefaultPackageManager as Me,getAgentDir as T,ModelRuntime as qt,SessionManager as Ae,SettingsManager as ei}from"@earendil-works/pi-coding-agent";import{getSupportedThinkingLevels as ti}from"@earendil-works/pi-ai";import{randomBytes as Et,timingSafeEqual as Ct}from"node:crypto";import{readFile as Mt}from"node:fs/promises";import{createServer as At}from"node:http";import{join as Tt}from"node:path";import{mkdir as je,opendir as Re,stat as Ve}from"node:fs/promises";import{homedir as _e}from"node:os";import{basename as Be,dirname as Y,join as X,posix as Oe,resolve as Q,win32 as Ue}from"node:path";function Z(t){return process.platform==="win32"?Ue.isAbsolute(t)&&/^(?:[A-Za-z]:[\\/]|[\\/]{2}[^\\/]+[\\/]+[^\\/]+)/.test(t):Oe.isAbsolute(t)}function De(t,e,i){if(t.length===i&&e.name.localeCompare(t[t.length-1].name)>=0)return!0;let r=0,n=t.length;for(;r<n;){let p=r+n>>>1;e.name.localeCompare(t[p].name)<0?n=p:r=p+1}return t.splice(r,0,e),t.length<=i?!1:(t.pop(),!0)}async function q(t){if(t!==void 0&&!Z(t))throw new Error("\u76EE\u5F55\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");let e=_e(),i=Q(t??e),r=[];for(let a=i;;a=Y(a)){let u=Y(a);if(r.unshift({name:u===a?a:Be(a),path:a,hidden:!1}),u===a)break}let n=[],p=!1,o=await Re(i);for await(let a of o)!a.isDirectory()&&!a.isSymbolicLink()||De(n,{name:a.name,isDirectory:a.isDirectory(),isSymbolicLink:a.isSymbolicLink()},1001)&&(p=!0);let l=[];for(let a of n){let u=X(i,a.name);if(!a.isDirectory&&a.isSymbolicLink)try{if(!(await Ve(u)).isDirectory())continue}catch{continue}if(l.length===1e3){p=!0;break}l.push({name:a.name,path:u,hidden:a.name.startsWith(".")})}return{path:i,home:e,crumbs:r,entries:l,truncated:p}}async function ee(t,e){if(!Z(t))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 i=X(Q(t),e);return await je(i),i}import{execFile as $e}from"node:child_process";import{accessSync as Fe,constants as He}from"node:fs";import{delimiter as Je,join as Ge}from"node:path";var Ke=(t,e,i)=>new Promise((r,n)=>{$e(t,[...e],{encoding:"utf8",signal:i,windowsHide:!0},(p,o,l)=>{p?n(Object.assign(new Error(p.message,{cause:p}),{code:p.code,stdout:o,stderr:l})):r({stdout:o,stderr:l})})});function ze(t){for(let e of(t??"").split(Je))if(e)for(let i of["zenity","kdialog"])try{return Fe(Ge(e,i),He.X_OK),!0}catch{}return!1}function te(t=process.platform,e=process.env){return e.SSH_CONNECTION||e.SSH_TTY?"browse":t==="darwin"||t==="linux"&&(e.DISPLAY||e.WAYLAND_DISPLAY)&&ze(e.PATH)?"native":"browse"}function L(t){if(!(typeof t!="object"||t===null||!("code"in t)))return typeof t.code=="string"||typeof t.code=="number"?t.code:void 0}function Ye(t){return typeof t=="object"&&t!==null&&"stderr"in t&&typeof t.stderr=="string"?t.stderr:""}function U(t){return t.replace(/[\r\n]+$/,"")||null}async function ie(t,e=process.platform,i=Ke){if(e==="darwin")try{let r=await i("osascript",["-e",'set selectedFolder to choose folder with prompt "Select Workspace Directory"',"-e","POSIX path of selectedFolder"],t);return U(r.stdout)}catch(r){if(!t.aborted&&L(r)===1&&/(?:User canceled|-128)/i.test(Ye(r)))return null;throw r}if(e==="linux"){try{return U((await i("zenity",["--file-selection","--directory","--title=Select Workspace Directory"],t)).stdout)}catch(r){if(t.aborted)throw r;if(L(r)===1)return null;if(L(r)!=="ENOENT")throw r}try{return U((await i("kdialog",["--getexistingdirectory",".","--title","Select Workspace Directory"],t)).stdout)}catch(r){if(t.aborted)throw r;if(L(r)===1)return null;throw r}}throw new Error(`\u5F53\u524D\u7CFB\u7EDF\u4E0D\u652F\u6301\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\uFF1A${e}`)}import{createHash as Xe,randomUUID as Qe}from"node:crypto";import{mkdir as Ze,readFile as qe,writeFile as et}from"node:fs/promises";import{join as re}from"node:path";import{getAgentDir as tt}from"@earendil-works/pi-coding-agent";var N=20*1024*1024,se=20,it=/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu;function rt(t){let e=t.indexOf("."),i=(e<0?t:t.slice(0,e)).replace(/[. ]+$/u,"");return it.test(i)}function st(t,e){let i=0,r="";for(let n of Buffer.from(t).toString("utf8")){let p=Buffer.byteLength(n);if(i+p>e)break;r+=n,i+=p}return r}function nt(t){if(t===void 0)return"file";let i=t.slice(Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"))+1).replace(/[\u0000-\u001f\u007f]/g,"").replace(/[<>:"|?*]/g,"_").trim().replace(/[. ]+$/u,"");return rt(i)&&(i=`_${i}`),i=st(i,255).replace(/[. ]+$/u,""),i===""||i==="."||i===".."?"file":i}function ot(t){return t.length>=8&&t.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10]))?"image/png":t.length>=3&&t.subarray(0,3).equals(Buffer.from([255,216,255]))?"image/jpeg":t.length>=6&&["GIF87a","GIF89a"].includes(t.toString("ascii",0,6))?"image/gif":t.length>=12&&t.toString("ascii",0,4)==="RIFF"&&t.toString("ascii",8,12)==="WEBP"?"image/webp":null}async function ne(t,e,i,r){if(r.byteLength===0||r.byteLength>N)throw new Error("\u6587\u4EF6\u4E3A\u7A7A\u6216\u8D85\u8FC7 20 MB");let n=nt(e),p=Xe("sha256").update(r).digest("hex"),o=re(tt(),"pi-web","attachments",p);await Ze(o,{recursive:!0});let l=re(o,n);try{await et(l,r,{flag:"wx",mode:384})}catch(a){if(!(a instanceof Error&&"code"in a&&a.code==="EEXIST"))throw a}return{id:Qe(),name:n,bytes:r.byteLength,path:l,mediaType:ot(r)??i.replace(/^image\//,"application/"),sessionId:t}}async function oe(t){return{type:"image",data:(await qe(t.path)).toString("base64"),mimeType:t.mediaType}}import{randomBytes as at}from"node:crypto";function ae(t,e,i){return t!=="openai-codex"||e!=="oauth"?i:{...i,prompt:r=>r.type==="select"&&r.options.some(n=>n.id==="browser")&&r.options.some(n=>n.id==="device_code")?Promise.resolve("browser"):i.prompt(r)}}var j=class{flows=new Map;start(e,i,r,n){let p=this.getActive();if(p){if(p.providerId===e&&p.method===i&&n===void 0)return p;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 o=at(18).toString("base64url"),l={view:{id:o,providerId:e,method:i,status:"running"},controller:new AbortController};return this.flows.set(o,l),r(e,i,{signal:l.controller.signal,notify:a=>{l.view={...l.view,event:a,...a.type==="auth_url"||a.type==="device_code"?{authorization:a}:{}}},prompt:a=>{if(a.type==="secret"&&n!==void 0){let u=n;return n=void 0,Promise.resolve(u)}return new Promise((u,h)=>{let{signal:g,...c}=a;l.answer=u,l.reject=h,l.view={...l.view,status:"waiting",prompt:c},g?.aborted?h(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")):g?.addEventListener("abort",()=>h(new Error("\u767B\u5F55\u8F93\u5165\u5DF2\u53D6\u6D88")),{once:!0})})}}).then(()=>{l.view.status!=="cancelled"&&(l.view={id:o,providerId:e,method:i,status:"done"})}).catch(()=>{l.view.status!=="cancelled"&&(l.view={id:o,providerId:e,method:i,status:"error",error:"\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u63D0\u4F9B\u65B9\u63D0\u793A\u5E76\u91CD\u8BD5\u3002"})}),{...l.view}}get(e){let i=this.flows.get(e)?.view;return i?{...i}:void 0}getActive(){let e=[...this.flows.values()].find(({view:i})=>i.status==="running"||i.status==="waiting")?.view;return e?{...e}:void 0}respond(e,i){let r=this.flows.get(e);if(!r?.answer||r.view.status!=="waiting"||r.view.prompt?.type==="select"&&!r.view.prompt.options.some(p=>p.id===i))return!1;let n=r.answer;return r.answer=void 0,r.reject=void 0,r.view={...r.view,status:"running",prompt:void 0},n(i),!0}cancel(e){let i=this.flows.get(e);return!i||i.view.status==="done"||i.view.status==="error"?!1:(i.view={...i.view,status:"cancelled",prompt:void 0},i.controller.abort(),i.reject?.(new Error("\u767B\u5F55\u5DF2\u53D6\u6D88")),i.answer=void 0,i.reject=void 0,!0)}close(){for(let e of this.flows.keys())this.cancel(e);this.flows.clear()}};import{randomBytes as dt}from"node:crypto";import{readFile as lt,rename as ct,rm as pt,stat as ut,writeFile as mt,mkdir as ft}from"node:fs/promises";import{dirname as gt}from"node:path";var wt=["openai-completions","openai-responses","anthropic-messages"];function D(t){if(!t||typeof t!="object")return!1;let e=t;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||!wt.includes(e.api)||typeof e.baseUrl!="string"||e.baseUrl.length>2048)return!1;try{let i=new URL(e.baseUrl);return(i.protocol==="https:"||i.protocol==="http:")&&!!i.hostname&&!i.username&&!i.password&&!i.hash}catch{return!1}}async function de(t,e){if(!D(e))throw new Error("\u81EA\u5B9A\u4E49\u63D0\u4F9B\u65B9\u540D\u79F0\u3001\u5730\u5740\u6216\u6A21\u578B\u65E0\u6548");let i;try{i=await lt(t,"utf8")}catch(l){if(l.code!=="ENOENT")throw l}let r;if(i===void 0)r={providers:{}};else{try{r=JSON.parse(i)}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(!r||typeof r!="object"||!r.providers||typeof r.providers!="object"||Array.isArray(r.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548")}if(Object.hasOwn(r.providers,e.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");let n={...r,providers:{...r.providers,[e.id]:{name:e.name.trim(),baseUrl:e.baseUrl,api:e.api,models:[{id:e.modelId.trim()}]}}};await ft(gt(t),{recursive:!0});let p=i===void 0?384:(await ut(t)).mode&511,o=`${t}.pi-web-${dt(6).toString("hex")}.tmp`;try{await mt(o,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`,{mode:p,flag:"wx"}),await ct(o,t)}finally{await pt(o,{force:!0})}}import{randomBytes as ht}from"node:crypto";import{mkdir as yt,readFile as vt,rename as kt,rm as bt,stat as Pt,writeFile as St}from"node:fs/promises";import{dirname as xt}from"node:path";function le(t){if(!t||t.length>2048)return!1;try{let e=new URL(t);return(e.protocol==="https:"||e.protocol==="http:")&&!!e.hostname&&!e.username&&!e.password&&!e.search&&!e.hash}catch{return!1}}function ce(t){if(!t||typeof t!="object")return!1;let e=t;return e.action==="save"?(e.originalId===void 0||typeof e.originalId=="string")&&pe(e.model):e.action==="base_url"?e.baseUrl===null||typeof e.baseUrl=="string"&&le(e.baseUrl):e.action==="remove"&&typeof e.id=="string"&&e.id.length>0&&e.id.length<=200}function pe(t){if(!t||typeof t!="object")return!1;let e=t;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 i of[e.contextWindow,e.maxTokens])if(i!==void 0&&(!Number.isSafeInteger(i)||i<=0))return!1;return e.input===void 0||Array.isArray(e.input)&&e.input.length>0&&e.input.every(i=>i==="text"||i==="image")&&new Set(e.input).size===e.input.length}async function ue(t){let e;try{e=await vt(t,"utf8")}catch(r){if(r.code!=="ENOENT")throw r}if(e===void 0)return{config:{providers:{}}};let i;try{i=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(!i||typeof i!="object"||!i.providers||typeof i.providers!="object"||Array.isArray(i.providers))throw new Error("models.json \u7ED3\u6784\u65E0\u6548");return{config:i,existing:e}}async function It(t,e,i){await yt(xt(t),{recursive:!0});let r=i===void 0?384:(await Pt(t)).mode&511,n=`${t}.pi-web-${ht(6).toString("hex")}.tmp`;try{await St(n,`${JSON.stringify(e,null,2)}
|
|
3
|
+
`,{mode:r,flag:"wx"}),await kt(n,t)}finally{await bt(n,{force:!0})}}async function me(t,e,i){if(!i.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:r}=await ue(t),n=r.providers[e],p=new Set(n?.models?.map(o=>o.id)??[]);return{providerId:e,baseUrl:n?.baseUrl,models:i.getModels(e).map(o=>({id:o.id,name:o.name,contextWindow:o.contextWindow,maxTokens:o.maxTokens,input:[...o.input],source:p.has(o.id)?"custom":"builtin",overridden:!!n?.modelOverrides?.[o.id]}))}}async function fe(t,e,i,r){if(!r.getProvider(e))throw new Error("\u63D0\u4F9B\u65B9\u4E0D\u5B58\u5728");let{config:n,existing:p}=await ue(t),o={...n.providers[e]??{}},l=[...o.models??[]],a={...o.modelOverrides??{}};if(i.action==="base_url"){if(i.baseUrl!==null&&!le(i.baseUrl))throw new Error("API \u5730\u5740\u65E0\u6548");i.baseUrl===null?delete o.baseUrl:o.baseUrl=i.baseUrl}else if(i.action==="save"){if(!pe(i.model))throw new Error("\u6A21\u578B\u53C2\u6570\u65E0\u6548");let u={id:i.model.id.trim(),...i.model.name===void 0?{}:{name:i.model.name},...i.model.contextWindow===void 0?{}:{contextWindow:i.model.contextWindow},...i.model.maxTokens===void 0?{}:{maxTokens:i.model.maxTokens},...i.model.input===void 0?{}:{input:i.model.input}},h=i.originalId,g=h===void 0?-1:l.findIndex(c=>c.id===h);if(h===void 0&&(l.some(c=>c.id===u.id)||r.getModel(e,u.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");if(g>=0){if(u.id!==h&&(l.some(f=>f.id===u.id)||r.getModel(e,u.id)))throw new Error("\u6A21\u578B ID \u5DF2\u5B58\u5728");let c={...l[g],...u};for(let f of["name","contextWindow","maxTokens","input"])u[f]===void 0&&delete c[f];l[g]=c}else if(h!==void 0&&r.getModel(e,h)){if(u.id!==h)throw new Error("\u5185\u7F6E\u6A21\u578B ID \u4E0D\u53EF\u4FEE\u6539");let{id:c,...f}=u;a[h]={...a[h],...f};for(let C of["name","contextWindow","maxTokens","input"])u[C]===void 0&&delete a[h][C]}else{if(h!==void 0)throw new Error("\u6A21\u578B\u4E0D\u5B58\u5728");l.push(u)}}else{let u=l.findIndex(h=>h.id===i.id);if(u>=0)l.splice(u,1);else if(Object.hasOwn(a,i.id))delete a[i.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")}l.length?o.models=l:delete o.models,Object.keys(a).length?o.modelOverrides=a:delete o.modelOverrides,Object.keys(o).length?n.providers[e]=o:delete n.providers[e],await It(t,n,p)}function ge(t){return/^(?:npm:|git:|https?:\/\/|ssh:\/\/|git@)/i.test(t.trim())}var Wt={"/":{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 m(t,e,i){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),t.end(JSON.stringify(i))}function Lt(t,e){let i=t.headers.authorization;if(typeof i!="string"||!i.startsWith("Bearer "))return!1;let r=Buffer.from(i.slice(7),"utf8");return r.length===e.length&&Ct(r,e)}async function Nt(t){let e=0,i=[];for await(let r of t){let n=Buffer.isBuffer(r)?r:Buffer.from(r);if(e+=n.length,e>64*1024)throw new Error("\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927");i.push(n)}return JSON.parse(Buffer.concat(i).toString("utf8"))}async function jt(t){let e=0,i=[];for await(let r of t){let n=Buffer.isBuffer(r)?r:Buffer.from(r);if(e+=n.length,e>N)throw new Error("\u6587\u4EF6\u8D85\u8FC7 20 MB");i.push(n)}return Buffer.concat(i)}async function Rt(t){await new Promise((i,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r),i()})});let e=t.address();if(e===null||typeof e=="string")throw new Error("\u65E0\u6CD5\u786E\u5B9A\u76D1\u542C\u7AEF\u53E3");return e.port}async function we(t,e){let i=Et(24).toString("base64url"),r=Buffer.from(i),n=te(),p=new Set,o=new Map,l=new j,a="",u=At(async(g,c)=>{c.setHeader("X-Content-Type-Options","nosniff"),c.setHeader("Referrer-Policy","no-referrer"),c.setHeader("Content-Security-Policy","default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'self'; img-src 'self' data: blob:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'");let f;try{f=new URL(g.url??"/",a).pathname}catch{m(c,400,{error:"\u8BF7\u6C42\u5730\u5740\u65E0\u6548"});return}let C=Wt[f];if(g.method==="GET"&&C){try{let d=await Mt(Tt(e,C.path));c.writeHead(200,{"Content-Type":C.type,"Cache-Control":"no-store"}),c.end(d)}catch{m(c,500,{error:"\u9875\u9762\u6587\u4EF6\u4E0D\u53EF\u7528"})}return}if(!f.startsWith("/api/")){m(c,404,{error:"\u672A\u627E\u5230"});return}if(!Lt(g,r)){m(c,401,{error:"\u8BBF\u95EE\u4EE4\u724C\u65E0\u6548"});return}if(g.method==="GET"&&f==="/api/image"){let d=new URL(g.url??f,a),w=d.searchParams.get("sessionId")??"",v=d.searchParams.get("messageId")??"",y=Number(d.searchParams.get("index"));if(!w||w!==t.snapshot().sessionId||!v||!Number.isInteger(y)||y<0||y>100){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u56FE\u7247\u5730\u5740\u65E0\u6548"});return}let E=t.image?.(w,v,y);if(!E||!["image/png","image/jpeg","image/webp","image/gif"].includes(E.mimeType)){m(c,404,{error:"\u56FE\u7247\u4E0D\u53EF\u7528"});return}c.writeHead(200,{"Content-Type":E.mimeType,"Cache-Control":"private, no-store"}),c.end(E.data);return}if(g.method==="POST"&&f==="/api/attachment"){if(g.headers.origin!==void 0&&g.headers.origin!==a){m(c,403,{error:"\u6765\u6E90\u4E0D\u5339\u914D"});return}let d=new URL(g.url??f,a),w=d.searchParams.get("sessionId"),v=d.searchParams.get("name");try{if(!w||!v||v.length>1024||w!==t.snapshot().sessionId){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u6587\u4EF6\u540D\u65E0\u6548"});return}if(Number(g.headers["content-length"]??0)>N){m(c,413,{error:"\u6587\u4EF6\u8D85\u8FC7 20 MB"});return}let y=await ne(w,v,g.headers["content-type"]??"application/octet-stream",await jt(g));if(w!==t.snapshot().sessionId){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}o.set(y.id,y),m(c,201,{id:y.id,name:y.name,bytes:y.bytes})}catch(y){m(c,400,{error:y instanceof Error?y.message:"\u4E0A\u4F20\u5931\u8D25"})}return}if(g.method==="GET"&&f==="/api/session"){try{m(c,200,t.snapshot())}catch{m(c,503,{error:"\u5F53\u524D\u4F1A\u8BDD\u4E0D\u53EF\u7528"})}return}if(g.method==="GET"&&f==="/api/providers"){try{m(c,200,await t.providers?.()??[])}catch{m(c,503,{error:"\u6A21\u578B\u63D0\u4F9B\u65B9\u4E0D\u53EF\u7528"})}return}if(g.method==="GET"&&f==="/api/provider/models"){let d=new URL(g.url??f,a).searchParams.get("providerId")??"";try{if(!d||!t.providerModels){m(c,400,{error:"\u63D0\u4F9B\u65B9\u65E0\u6548"});return}m(c,200,await t.providerModels(d))}catch(w){m(c,400,{error:w instanceof Error?w.message:"\u6A21\u578B\u76EE\u5F55\u4E0D\u53EF\u7528"})}return}if(g.method==="GET"&&f==="/api/provider/login/active"){m(c,200,{active:l.getActive()??null});return}if(g.method==="GET"&&f==="/api/provider/login"){let d=new URL(g.url??f,a).searchParams.get("id")??"",w=l.get(d);m(c,w?200:404,w??{error:"\u767B\u5F55\u6D41\u7A0B\u4E0D\u5B58\u5728"});return}if(g.method==="GET"&&(f==="/api/models"||f==="/api/config"||f==="/api/workspaces"||f==="/api/commands")){try{m(c,200,f==="/api/models"?await t.models():f==="/api/config"?await t.config():f==="/api/commands"?t.commands?.()??[]:await t.workspaces())}catch{m(c,503,{error:"Pi \u914D\u7F6E\u4E0D\u53EF\u7528"})}return}if(g.method==="GET"&&f==="/api/directory/capability"){m(c,200,{kind:n});return}if(g.method==="GET"&&f==="/api/events"){let d;try{d=t.snapshot()}catch{m(c,503,{error:"\u5F53\u524D\u4F1A\u8BDD\u4E0D\u53EF\u7528"});return}c.writeHead(200,{"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"no-store",Connection:"keep-alive","X-Accel-Buffering":"no"}),p.add(c),c.write(`${JSON.stringify({type:"snapshot",session:d})}
|
|
4
|
+
`),c.on("close",()=>p.delete(c));return}if(g.method==="POST"&&["/api/message","/api/attachment/remove","/api/abort","/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(f)){if(g.headers.origin!==void 0&&g.headers.origin!==a){m(c,403,{error:"\u6765\u6E90\u4E0D\u5339\u914D"});return}if(!g.headers["content-type"]?.startsWith("application/json")){m(c,415,{error:"\u9700\u8981 JSON \u8BF7\u6C42"});return}try{let d=await Nt(g);if(typeof d!="object"||d===null||!("sessionId"in d)||typeof d.sessionId!="string"){m(c,400,{error:"\u7F3A\u5C11\u4F1A\u8BDD\u6807\u8BC6"});return}if(f==="/api/provider/custom"){if(d.sessionId!==t.snapshot().sessionId){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("provider"in d)||!D(d.provider)||!t.addCustomProvider){m(c,400,{error:"\u81EA\u5B9A\u4E49\u63D0\u4F9B\u65B9\u65E0\u6548"});return}await t.addCustomProvider(d.sessionId,d.provider),m(c,201,{accepted:!0});return}if(f==="/api/provider/models"||f==="/api/provider/logout"){if(d.sessionId!==t.snapshot().sessionId){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(!("providerId"in d)||typeof d.providerId!="string"){m(c,400,{error:"\u63D0\u4F9B\u65B9\u65E0\u6548"});return}if(f==="/api/provider/models"){if(!("change"in d)||!ce(d.change)||!t.updateProviderModel){m(c,400,{error:"\u6A21\u578B\u53C2\u6570\u65E0\u6548"});return}await t.updateProviderModel(d.sessionId,d.providerId,d.change)}else{if(!t.logoutProvider){m(c,400,{error:"\u65E0\u6CD5\u79FB\u9664\u8BA4\u8BC1"});return}await t.logoutProvider(d.sessionId,d.providerId)}m(c,200,{accepted:!0});return}if(f.startsWith("/api/provider/login")){if(d.sessionId!==t.snapshot().sessionId){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362"});return}if(f==="/api/provider/login"){if(!("providerId"in d)||typeof d.providerId!="string"||!("method"in d)||d.method!=="api_key"&&d.method!=="oauth"||!t.loginProvider||!t.providers){m(c,400,{error:"\u767B\u5F55\u65B9\u5F0F\u65E0\u6548"});return}if(!(await t.providers()).some(E=>E.id===d.providerId&&E.methods.includes(d.method))){m(c,400,{error:"\u63D0\u4F9B\u65B9\u4E0D\u652F\u6301\u6B64\u767B\u5F55\u65B9\u5F0F"});return}let v="initialSecret"in d?d.initialSecret:void 0;if(v!==void 0&&(d.method!=="api_key"||typeof v!="string"||!v.trim()||v.length>16384)){m(c,400,{error:"API Key \u65E0\u6548"});return}let y=l.start(d.providerId,d.method,t.loginProvider,v);m(c,202,{id:y.id});return}if(!("id"in d)||typeof d.id!="string"){m(c,400,{error:"\u767B\u5F55\u6D41\u7A0B\u65E0\u6548"});return}if(f==="/api/provider/login/cancel"){m(c,l.cancel(d.id)?202:404,{accepted:!0});return}if(!("value"in d)||typeof d.value!="string"||d.value.length>16384||!l.respond(d.id,d.value)){m(c,400,{error:"\u767B\u5F55\u8F93\u5165\u65E0\u6548"});return}m(c,202,{accepted:!0});return}if(f==="/api/attachment/remove"){if(!("id"in d)||typeof d.id!="string"||d.sessionId!==t.snapshot().sessionId){m(c,409,{error:"\u4F1A\u8BDD\u5DF2\u5207\u6362\u6216\u9644\u4EF6\u65E0\u6548"});return}o.get(d.id)?.sessionId===d.sessionId&&o.delete(d.id),m(c,202,{accepted:!0});return}if(f==="/api/directory/pick"){if(n!=="native"){m(c,409,{error:"\u672C\u5730\u76EE\u5F55\u9009\u62E9\u5668\u4E0D\u53EF\u7528"});return}let w=new AbortController;c.once("close",()=>w.abort()),m(c,200,{path:await ie(w.signal)});return}if(f==="/api/directory/list"){if("path"in d&&(typeof d.path!="string"||d.path.length>4096)){m(c,400,{error:"\u76EE\u5F55\u8DEF\u5F84\u65E0\u6548"});return}m(c,200,await q("path"in d?d.path:void 0));return}if(f==="/api/directory/create"){if(!("path"in d)||typeof d.path!="string"||d.path.length>4096||!("name"in d)||typeof d.name!="string"||d.name.length>255){m(c,400,{error:"\u6587\u4EF6\u5939\u540D\u79F0\u6216\u8DEF\u5F84\u65E0\u6548"});return}m(c,200,{path:await ee(d.path,d.name)});return}if(f==="/api/workspace/add"){if(!("path"in d)||typeof d.path!="string"||d.path.length>4096||!("create"in d)||typeof d.create!="boolean"){m(c,400,{error:"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u65E0\u6548"});return}await t.addWorkspace(d.path,d.create),m(c,202,{accepted:!0});return}if(f==="/api/workspace/select"||f==="/api/workspace/remove"||f==="/api/workspace/new-session"){if(!("id"in d)||typeof d.id!="string"){m(c,400,{error:"\u5DE5\u4F5C\u533A\u65E0\u6548"});return}f==="/api/workspace/select"?await t.selectWorkspace(d.id):f==="/api/workspace/new-session"?await t.newSessionInWorkspace(d.id):await t.removeWorkspace(d.id),m(c,202,{accepted:!0});return}if(f==="/api/session/select"){if(!("workspaceId"in d)||typeof d.workspaceId!="string"||!("id"in d)||typeof d.id!="string"||!("path"in d)||typeof d.path!="string"){m(c,400,{error:"\u4F1A\u8BDD\u65E0\u6548"});return}await t.selectSession(d.workspaceId,d.id,d.path),m(c,202,{accepted:!0});return}if(f==="/api/thinking-level"){if(!("level"in d)||typeof d.level!="string"){m(c,400,{error:"\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548"});return}await t.setThinkingLevel(d.sessionId,d.level)}else if(f==="/api/model"){if(!("provider"in d)||typeof d.provider!="string"||!("id"in d)||typeof d.id!="string"){m(c,400,{error:"\u6A21\u578B\u65E0\u6548"});return}await t.setModel(d.sessionId,d.provider,d.id)}else if(f==="/api/config"){let w=d;if(!["packages","extensions","skills"].includes(w.kind)||!["global","project"].includes(w.scope)||!["add","remove"].includes(w.action)||typeof w.value!="string"||!w.value.trim()||w.value.length>2048){m(c,400,{error:"\u914D\u7F6E\u9879\u65E0\u6548"});return}if(w.action==="add"&&w.kind!=="packages"&&ge(w.value)){m(c,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}m(c,200,await t.updateConfig(w));return}else if(f==="/api/message"){let w="attachments"in d?d.attachments:[];if(!Array.isArray(w)||w.length>se||w.some(b=>typeof b!="string")||new Set(w).size!==w.length){m(c,400,{error:"\u9644\u4EF6\u65E0\u6548\u6216\u8FC7\u591A"});return}let v=w.map(b=>o.get(b));if(v.some(b=>!b||b.sessionId!==d.sessionId)){m(c,400,{error:"\u9644\u4EF6\u4E0D\u53EF\u7528"});return}if(!("text"in d)||typeof d.text!="string"||!d.text.trim()&&w.length===0||d.text.length>32e3){m(c,400,{error:"\u6D88\u606F\u65E0\u6548\u6216\u8FC7\u957F"});return}let y=v,E=[d.text.trim(),...y.map(b=>`\u9644\u4EF6 ${JSON.stringify(b.name)}\uFF1A${b.path}`)].filter(Boolean).join(`
|
|
4
5
|
|
|
5
|
-
`),
|
|
6
|
-
`;for(let m of p)m.write(d)},async close(){l.close();for(let f of p)f.end();p.clear(),await new Promise((f,d)=>g.close(m=>m?d(m):f()))}}}import{getSupportedThinkingLevels as gt}from"@earendil-works/pi-ai";function ae(e){let t=[],r=e;for(;;){let i=/(^|\n\n)附件 ("(?:\\.|[^"\\])*"):([^\n]+)$/u.exec(r);if(!i||!/[\\/]pi-web[\\/]attachments[\\/][a-f0-9]{64}[\\/]/u.test(i[3]))break;let a;try{a=JSON.parse(i[2])}catch{break}t.unshift({name:a,image:/\.(?:png|jpe?g|webp|gif)$/iu.test(a)}),r=r.slice(0,i.index)}return{text:r,attachments:t}}function C(e){return typeof e=="string"?[{kind:"text",text:e}]:e.flatMap(t=>t.type==="text"?[{kind:"text",text:t.text}]:t.type==="thinking"?[{kind:"thinking",text:t.thinking}]:t.type==="image"?[{kind:"image",text:"\u56FE\u7247\u9644\u4EF6"}]:t.type==="toolCall"?[{kind:"toolCall",text:JSON.stringify(t.arguments??{}),toolName:t.name,toolCallId:t.id}]:[])}function U(e){if(e.type==="custom_message")return e.display?{id:e.id,role:"notice",timestamp:e.timestamp,blocks:C(e.content)}:null;if(e.type!=="message")return null;let{message:t}=e;return t.role==="user"||t.role==="assistant"?{id:e.id,role:t.role,timestamp:e.timestamp,blocks:C(t.content),...t.role==="assistant"?{...t.stopReason==="error"&&t.errorMessage?{error:t.errorMessage}:{},usage:{input:t.usage.input,output:t.usage.output,cacheRead:t.usage.cacheRead,cacheWrite:t.usage.cacheWrite,...t.usage.reasoning===void 0?{}:{reasoning:t.usage.reasoning},totalTokens:t.usage.totalTokens,cost:t.usage.cost.total},model:`${t.provider}/${t.model}`}:{}}:t.role==="toolResult"?{id:e.id,role:"tool",timestamp:e.timestamp,blocks:C(t.content),isError:t.isError,toolCallId:t.toolCallId,toolName:t.toolName}:null}function $(e,t){let r=e?.trim();if(r)return r;let i=t.find(p=>p.role==="user"),a=ae(i?.blocks.find(p=>p.kind==="text")?.text??"").text.replace(/\s+/g," ").trim();return a?a.slice(0,50):"\u5F53\u524D\u4F1A\u8BDD"}function ce(e,t){let r=e.sessionManager.getBranch().flatMap(i=>{let a=U(i);return a?[a]:[]});return{schemaVersion:1,sessionId:e.sessionManager.getSessionId(),cwd:e.cwd,name:$(t,r),model:e.model?`${e.model.provider}/${e.model.id}`:null,thinkingLevel:e.thinkingLevel??null,thinkingLevels:e.model?gt(e.model):["off"],idle:e.isIdle(),contextUsage:e.getContextUsage()??null,messages:r}}import{randomUUID as le}from"node:crypto";import{mkdir as de,readFile as ft,realpath as wt,rename as ht,rm as yt,stat as vt,writeFile as kt}from"node:fs/promises";import{basename as bt,dirname as St,isAbsolute as Pt,join as xt}from"node:path";var N=class{items=[];mutationChain=Promise.resolve();file;constructor(t){this.file=t}async load(){try{let t=JSON.parse(await ft(this.file,"utf8"));if(!Array.isArray(t))throw new Error("\u5DE5\u4F5C\u533A\u8BB0\u5F55\u65E0\u6548");this.items=t.filter(r=>typeof r=="object"&&r!==null&&typeof r.id=="string"&&typeof r.path=="string"&&typeof r.title=="string")}catch(t){if(t.code!=="ENOENT")throw t}}list(){return[...this.items]}get(t){return this.items.find(r=>r.id===t)}async add(t,r=!1){if(!Pt(t)||t.includes("\0"))throw new Error("\u8BF7\u8F93\u5165\u5B8C\u6574\u7684\u76EE\u5F55\u8DEF\u5F84");r&&await de(t,{recursive:!0});let i=await wt(t);if(!(await vt(i)).isDirectory())throw new Error("\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55");return this.mutate(async()=>{let a=this.items.find(l=>l.path===i);if(a)return a;let p={id:le(),path:i,title:bt(i)||i},n=[p,...this.items];return await this.save(n),this.items=n,p})}async remove(t){await this.mutate(async()=>{if(!this.get(t))throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");let r=this.items.filter(i=>i.id!==t);await this.save(r),this.items=r})}mutate(t){let r=this.mutationChain.then(t,t);return this.mutationChain=r.then(()=>{},()=>{}),r}async save(t){await de(St(this.file),{recursive:!0});let r=`${this.file}.${le()}.tmp`;try{await kt(r,JSON.stringify(t,null,2),{mode:384}),await ht(r,this.file)}catch(i){throw await yt(r,{force:!0}),i}}};function pe(e){return xt(e,"pi-web","workspaces.json")}import{createAgentSession as Ct,DefaultResourceLoader as Et,getAgentDir as At,SessionManager as V}from"@earendil-works/pi-coding-agent";import{realpath as me}from"node:fs/promises";import{realpath as ue}from"node:fs/promises";import{SessionManager as It}from"@earendil-works/pi-coding-agent";async function M(e){let t=await ue(e),r=await It.list(t),i=await Promise.all(r.map(async a=>a.cwd!==""&&await ue(a.cwd).catch(()=>null)===t));return r.filter((a,p)=>i[p])}var j=class{active=null;detach=null;cwd=null;lastStreamAt=0;publish;fallbackModel;constructor(t,r){this.publish=t,this.fallbackModel=r}get session(){return this.active}get path(){return this.cwd}async open(t,r){if(this.active&&!this.active.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A");let i=await me(t),a;if(r==="new")a=V.create(i);else if(r==="continue"){let c=(await M(i))[0];a=c?V.open(c.path):V.create(i)}else a=V.open(r.sessionFile);if(await me(a.getCwd())!==i)throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");let p=a.buildSessionProjection().model?void 0:this.active?.model??this.fallbackModel(),n=new Et({cwd:i,agentDir:At(),noExtensions:!0});await n.reload();let{session:l}=await Ct({cwd:i,sessionManager:a,model:p,resourceLoader:n});this.detach?.(),this.active?.dispose(),this.active=l,this.cwd=i,this.detach=l.subscribe(c=>{if(c.type==="message_update"&&c.message.role==="assistant"){let g=Date.now();g-this.lastStreamAt>=60&&(this.lastStreamAt=g,this.publish({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(c.message.timestamp).toISOString(),blocks:C(c.message.content)}}))}(c.type==="message_end"||c.type==="agent_start"||c.type==="agent_settled"||c.type==="session_info_changed")&&(c.type==="message_end"&&c.message.role==="assistant"&&this.publish({type:"stream",message:null}),this.publish({type:"snapshot",session:this.snapshot()}))}),this.publish({type:"stream",message:null}),this.publish({type:"snapshot",session:this.snapshot()})}snapshot(){let t=this.active;if(!t||!this.cwd)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A\u4F1A\u8BDD");let r=t.sessionManager.getBranch().flatMap(i=>{let a=U(i);return a?[a]:[]});return{schemaVersion:1,sessionId:t.sessionManager.getSessionId(),cwd:this.cwd,name:$(t.sessionManager.getSessionName(),r),model:t.model?`${t.model.provider}/${t.model.id}`:null,thinkingLevel:t.thinkingLevel,thinkingLevels:t.getAvailableThinkingLevels(),idle:t.isIdle,contextUsage:t.getContextUsage()??null,messages:r}}async send(t,r=[]){if(!this.active||!this.active.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let i=this.active,a=!1,p,n,l=new Promise((c,g)=>{p=c,n=g});i.prompt(t,{images:r,preflightResult:c=>{c&&(a=!0,p())}}).then(()=>{a||p()}).catch(c=>{a?this.publish({type:"error",message:c instanceof Error?c.message:"Pi \u8BF7\u6C42\u5931\u8D25"}):n(c)}),await l}async stop(){await this.active?.abort()}async models(){return(await this.active?.modelRuntime.getAvailable()??[]).map(r=>({provider:r.provider,id:r.id,name:r.name}))}async setModel(t,r){if(!this.active||!this.active.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let i=this.active.modelRuntime.getModel(t,r);if(!i)throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");await this.active.setModel(i),this.publish({type:"snapshot",session:this.snapshot()})}dispose(){this.detach?.(),this.active?.dispose(),this.detach=null,this.active=null,this.cwd=null}};import{basename as F,dirname as Mt}from"node:path";function ge(e,t){let r=i=>t[i].map(a=>({name:i==="skills"&&F(a.path).toLowerCase()==="skill.md"?F(Mt(a.path)):F(a.path),path:a.path,source:a.metadata.source,scope:a.metadata.scope,enabled:a.enabled}));return{packages:e.map(i=>({name:i.source,path:i.installedPath??"",source:i.source,scope:i.scope,enabled:!!i.installedPath})),extensions:r("extensions"),skills:r("skills")}}import{execFile as Tt}from"node:child_process";var Lt=(e,t)=>new Promise((r,i)=>{Tt(e,[...t],{windowsHide:!0},a=>{a?i(a):r()})});async function fe(e,t=process.platform,r=process.env,i=Lt){if(r.SSH_CONNECTION||r.SSH_TTY||r.SSH_CLIENT||t==="linux"&&!r.DISPLAY&&!r.WAYLAND_DISPLAY)return!1;let a=t==="darwin"?"open":t==="linux"?"xdg-open":t==="win32"?"explorer.exe":null;return a===null?!1:(await i(a,[e]),!0)}var Dt=Vt(Wt(jt(import.meta.url)),"../web/dist"),Ot=Symbol.for("pi-web.bridge-state"),s=globalThis[Ot]??={bridge:null,current:null,commandContext:null,pi:null,replacementContext:null,replacementSessionId:null,lastStreamAt:0,workspaces:null,workspaceSessions:null,selected:"tui",activeWorkspaceId:null},Ut=null;function $t(){return Ut??=Rt.create({refreshOnCreate:!1})}var R=new Map;async function H(){let e=await $t(),t=s.selected==="tui"?s.current?.modelRegistry:void 0,r=new Set(t?.getRegisteredProviderIds()??[]);for(let i of R.keys())r.has(i)||(e.unregisterProvider(i),R.delete(i));for(let i of r){let a=t?.getRegisteredNativeProvider(i),p=t?.getRegisteredProviderConfig(i),n=a??p;!n||R.get(i)===n||(a?e.registerNativeProvider(a):p&&e.registerProvider(i,p),R.set(i,n))}return await e.refresh({allowNetwork:!1}),e}function k(){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 ce(s.current,s.current.sessionManager.getSessionName())}function P(e){if(k().sessionId!==e)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362")}async function he(){let e=s.workspaces?.list()??[],t=k(),r=await B(t.cwd).catch(()=>t.cwd),i=(await Promise.all(e.map(async a=>{let n=(await M(a.path).catch(()=>[])).map(l=>({id:l.id,workspaceId:a.id,path:l.path,name:l.name||l.firstMessage?.slice(0,50)||"\u5F53\u524D\u4F1A\u8BDD",modified:l.modified.toISOString()}));return a.path===r&&!n.some(l=>l.id===t.sessionId)&&n.unshift({id:t.sessionId,workspaceId:a.id,path:null,name:t.name,modified:new Date().toISOString()}),n}))).flat();return{items:e,activeId:s.activeWorkspaceId,sessions:i}}async function x(){s.bridge&&s.bridge.publish({type:"workspaces",value:await he()})}async function J(e,t=!1){let r=s.workspaces?.get(e);if(!r)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(await B(r.path),!t&&s.current&&r.path===await B(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=e,s.bridge?.publish({type:"stream",message:null}),s.bridge?.publish({type:"snapshot",session:k()})}else{if(!s.workspaceSessions)throw new Error("Pi \u5DE5\u4F5C\u533A\u670D\u52A1\u4E0D\u53EF\u7528");await s.workspaceSessions.open(r.path,t?"new":"continue"),s.selected="sdk",s.activeWorkspaceId=e,s.bridge?.publish({type:"snapshot",session:k()})}await x()}function I(e){let t=s.current;if(t===null||t.sessionManager.getSessionId()!==e)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");return t}function S(e){s.current=e,s.selected==="tui"&&s.bridge?.publish({type:"snapshot",session:k()})}function ye(){if(s.current===null)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let e=s.selected==="sdk"?s.workspaceSessions?.path:s.current.cwd;if(!e)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A");let t=s.selected==="tui"?s.current.isProjectTrusted():s.workspaceSessions?.session?.settingsManager.isProjectTrusted()??!1;return Bt.create(e,void 0,{projectTrusted:t})}async function ve(){let e=ye(),t=a=>({packages:(a.packages??[]).map(p=>typeof p=="string"?p:p.source),extensions:a.extensions??[],skills:a.skills??[]}),r=new we({cwd:k().cwd,agentDir:_(),settingsManager:e}),i=ge(r.listConfiguredPackages(),await r.resolve(async()=>"skip"));return{projectTrusted:e.isProjectTrusted(),global:t(e.getGlobalSettings()),project:t(e.getProjectSettings()),installed:i}}async function Ft(e){P(e.sessionId);let t=s.selected==="tui"?I(e.sessionId):null;if(t?!t.isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let r=ye();if(e.scope==="project"&&!r.isProjectTrusted())throw new Error("\u5F53\u524D\u9879\u76EE\u5C1A\u672A\u53D7\u4FE1\u4EFB\uFF0C\u65E0\u6CD5\u4FEE\u6539\u9879\u76EE\u8BBE\u7F6E");let i=e.value.trim(),a=e.scope==="project"?r.getProjectSettings():r.getGlobalSettings();if(e.kind==="packages"){let p=new we({cwd:k().cwd,agentDir:_(),settingsManager:r});e.action==="add"?await p.installAndPersist(i,{local:e.scope==="project"}):await p.removeAndPersist(i,{local:e.scope==="project"})}else if(e.kind==="extensions"){let p=a.extensions??[],n=e.action==="add"?[...new Set([...p,i])]:p.filter(l=>l!==i);e.scope==="project"?r.setProjectExtensionPaths(n):r.setExtensionPaths(n)}else{let p=a.skills??[],n=e.action==="add"?[...new Set([...p,i])]:p.filter(l=>l!==i);e.scope==="project"?r.setProjectSkillPaths(n):r.setSkillPaths(n)}return await r.flush(),s.selected==="tui"?(s.commandContext&&await s.commandContext.reload(),s.current&&S(s.current)):(await s.workspaceSessions?.session?.resourceLoader.reload(),s.workspaceSessions?.session?.refreshContext()),await ve()}function Ht(e,t=fe){s.pi=e,e.on("session_start",(r,i)=>{s.replacementSessionId!==i.sessionManager.getSessionId()&&(s.replacementContext=null,s.replacementSessionId=null),S(i),s.selected==="tui"&&s.workspaces&&s.workspaces.add(i.cwd).then(async a=>{s.selected!=="tui"||s.current?.sessionManager.getSessionId()!==i.sessionManager.getSessionId()||(s.activeWorkspaceId=a.id,await x())}).catch(a=>{s.bridge?.publish({type:"error",message:a instanceof Error?a.message:"\u65E0\u6CD5\u6CE8\u518C\u5F53\u524D\u5DE5\u4F5C\u533A"})})}),e.on("agent_start",(r,i)=>S(i)),e.on("agent_end",(r,i)=>S(i)),e.on("agent_settled",(r,i)=>S(i)),e.on("model_select",(r,i)=>S(i)),e.on("thinking_level_select",(r,i)=>S(i)),e.on("message_end",(r,i)=>{s.selected==="tui"&&r.message.role==="assistant"&&s.bridge?.publish({type:"stream",message:null}),S(i),s.selected==="tui"&&x()}),e.on("session_info_changed",(r,i)=>S(i)),e.on("message_update",(r,i)=>{if(s.current=i,s.selected!=="tui"||r.message.role!=="assistant"||s.bridge===null)return;let a=Date.now();a-s.lastStreamAt<60||(s.lastStreamAt=a,s.bridge.publish({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(r.message.timestamp).toISOString(),blocks:C(r.message.content)}}))}),e.on("session_shutdown",r=>{if(s.current=null,r.reason==="new"||r.reason==="resume"||r.reason==="fork")return;let i=s.bridge;s.bridge=null,s.commandContext=null,s.replacementContext=null,s.replacementSessionId=null,s.pi=null,s.workspaceSessions?.dispose(),s.workspaceSessions=null,s.selected="tui",s.activeWorkspaceId=null,i&&i.close()}),e.registerCommand("web",{description:"Open the current Pi session in a local web interface",handler:async(r,i)=>{s.current=i,s.commandContext=i,s.pi=e,s.workspaces===null&&(s.workspaces=new N(pe(_())),await s.workspaces.load());let a=await s.workspaces.add(i.cwd);if(s.selected==="tui"&&(s.activeWorkspaceId=a.id),s.bridge&&s.bridge.protocolVersion!==3){let n=s.bridge;s.bridge=null,await n.close()}s.bridge===null&&(s.workspaceSessions=new j(n=>{s.selected==="sdk"&&(s.bridge?.publish(n),n.type==="snapshot"&&n.session.idle&&x())},()=>s.current?.model),s.bridge=await oe({snapshot:k,image(n,l,c){P(n);let y=(s.selected==="sdk"?s.workspaceSessions?.session?.sessionManager.getBranch():s.current?.sessionManager.getBranch())?.find(d=>d.id===l);if(y?.type!=="message"||y.message.role!=="user"||!Array.isArray(y.message.content))return null;let f=y.message.content[c];return f?.type!=="image"?null:{data:Buffer.from(f.data,"base64"),mimeType:f.mimeType}},async workspaces(){return he()},async addWorkspace(n,l){let c=await s.workspaces.add(n,l);try{await J(c.id,!0)}catch(g){throw await x(),g}},async selectWorkspace(n){await J(n)},async newSessionInWorkspace(n){await J(n,!0)},async removeWorkspace(n){if(n===s.activeWorkspaceId)throw new Error("\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A");await s.workspaces.remove(n),await x()},async selectSession(n,l,c){let g=s.workspaces?.get(n);if(!g)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(l===s.current?.sessionManager.getSessionId()&&g.path===await B(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=n,s.bridge?.publish({type:"snapshot",session:k()})}else{if(s.selected==="sdk"&&s.workspaceSessions?.session?.sessionManager.getSessionId()===l&&s.workspaceSessions.path===g.path)return;if(!(await M(g.path)).some(f=>f.id===l&&f.path===c))throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");await s.workspaceSessions.open(g.path,{sessionFile:c}),s.selected="sdk",s.activeWorkspaceId=n,s.bridge?.publish({type:"snapshot",session:k()})}await x()},async models(){if(s.selected==="sdk")return s.workspaceSessions?.models()??[];let n=s.current;if(!n)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let l=n.scopedModels?.map(c=>`${c.model.provider}/${c.model.id}`)??[];return n.modelRegistry.getAvailable().filter(c=>l.length===0||l.includes(`${c.provider}/${c.id}`)).map(c=>({provider:c.provider,id:c.id,name:c.name}))},async providers(){let n=await H();return n.getProviders().map(l=>({id:l.id,name:l.name,configured:n.getProviderAuthStatus(l.id).configured,methods:[l.auth.apiKey?.login?"api_key":null,l.auth.oauth?"oauth":null].filter(c=>c!==null)}))},async loginProvider(n,l,c){let g=await H();await g.login(n,l,c),await g.refresh({providers:[n],allowNetwork:!1}),await s.current?.modelRegistry.refresh({providers:[n],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[n],allowNetwork:!1})},async addCustomProvider(n,l){if(P(n),s.selected==="tui"?!I(n).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let c=await H();if(c.getProvider(l.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");await se(Nt(_(),"models.json"),l),await c.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(n=>n.name!=="web").map(n=>({name:n.name,description:n.description})):[]},async compact(n){if(P(n),s.selected==="sdk"){let c=s.workspaceSessions?.session;if(!c||!c.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");await c.compact(),s.bridge?.publish({type:"snapshot",session:k()});return}let l=I(n);if(!l.isIdle())throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");l.compact()},async setModel(n,l,c){if(P(n),s.selected==="sdk"){await s.workspaceSessions.setModel(l,c);return}let g=I(n);if(!g.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let y=g.modelRegistry.find(l,c);if(!y||!g.modelRegistry.getAvailable().some(f=>f.provider===l&&f.id===c))throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");if(!s.pi||!await s.pi.setModel(y))throw new Error("\u6A21\u578B\u63D0\u4F9B\u65B9\u672A\u914D\u7F6E\u8BA4\u8BC1");S(g)},async setThinkingLevel(n,l){if(P(n),!["off","minimal","low","medium","high","xhigh"].includes(l))throw new Error("\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548");if(s.selected==="sdk"){let y=s.workspaceSessions?.session;if(!y||!y.isIdle||!y.getAvailableThinkingLevels().includes(l))throw new Error("\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6");y.setThinkingLevel(l),s.bridge?.publish({type:"snapshot",session:k()});return}let g=I(n);if(!g.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!g.model||!_t(g.model).includes(l))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(l),S(g)},config:ve,updateConfig:Ft,async send(n,l,c=[]){if(P(n),s.selected==="sdk"){await s.workspaceSessions.send(l,c);return}if(!I(n).isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(s.replacementContext!==null&&s.replacementSessionId===n){await s.replacementContext.sendUserMessage(c.length?[{type:"text",text:l},...c]:l,{expandPromptTemplates:!0});return}if(s.pi===null)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");s.pi.sendUserMessage(c.length?[{type:"text",text:l},...c]:l,{expandPromptTemplates:!0})},abort(n){P(n),s.selected==="sdk"?s.workspaceSessions.stop():I(n).abort()},async newSession(n){if(P(n),s.selected==="sdk"){let g=s.workspaces?.get(s.activeWorkspaceId??"");if(!g)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");await s.workspaceSessions.open(g.path,"new"),await x();return}if(!I(n).isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(s.commandContext===null)throw new Error("\u8BF7\u5728 Pi \u4E2D\u91CD\u65B0\u8F93\u5165 /web");if((await s.commandContext.newSession({withSession:async g=>{s.commandContext=g,s.replacementContext=g,s.replacementSessionId=g.sessionManager.getSessionId(),s.current=g}})).cancelled)throw new Error("\u65B0\u4F1A\u8BDD\u5DF2\u53D6\u6D88");await x()}},Dt));let p=await t(s.bridge.url).catch(()=>!1);i.ui.notify(`pi-webapp: ${s.bridge.url}`,p?"info":"warning"),i.ui.setStatus("pi-webapp","Web \u5DF2\u542F\u52A8 \xB7 /web \u91CD\u65B0\u6253\u5F00")}})}export{Ht as default};
|
|
6
|
+
`),Ne=await Promise.all(y.filter(b=>["image/png","image/jpeg","image/webp","image/gif"].includes(b.mediaType)).map(oe));await t.send(d.sessionId,E,Ne);for(let b of w)o.delete(b)}else if(f==="/api/compact"){if(!t.compact)throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u652F\u6301\u538B\u7F29");await t.compact(d.sessionId)}else f==="/api/abort"?t.abort(d.sessionId):await t.newSession(d.sessionId);m(c,202,{accepted:!0})}catch(d){let w=d instanceof Error?d.message:"\u8BF7\u6C42\u5931\u8D25";m(c,w==="\u4F1A\u8BDD\u5DF2\u5207\u6362"?409:400,{error:w})}return}m(c,404,{error:"\u672A\u627E\u5230"})});return a=`http://127.0.0.1:${await Rt(u)}`,{protocolVersion:3,url:`${a}/#${i}`,publish(g){if(g.type==="snapshot")for(let[f,C]of o)C.sessionId!==g.session.sessionId&&o.delete(f);let c=`${JSON.stringify(g)}
|
|
7
|
+
`;for(let f of p)f.write(c)},async close(){l.close();for(let g of p)g.end();p.clear(),await new Promise((g,c)=>u.close(f=>f?c(f):g()))}}}import{getSupportedThinkingLevels as Vt}from"@earendil-works/pi-ai";function he(t){let e=[],i=t;for(;;){let r=/(^|\n\n)附件 ("(?:\\.|[^"\\])*"):([^\n]+)$/u.exec(i);if(!r||!/[\\/]pi-web[\\/]attachments[\\/][a-f0-9]{64}[\\/]/u.test(r[3]))break;let n;try{n=JSON.parse(r[2])}catch{break}e.unshift({name:n,image:/\.(?:png|jpe?g|webp|gif)$/iu.test(n)}),i=i.slice(0,r.index)}return{text:i,attachments:e}}function M(t){return typeof t=="string"?[{kind:"text",text:t}]:t.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 $(t){if(t.type==="custom_message")return t.display?{id:t.id,role:"notice",timestamp:t.timestamp,blocks:M(t.content)}:null;if(t.type!=="message")return null;let{message:e}=t;return e.role==="user"||e.role==="assistant"?{id:t.id,role:e.role,timestamp:t.timestamp,blocks:M(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:t.id,role:"tool",timestamp:t.timestamp,blocks:M(e.content),isError:e.isError,toolCallId:e.toolCallId,toolName:e.toolName}:null}function F(t,e){let i=t?.trim();if(i)return i;let r=e.find(p=>p.role==="user"),n=he(r?.blocks.find(p=>p.kind==="text")?.text??"").text.replace(/\s+/g," ").trim();return n?n.slice(0,50):"\u5F53\u524D\u4F1A\u8BDD"}function ye(t,e){let i=t.sessionManager.getBranch().flatMap(r=>{let n=$(r);return n?[n]:[]});return{schemaVersion:1,sessionId:t.sessionManager.getSessionId(),cwd:t.cwd,name:F(e,i),model:t.model?`${t.model.provider}/${t.model.id}`:null,thinkingLevel:t.thinkingLevel??null,thinkingLevels:t.model?Vt(t.model):["off"],idle:t.isIdle(),contextUsage:t.getContextUsage()??null,messages:i}}import{randomUUID as H}from"node:crypto";import{mkdir as ve,readFile as _t,realpath as ke,rename as Bt,rm as Ot,stat as be,writeFile as Ut}from"node:fs/promises";import{basename as Pe,dirname as Dt,isAbsolute as Se,join as $t}from"node:path";var R=class{items=[];hiddenPaths=[];mutationChain=Promise.resolve();file;constructor(e){this.file=e}async load(){try{let e=JSON.parse(await _t(this.file,"utf8")),i,r=[];if(Array.isArray(e)?i=e:e&&typeof e=="object"&&"version"in e&&e.version===2&&"items"in e&&"hiddenPaths"in e&&(i=e.items,r=e.hiddenPaths),!Array.isArray(i)||!Array.isArray(r))throw new Error("\u5DE5\u4F5C\u533A\u8BB0\u5F55\u65E0\u6548");this.items=i.filter(n=>typeof n=="object"&&n!==null&&typeof n.id=="string"&&typeof n.path=="string"&&typeof n.title=="string"),this.hiddenPaths=r.filter(n=>typeof n=="string")}catch(e){if(e.code!=="ENOENT")throw e}}list(){return[...this.items]}get(e){return this.items.find(i=>i.id===e)}async add(e,i=!1){if(!Se(e)||e.includes("\0"))throw new Error("\u8BF7\u8F93\u5165\u5B8C\u6574\u7684\u76EE\u5F55\u8DEF\u5F84");i&&await ve(e,{recursive:!0});let r=await ke(e);if(!(await be(r)).isDirectory())throw new Error("\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55");return this.mutate(async()=>{let n=this.hiddenPaths.filter(a=>a!==r),p=this.items.find(a=>a.path===r);if(p)return n.length!==this.hiddenPaths.length&&(await this.save(this.items,n),this.hiddenPaths=n),p;let o={id:H(),path:r,title:Pe(r)||r},l=[o,...this.items];return await this.save(l,n),this.items=l,this.hiddenPaths=n,o})}async discover(e){let i=(await Promise.all([...new Set(e)].filter(Se).map(async r=>{try{let n=await ke(r);return(await be(n)).isDirectory()?n:null}catch{return null}}))).filter(r=>r!==null);await this.mutate(async()=>{let r=new Set([...this.items.map(o=>o.path),...this.hiddenPaths]),n=[];for(let o of i)r.has(o)||(r.add(o),n.push({id:H(),path:o,title:Pe(o)||o}));if(n.length===0)return;let p=[...this.items,...n];await this.save(p,this.hiddenPaths),this.items=p})}async remove(e){await this.mutate(async()=>{let i=this.get(e);if(!i)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");let r=this.items.filter(p=>p.id!==e),n=[...new Set([...this.hiddenPaths,i.path])];await this.save(r,n),this.items=r,this.hiddenPaths=n})}mutate(e){let i=this.mutationChain.then(e,e);return this.mutationChain=i.then(()=>{},()=>{}),i}async save(e,i){await ve(Dt(this.file),{recursive:!0});let r=`${this.file}.${H()}.tmp`;try{await Ut(r,JSON.stringify({version:2,items:e,hiddenPaths:i},null,2),{mode:384}),await Bt(r,this.file)}catch(n){throw await Ot(r,{force:!0}),n}}};function xe(t){return $t(t,"pi-web","workspaces.json")}import{createAgentSession as Ht,DefaultResourceLoader as Jt,getAgentDir as Gt,SessionManager as V}from"@earendil-works/pi-coding-agent";import{realpath as Ee}from"node:fs/promises";import{realpath as Ie}from"node:fs/promises";import{SessionManager as Ft}from"@earendil-works/pi-coding-agent";async function W(t,e){let i=await Ie(t),r=e??await Ft.listAll(),n=await Promise.all(r.map(async p=>p.cwd!==""&&await Ie(p.cwd).catch(()=>null)===i));return r.filter((p,o)=>n[o])}var _=class{active=null;detach=null;cwd=null;lastStreamAt=0;publish;fallbackModel;constructor(e,i){this.publish=e,this.fallbackModel=i}get session(){return this.active}get path(){return this.cwd}async open(e,i){if(this.active&&!this.active.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F\u518D\u5207\u6362\u5DE5\u4F5C\u533A");let r=await Ee(e),n;if(i==="new")n=V.create(r);else if(i==="continue"){let a=(await W(r))[0];n=a?V.open(a.path):V.create(r)}else n=V.open(i.sessionFile);if(await Ee(n.getCwd())!==r)throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");let p=n.buildSessionProjection().model?void 0:this.active?.model??this.fallbackModel(),o=new Jt({cwd:r,agentDir:Gt(),noExtensions:!0});await o.reload();let{session:l}=await Ht({cwd:r,sessionManager:n,model:p,resourceLoader:o});this.detach?.(),this.active?.dispose(),this.active=l,this.cwd=r,this.detach=l.subscribe(a=>{if(a.type==="message_update"&&a.message.role==="assistant"){let u=Date.now();u-this.lastStreamAt>=60&&(this.lastStreamAt=u,this.publish({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(a.message.timestamp).toISOString(),blocks:M(a.message.content)}}))}(a.type==="message_end"||a.type==="agent_start"||a.type==="agent_settled"||a.type==="session_info_changed")&&(a.type==="message_end"&&a.message.role==="assistant"&&this.publish({type:"stream",message:null}),this.publish({type:"snapshot",session:this.snapshot()}))}),this.publish({type:"stream",message:null}),this.publish({type:"snapshot",session:this.snapshot()})}snapshot(){let e=this.active;if(!e||!this.cwd)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u5DE5\u4F5C\u533A\u4F1A\u8BDD");let i=e.sessionManager.getBranch().flatMap(r=>{let n=$(r);return n?[n]:[]});return{schemaVersion:1,sessionId:e.sessionManager.getSessionId(),cwd:this.cwd,name:F(e.sessionManager.getSessionName(),i),model:e.model?`${e.model.provider}/${e.model.id}`:null,thinkingLevel:e.thinkingLevel,thinkingLevels:e.getAvailableThinkingLevels(),idle:e.isIdle,contextUsage:e.getContextUsage()??null,messages:i}}async send(e,i=[]){if(!this.active||!this.active.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let r=this.active,n=!1,p,o,l=new Promise((a,u)=>{p=a,o=u});r.prompt(e,{images:i,preflightResult:a=>{a&&(n=!0,p())}}).then(()=>{n||p()}).catch(a=>{n?this.publish({type:"error",message:a instanceof Error?a.message:"Pi \u8BF7\u6C42\u5931\u8D25"}):o(a)}),await l}async stop(){await this.active?.abort()}async models(){return(await this.active?.modelRuntime.getAvailable()??[]).map(i=>({provider:i.provider,id:i.id,name:i.name}))}async setModel(e,i){if(!this.active||!this.active.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let r=this.active.modelRuntime.getModel(e,i);if(!r)throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");await this.active.setModel(r),this.publish({type:"snapshot",session:this.snapshot()})}dispose(){this.detach?.(),this.active?.dispose(),this.detach=null,this.active=null,this.cwd=null}};import{basename as J,dirname as Kt}from"node:path";function Ce(t,e){let i=r=>e[r].map(n=>({name:r==="skills"&&J(n.path).toLowerCase()==="skill.md"?J(Kt(n.path)):J(n.path),path:n.path,source:n.metadata.source,scope:n.metadata.scope,enabled:n.enabled}));return{packages:t.map(r=>({name:r.source,path:r.installedPath??"",source:r.source,scope:r.scope,enabled:!!r.installedPath})),extensions:i("extensions"),skills:i("skills")}}import{execFile as zt}from"node:child_process";var Yt=(t,e)=>new Promise((i,r)=>{zt(t,[...e],{windowsHide:!0},n=>{n?r(n):i()})});async function G(t,e=process.platform,i=process.env,r=Yt){if(i.SSH_CONNECTION||i.SSH_TTY||i.SSH_CLIENT||e==="linux"&&!i.DISPLAY&&!i.WAYLAND_DISPLAY)return!1;let n=e==="darwin"?"open":e==="linux"?"xdg-open":e==="win32"?"explorer.exe":null;return n===null?!1:(await r(n,[t]),!0)}var ii=Qt(Xt(Zt(import.meta.url)),"../web/dist"),ri=Symbol.for("pi-web.bridge-state"),s=globalThis[ri]??={bridge:null,current:null,commandContext:null,pi:null,replacementContext:null,replacementSessionId:null,lastStreamAt:0,workspaces:null,workspaceSessions:null,selected:"tui",activeWorkspaceId:null,autoOpened:!1},si=null;function ni(){return si??=qt.create({refreshOnCreate:!1})}var B=new Map;async function A(){let t=await ni(),e=s.selected==="tui"?s.current?.modelRegistry:void 0,i=new Set(e?.getRegisteredProviderIds()??[]);for(let r of B.keys())i.has(r)||(t.unregisterProvider(r),B.delete(r));for(let r of i){let n=e?.getRegisteredNativeProvider(r),p=e?.getRegisteredProviderConfig(r),o=n??p;!o||B.get(r)===o||(n?t.registerNativeProvider(n):p&&t.registerProvider(r,p),B.set(r,o))}return await t.refresh({allowNetwork:!1}),t}function k(){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 ye(s.current,s.current.sessionManager.getSessionName())}function S(t){if(k().sessionId!==t)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362")}async function Te(){let t=s.workspaces?.list()??[],e=k(),i=await O(e.cwd).catch(()=>e.cwd),r=await Ae.listAll(),n=(await Promise.all(t.map(async p=>{let l=(await W(p.path,r).catch(()=>[])).map(a=>({id:a.id,workspaceId:p.id,path:a.path,name:a.name||a.firstMessage?.slice(0,50)||"\u5F53\u524D\u4F1A\u8BDD",modified:a.modified.toISOString()}));return p.path===i&&!l.some(a=>a.id===e.sessionId)&&l.unshift({id:e.sessionId,workspaceId:p.id,path:null,name:e.name,modified:new Date().toISOString()}),l}))).flat();return{items:t,activeId:s.activeWorkspaceId,sessions:n}}async function I(){s.bridge&&s.bridge.publish({type:"workspaces",value:await Te()})}async function z(t,e=!1){let i=s.workspaces?.get(t);if(!i)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(await O(i.path),!e&&s.current&&i.path===await O(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=t,s.bridge?.publish({type:"stream",message:null}),s.bridge?.publish({type:"snapshot",session:k()})}else{if(!s.workspaceSessions)throw new Error("Pi \u5DE5\u4F5C\u533A\u670D\u52A1\u4E0D\u53EF\u7528");await s.workspaceSessions.open(i.path,e?"new":"continue"),s.selected="sdk",s.activeWorkspaceId=t,s.bridge?.publish({type:"snapshot",session:k()})}await I()}function x(t){let e=s.current;if(e===null||e.sessionManager.getSessionId()!==t)throw new Error("\u4F1A\u8BDD\u5DF2\u5207\u6362");return e}function P(t){s.current=t,s.selected==="tui"&&s.bridge?.publish({type:"snapshot",session:k()})}function We(){if(s.current===null)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let t=s.selected==="sdk"?s.workspaceSessions?.path:s.current.cwd;if(!t)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 ei.create(t,void 0,{projectTrusted:e})}async function Le(){let t=We(),e=n=>({packages:(n.packages??[]).map(p=>typeof p=="string"?p:p.source),extensions:n.extensions??[],skills:n.skills??[]}),i=new Me({cwd:k().cwd,agentDir:T(),settingsManager:t}),r=Ce(i.listConfiguredPackages(),await i.resolve(async()=>"skip"));return{projectTrusted:t.isProjectTrusted(),global:e(t.getGlobalSettings()),project:e(t.getProjectSettings()),installed:r}}async function oi(t){S(t.sessionId);let e=s.selected==="tui"?x(t.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 i=We();if(t.scope==="project"&&!i.isProjectTrusted())throw new Error("\u5F53\u524D\u9879\u76EE\u5C1A\u672A\u53D7\u4FE1\u4EFB\uFF0C\u65E0\u6CD5\u4FEE\u6539\u9879\u76EE\u8BBE\u7F6E");let r=t.value.trim(),n=t.scope==="project"?i.getProjectSettings():i.getGlobalSettings();if(t.kind==="packages"){let p=new Me({cwd:k().cwd,agentDir:T(),settingsManager:i});t.action==="add"?await p.installAndPersist(r,{local:t.scope==="project"}):await p.removeAndPersist(r,{local:t.scope==="project"})}else if(t.kind==="extensions"){let p=n.extensions??[],o=t.action==="add"?[...new Set([...p,r])]:p.filter(l=>l!==r);t.scope==="project"?i.setProjectExtensionPaths(o):i.setExtensionPaths(o)}else{let p=n.skills??[],o=t.action==="add"?[...new Set([...p,r])]:p.filter(l=>l!==r);t.scope==="project"?i.setProjectSkillPaths(o):i.setSkillPaths(o)}return await i.flush(),s.selected==="tui"?(s.commandContext&&await s.commandContext.reload(),s.current&&P(s.current)):(await s.workspaceSessions?.session?.resourceLoader.reload(),s.workspaceSessions?.session?.refreshContext()),await Le()}function ai(t,e=G){s.pi=t,t.on("session_start",(r,n)=>{s.replacementSessionId!==n.sessionManager.getSessionId()&&(s.replacementContext=null,s.replacementSessionId=null),P(n),s.selected==="tui"&&s.workspaces&&s.workspaces.add(n.cwd).then(async p=>{s.selected!=="tui"||s.current?.sessionManager.getSessionId()!==n.sessionManager.getSessionId()||(s.activeWorkspaceId=p.id,await I())}).catch(p=>{s.bridge?.publish({type:"error",message:p instanceof Error?p.message:"\u65E0\u6CD5\u6CE8\u518C\u5F53\u524D\u5DE5\u4F5C\u533A"})}),process.env.PI_WEBAPP_AUTO_OPEN==="1"&&n.mode==="tui"&&!s.autoOpened&&(s.autoOpened=!0,i(n).catch(p=>{n.ui.notify(p instanceof Error?p.message:"Web \u542F\u52A8\u5931\u8D25","error")}))}),t.on("agent_start",(r,n)=>P(n)),t.on("agent_end",(r,n)=>P(n)),t.on("agent_settled",(r,n)=>P(n)),t.on("model_select",(r,n)=>P(n)),t.on("thinking_level_select",(r,n)=>P(n)),t.on("message_end",(r,n)=>{s.selected==="tui"&&r.message.role==="assistant"&&s.bridge?.publish({type:"stream",message:null}),P(n),s.selected==="tui"&&I()}),t.on("session_info_changed",(r,n)=>P(n)),t.on("message_update",(r,n)=>{if(s.current=n,s.selected!=="tui"||r.message.role!=="assistant"||s.bridge===null)return;let p=Date.now();p-s.lastStreamAt<60||(s.lastStreamAt=p,s.bridge.publish({type:"stream",message:{id:"stream",role:"assistant",timestamp:new Date(r.message.timestamp).toISOString(),blocks:M(r.message.content)}}))}),t.on("session_shutdown",r=>{if(s.current=null,r.reason==="new"||r.reason==="resume"||r.reason==="fork")return;let n=s.bridge;s.bridge=null,s.commandContext=null,s.replacementContext=null,s.replacementSessionId=null,s.pi=null,s.workspaceSessions?.dispose(),s.workspaceSessions=null,s.selected="tui",s.activeWorkspaceId=null,s.autoOpened=!1,n&&n.close()});let i=async r=>{s.current=r,s.commandContext="newSession"in r?r:null,s.pi=t,s.workspaces===null&&(s.workspaces=new R(xe(T())),await s.workspaces.load());try{await s.workspaces.discover((await Ae.listAll()).map(o=>o.cwd))}catch(o){r.ui.notify(`\u65E0\u6CD5\u8BFB\u53D6\u90E8\u5206 Pi \u5386\u53F2\u5DE5\u4F5C\u533A\uFF1A${o instanceof Error?o.message:String(o)}`,"warning")}let n=await s.workspaces.add(r.cwd);if(s.selected==="tui"&&(s.activeWorkspaceId=n.id),s.bridge&&s.bridge.protocolVersion!==3){let o=s.bridge;s.bridge=null,await o.close()}s.bridge===null&&(s.workspaceSessions=new _(o=>{s.selected==="sdk"&&(s.bridge?.publish(o),o.type==="snapshot"&&o.session.idle&&I())},()=>s.current?.model),s.bridge=await we({snapshot:k,image(o,l,a){S(o);let h=(s.selected==="sdk"?s.workspaceSessions?.session?.sessionManager.getBranch():s.current?.sessionManager.getBranch())?.find(c=>c.id===l);if(h?.type!=="message"||h.message.role!=="user"||!Array.isArray(h.message.content))return null;let g=h.message.content[a];return g?.type!=="image"?null:{data:Buffer.from(g.data,"base64"),mimeType:g.mimeType}},async workspaces(){return Te()},async addWorkspace(o,l){let a=await s.workspaces.add(o,l);try{await z(a.id,!0)}catch(u){throw await I(),u}},async selectWorkspace(o){await z(o)},async newSessionInWorkspace(o){await z(o,!0)},async removeWorkspace(o){if(o===s.activeWorkspaceId)throw new Error("\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A");await s.workspaces.remove(o),await I()},async selectSession(o,l,a){let u=s.workspaces?.get(o);if(!u)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");if(l===s.current?.sessionManager.getSessionId()&&u.path===await O(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=o,s.bridge?.publish({type:"snapshot",session:k()})}else{if(s.selected==="sdk"&&s.workspaceSessions?.session?.sessionManager.getSessionId()===l&&s.workspaceSessions.path===u.path)return;if(!(await W(u.path)).some(g=>g.id===l&&g.path===a))throw new Error("\u4F1A\u8BDD\u4E0D\u5C5E\u4E8E\u8BE5\u5DE5\u4F5C\u533A");await s.workspaceSessions.open(u.path,{sessionFile:a}),s.selected="sdk",s.activeWorkspaceId=o,s.bridge?.publish({type:"snapshot",session:k()})}await I()},async models(){if(s.selected==="sdk")return s.workspaceSessions?.models()??[];let o=s.current;if(!o)throw new Error("\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD");let l=o.scopedModels?.map(a=>`${a.model.provider}/${a.model.id}`)??[];return o.modelRegistry.getAvailable().filter(a=>l.length===0||l.includes(`${a.provider}/${a.id}`)).map(a=>({provider:a.provider,id:a.id,name:a.name}))},async providers(){let o=await A(),l=new Set((await o.listCredentials()).map(a=>a.providerId));return o.getProviders().map(a=>({id:a.id,name:a.name,configured:o.getProviderAuthStatus(a.id).configured,storedCredential:l.has(a.id),methods:[a.auth.apiKey?.login?"api_key":null,a.auth.oauth?"oauth":null].filter(u=>u!==null)}))},async providerModels(o){let l=await A();return me(K(T(),"models.json"),o,l)},async updateProviderModel(o,l,a){if(S(o),s.selected==="tui"?!x(o).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let u=k().model;if(a.action==="remove"&&u===`${l}/${a.id}`)throw new Error("\u8BF7\u5148\u5207\u6362\u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B");if(a.action==="save"&&a.originalId&&a.originalId!==a.model.id&&u===`${l}/${a.originalId}`)throw new Error("\u8BF7\u5148\u5207\u6362\u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B");let h=await A();await fe(K(T(),"models.json"),l,a,h),await h.refresh({providers:[l],allowNetwork:!1}),await s.current?.modelRegistry.refresh({providers:[l],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[l],allowNetwork:!1});let g=a.action==="save"?a.model.id:a.action==="base_url"&&u?.startsWith(`${l}/`)?u.slice(l.length+1):null;if(g&&u===`${l}/${g}`)if(s.selected==="sdk")try{await s.workspaceSessions.setModel(l,g)}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 c=x(o),f=c.modelRegistry.find(l,g);if(!f||!s.pi||!await s.pi.setModel(f))throw new Error("\u6A21\u578B\u5DF2\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u8BE5\u6A21\u578B\u4EE5\u5E94\u7528\u65B0\u53C2\u6570");P(c)}},async logoutProvider(o,l){if(S(o),s.selected==="tui"?!x(o).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let a=await A();if(!(await a.listCredentials()).some(u=>u.providerId===l))throw new Error("\u8BE5\u63D0\u4F9B\u65B9\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u8BA4\u8BC1");await a.logout(l),await s.current?.modelRegistry.refresh({providers:[l],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[l],allowNetwork:!1})},async loginProvider(o,l,a){let u=await A();await u.login(o,l,ae(o,l,a)),await u.refresh({providers:[o],allowNetwork:!1}),await s.current?.modelRegistry.refresh({providers:[o],allowNetwork:!1}),await s.workspaceSessions?.session?.modelRuntime.refresh({providers:[o],allowNetwork:!1})},async addCustomProvider(o,l){if(S(o),s.selected==="tui"?!x(o).isIdle():!s.workspaceSessions?.session?.isIdle)throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let a=await A();if(a.getProvider(l.id))throw new Error("\u63D0\u4F9B\u65B9\u5DF2\u5B58\u5728");await de(K(T(),"models.json"),l),await a.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(o=>o.name!=="web").map(o=>({name:o.name,description:o.description})):[]},async compact(o){if(S(o),s.selected==="sdk"){let a=s.workspaceSessions?.session;if(!a||!a.isIdle)throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");await a.compact(),s.bridge?.publish({type:"snapshot",session:k()});return}let l=x(o);if(!l.isIdle())throw new Error("\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");l.compact()},async setModel(o,l,a){if(S(o),s.selected==="sdk"){await s.workspaceSessions.setModel(l,a);return}let u=x(o);if(!u.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");let h=u.modelRegistry.find(l,a);if(!h||!u.modelRegistry.getAvailable().some(g=>g.provider===l&&g.id===a))throw new Error("\u6A21\u578B\u4E0D\u53EF\u7528");if(!s.pi||!await s.pi.setModel(h))throw new Error("\u6A21\u578B\u63D0\u4F9B\u65B9\u672A\u914D\u7F6E\u8BA4\u8BC1");P(u)},async setThinkingLevel(o,l){if(S(o),!["off","minimal","low","medium","high","xhigh"].includes(l))throw new Error("\u63A8\u7406\u5F3A\u5EA6\u65E0\u6548");if(s.selected==="sdk"){let h=s.workspaceSessions?.session;if(!h||!h.isIdle||!h.getAvailableThinkingLevels().includes(l))throw new Error("\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u6B64\u63A8\u7406\u5F3A\u5EA6");h.setThinkingLevel(l),s.bridge?.publish({type:"snapshot",session:k()});return}let u=x(o);if(!u.isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(!u.model||!ti(u.model).includes(l))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(l),P(u)},config:Le,updateConfig:oi,async send(o,l,a=[]){if(S(o),s.selected==="sdk"){await s.workspaceSessions.send(l,a);return}if(!x(o).isIdle())throw new Error("Pi \u6B63\u5728\u8FD0\u884C\uFF0C\u8BF7\u7B49\u5F85\u5F53\u524D\u56DE\u590D\u7ED3\u675F");if(s.replacementContext!==null&&s.replacementSessionId===o){await s.replacementContext.sendUserMessage(a.length?[{type:"text",text:l},...a]:l,{expandPromptTemplates:!0});return}if(s.pi===null)throw new Error("Pi \u4F1A\u8BDD\u4E0D\u53EF\u7528");s.pi.sendUserMessage(a.length?[{type:"text",text:l},...a]:l,{expandPromptTemplates:!0})},abort(o){S(o),s.selected==="sdk"?s.workspaceSessions.stop():x(o).abort()},async newSession(o){if(S(o),s.selected==="sdk"){let u=s.workspaces?.get(s.activeWorkspaceId??"");if(!u)throw new Error("\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");await s.workspaceSessions.open(u.path,"new"),await I();return}let l=x(o);if(!l.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(l.cwd,"new"),s.selected="sdk",s.bridge?.publish({type:"snapshot",session:k()}),await I();return}if((await s.commandContext.newSession({withSession:async u=>{s.commandContext=u,s.replacementContext=u,s.replacementSessionId=u.sessionManager.getSessionId(),s.current=u}})).cancelled)throw new Error("\u65B0\u4F1A\u8BDD\u5DF2\u53D6\u6D88");await I()}},ii));let p=await e(s.bridge.url).catch(()=>!1);r.ui.notify(`pi-webapp: ${s.bridge.url}`,p?"info":"warning"),r.ui.setStatus("pi-webapp","Web \u5DF2\u542F\u52A8 \xB7 /web \u91CD\u65B0\u6253\u5F00")};t.registerCommand("web",{description:"Open the current Pi session in a local web interface",handler:async(r,n)=>i(n)})}export{ai as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-webapp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A browser interface for Pi with live chat, workspaces, models, and attachments",
|
|
6
6
|
"repository": {
|
|
@@ -11,14 +11,18 @@
|
|
|
11
11
|
"keywords": [
|
|
12
12
|
"pi-package"
|
|
13
13
|
],
|
|
14
|
+
"bin": {
|
|
15
|
+
"pi-webapp": "./bin/pi-webapp.mjs"
|
|
16
|
+
},
|
|
14
17
|
"pi": {
|
|
15
|
-
"image": "https://unpkg.com/pi-webapp@0.1.
|
|
18
|
+
"image": "https://unpkg.com/pi-webapp@0.1.3/assets/cover-webapp.png",
|
|
16
19
|
"extensions": [
|
|
17
20
|
"./dist/extension.js"
|
|
18
21
|
]
|
|
19
22
|
},
|
|
20
23
|
"files": [
|
|
21
24
|
"assets/cover-webapp.png",
|
|
25
|
+
"bin",
|
|
22
26
|
"dist",
|
|
23
27
|
"web/dist",
|
|
24
28
|
"README.md",
|
|
@@ -26,13 +30,16 @@
|
|
|
26
30
|
"LICENSE"
|
|
27
31
|
],
|
|
28
32
|
"scripts": {
|
|
33
|
+
"start": "npm run build && node bin/pi-webapp.mjs",
|
|
34
|
+
"status": "node bin/pi-webapp.mjs status",
|
|
35
|
+
"stop": "node bin/pi-webapp.mjs stop",
|
|
29
36
|
"check": "tsc --noEmit && tsc -p web/tsconfig.json",
|
|
30
37
|
"test": "node --experimental-strip-types --test test/*.test.ts",
|
|
31
38
|
"build": "npm run build:web && npm run build:extension",
|
|
32
39
|
"build:web": "vite build",
|
|
33
40
|
"build:extension": "esbuild extension/index.ts --bundle --platform=node --format=esm --target=node22 --packages=external --minify --outfile=dist/extension.js",
|
|
34
41
|
"prepack": "npm run build",
|
|
35
|
-
"prepublishOnly": "npm run check && npm run test"
|
|
42
|
+
"prepublishOnly": "npm run check && npm run build && npm run test"
|
|
36
43
|
},
|
|
37
44
|
"publishConfig": {
|
|
38
45
|
"access": "public"
|
|
@@ -57,6 +64,7 @@
|
|
|
57
64
|
"dependencies": {
|
|
58
65
|
"anser": "^2.3.5",
|
|
59
66
|
"clsx": "^2.1.1",
|
|
67
|
+
"cross-spawn": "^7.0.6",
|
|
60
68
|
"react": "^18.3.1",
|
|
61
69
|
"react-dom": "^18.3.1",
|
|
62
70
|
"react-markdown": "^10.1.0",
|