pi-web-ui 0.76.0 → 0.78.0

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.
@@ -12,10 +12,10 @@
12
12
  <meta name="mobile-web-app-capable" content="yes" />
13
13
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
14
14
  <title>pi-web-ui — pi 编码智能体</title>
15
- <script type="module" crossorigin src="/assets/index-BBvR_HDI.js"></script>
15
+ <script type="module" crossorigin src="/assets/index-SREmjZgY.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="/assets/markdown-Cpo0pNcR.js">
17
17
  <link rel="modulepreload" crossorigin href="/assets/react-CtudoG1_.js">
18
- <link rel="stylesheet" crossorigin href="/assets/index-ChcqaOWi.css">
18
+ <link rel="stylesheet" crossorigin href="/assets/index-CaC1cuAF.css">
19
19
  </head>
20
20
  <body>
21
21
  <div id="root"></div>
package/web/dist/sw.js CHANGED
@@ -79,6 +79,16 @@ function isCachable(request) {
79
79
  return true;
80
80
  }
81
81
 
82
+ function assetContentOk(requestUrl, response) {
83
+ const ct = (response.headers.get("content-type") || "").toLowerCase();
84
+ const path = requestUrl.pathname.toLowerCase();
85
+ if (path.endsWith(".js")) return ct.includes("javascript");
86
+ if (path.endsWith(".css")) return ct.includes("css");
87
+ if (path.endsWith(".svg")) return ct.includes("svg");
88
+ if (path.endsWith(".webmanifest")) return ct.includes("json");
89
+ return true;
90
+ }
91
+
82
92
  self.addEventListener("fetch", (event) => {
83
93
  const { request } = event;
84
94
  if (!isCachable(request)) {
@@ -118,13 +128,18 @@ self.addEventListener("fetch", (event) => {
118
128
  event.respondWith(
119
129
  caches.match(request).then((cached) => {
120
130
  if (cached) return cached;
121
- return fetch(request).then((response) => {
122
- if (response && response.ok) {
123
- const copy = response.clone();
124
- caches.open(STATIC_CACHE).then((cache) => cache.put(request, copy));
125
- }
126
- return response;
127
- });
131
+ return fetch(request)
132
+ .then((response) => {
133
+ // Only cache bytes matching the extension: a missing file falls
134
+ // through to the SPA catch-all (index.html, 200) and must never be
135
+ // stored under an asset URL, or the page stays black until purged.
136
+ if (response && response.ok && assetContentOk(requestUrl, response)) {
137
+ const copy = response.clone();
138
+ caches.open(STATIC_CACHE).then((cache) => cache.put(request, copy));
139
+ }
140
+ return response;
141
+ })
142
+ .catch(() => caches.match(request).then((fallback) => fallback || Response.error()));
128
143
  }),
129
144
  );
130
145
  }
package/web/public/sw.js CHANGED
@@ -79,6 +79,16 @@ function isCachable(request) {
79
79
  return true;
80
80
  }
81
81
 
82
+ function assetContentOk(requestUrl, response) {
83
+ const ct = (response.headers.get("content-type") || "").toLowerCase();
84
+ const path = requestUrl.pathname.toLowerCase();
85
+ if (path.endsWith(".js")) return ct.includes("javascript");
86
+ if (path.endsWith(".css")) return ct.includes("css");
87
+ if (path.endsWith(".svg")) return ct.includes("svg");
88
+ if (path.endsWith(".webmanifest")) return ct.includes("json");
89
+ return true;
90
+ }
91
+
82
92
  self.addEventListener("fetch", (event) => {
83
93
  const { request } = event;
84
94
  if (!isCachable(request)) {
@@ -118,13 +128,18 @@ self.addEventListener("fetch", (event) => {
118
128
  event.respondWith(
119
129
  caches.match(request).then((cached) => {
120
130
  if (cached) return cached;
121
- return fetch(request).then((response) => {
122
- if (response && response.ok) {
123
- const copy = response.clone();
124
- caches.open(STATIC_CACHE).then((cache) => cache.put(request, copy));
125
- }
126
- return response;
127
- });
131
+ return fetch(request)
132
+ .then((response) => {
133
+ // Only cache bytes matching the extension: a missing file falls
134
+ // through to the SPA catch-all (index.html, 200) and must never be
135
+ // stored under an asset URL, or the page stays black until purged.
136
+ if (response && response.ok && assetContentOk(requestUrl, response)) {
137
+ const copy = response.clone();
138
+ caches.open(STATIC_CACHE).then((cache) => cache.put(request, copy));
139
+ }
140
+ return response;
141
+ })
142
+ .catch(() => caches.match(request).then((fallback) => fallback || Response.error()));
128
143
  }),
129
144
  );
130
145
  }
@@ -1,6 +0,0 @@
1
- import{a as l,j as n}from"./markdown-Cpo0pNcR.js";import{u as P,b as O,T as M,a as W,F as Y,c as z,d as Z,e as H,f as ee,g as ne,h as te,i as se,r as ae}from"./index-BBvR_HDI.js";import{D as re,o as ie}from"./xterm-B96xOxS9.js";import"./react-CtudoG1_.js";function le(t){let c=null;return{clean:t.replace(/\r?\n?\[pi-term-exit:(-?\d+)\]\r?\n?/g,(a,x)=>(c=Number(x),`\r
2
- `)).replace(/\r?\n?\x1b\[90m\[(?:进程已退出,退出码 |Process exited with code )-?\d+\]\x1b\[0m\r?\n?/g,`\r
3
- `),exitCode:c}}function ce({conversationId:t,terminalId:c,command:p,cwd:a,title:x,active:u,running:v,exitCode:j,send:h,register:C}){const T=l.useRef(null),y=l.useRef(null),{locale:o}=P(),N=l.useRef(o);N.current=o;const E=p?JSON.stringify(p):"";l.useEffect(()=>{const m=T.current;if(!m)return;const r=new re({theme:O(),fontFamily:'"SF Mono", "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace',fontSize:13,cursorBlink:!0,scrollback:8e3}),b=new ie;r.loadAddon(b),r.open(m),y.current={term:r,fit:b},u&&r.focus();const g=()=>{r.options.theme=O()};window.addEventListener(M,g),r.attachCustomKeyEventHandler(d=>{if(d.type!=="keydown")return!0;const S=d.key?.toLowerCase();if((d.ctrlKey||d.metaKey)&&S==="v")return!1;if(d.ctrlKey&&!d.shiftKey&&!d.altKey&&S==="c"&&r.hasSelection()){const D=r.textarea;return D&&(D.value=r.getSelection(),D.select()),!1}return!0});const _=C(t,c,{write:d=>r.write(le(d).clean),dispose:()=>r.dispose()}),$=()=>{try{b.fit(),h({type:"terminal_resize",terminalId:c,conversationId:t,cols:r.cols,rows:r.rows})}catch{}},B=requestAnimationFrame(()=>{try{b.fit()}catch{}h(p?{type:"run_command",terminalId:c,conversationId:t,command:p,cols:r.cols,rows:r.rows}:{type:"terminal_create",terminalId:c,title:x,locale:N.current,conversationId:t,cwd:a,cols:r.cols,rows:r.rows})}),R=r.onData(d=>{h({type:"terminal_input",terminalId:c,conversationId:t,data:d})});let k=null;return typeof ResizeObserver<"u"&&(k=new ResizeObserver(()=>{m.offsetWidth>0&&m.offsetHeight>0&&$()}),k.observe(m)),()=>{cancelAnimationFrame(B),R.dispose(),window.removeEventListener(M,g),k?.disconnect(),_(),r.dispose(),y.current=null}},[t,c,E,h,C]),l.useEffect(()=>{if(!u)return;const m=requestAnimationFrame(()=>{const r=y.current;if(r){try{r.fit.fit(),h({type:"terminal_resize",terminalId:c,conversationId:t,cols:r.term.cols,rows:r.term.rows})}catch{}r.term.focus()}});return()=>cancelAnimationFrame(m)},[u]);const{t:F}=P(),f=l.useRef(void 0);return l.useEffect(()=>{if(v===f.current||(f.current=v,v!==!1))return;const m=y.current;m&&m.term.write(`\r
4
- \x1B[90m${F("exitBanner",{code:j??""})}\x1B[0m\r
5
- `)},[v,c,j]),n.jsx("div",{ref:T,className:`term-xterm ${u?"":"hidden"}`})}const q={name:"",command:"",cwd:"${pwd}"};function pe({chat:t,send:c,terminal:p}){const a=W(),[x,u]=l.useState(null),[v,j]=l.useState(!1),[h,C]=l.useState(!1),[T,y]=l.useState(null),[o,N]=l.useState(q),[E,F]=l.useState(null),f=l.useRef(null),[m,r]=l.useState(!0),[b,g]=l.useState(null),[_,$]=l.useState("");l.useEffect(()=>{t.terminals.length===0?u(null):t.terminals.some(e=>e.id===x)||u(t.terminals[t.terminals.length-1].id)},[t.terminals,x]),l.useEffect(()=>{t.terminalActiveId&&(u(t.terminalActiveId),j(!1))},[t.terminalActiveId]),l.useEffect(()=>()=>{f.current&&clearTimeout(f.current)},[]);const B=t.terminals.filter(e=>!e.agentBash),R=t.terminals.filter(e=>e.agentBash),k=e=>{if(!t.ready)return;const s=ae(),i=t.activeConversationId||t.state?.conversationId||"";p.create({...e,id:s,conversationId:i,cols:e.cols??80,rows:e.rows??24,running:!0,exitCode:null}),u(s),j(!1)},d=()=>k({title:a("terminalTitle",{n:B.length+1}),cwd:t.state?.cwd??""}),S=e=>{const s=e.name||e.command,i=t.terminals.find(w=>w.title===s);if(i){p.restart(i.id),u(i.id),c({type:"run_command",terminalId:i.id,conversationId:i.conversationId,command:e,cols:80,rows:24});return}k({title:s,cwd:t.state?.cwd??"",command:e})},D=e=>{const s=t.terminals.find(i=>i.id===e);if(s&&c({type:"terminal_kill",terminalId:e,conversationId:s.conversationId}),p.close(e),x===e){const i=t.terminals.filter(w=>w.id!==e);u(i.length>0?i[i.length-1].id:null)}},I=e=>n.jsxs("div",{className:`term-tab ${e.id===x?"active":""}`,children:[n.jsxs("button",{type:"button",className:"term-tab-main",title:`${e.cwd}${e.command?`
6
- > ${e.command.command}`:""}`,onClick:()=>{b||(u(e.id),j(!1))},children:[n.jsx("span",{className:`term-tab-dot ${e.running?"run":"exit"}`}),n.jsxs("span",{className:"term-tab-title",children:[b===e.id?n.jsx("input",{autoFocus:!0,className:"term-tab-rename-input",value:_,placeholder:e.title,onClick:s=>s.stopPropagation(),onChange:s=>$(s.target.value),onKeyDown:s=>{if(s.stopPropagation(),s.key==="Enter"&&!s.nativeEvent.isComposing){const i=_.trim();i&&c({type:"rename_terminal",terminalId:e.id,conversationId:e.conversationId,title:i}),g(null)}else s.key==="Escape"&&g(null)},onBlur:()=>g(null)}):e.title,!e.running&&n.jsx("span",{className:"term-tab-exit",children:a("exited",{code:e.exitCode===null?"":` ${e.exitCode}`})})]})]}),n.jsx("button",{type:"button",className:"term-tab-close term-tab-rename",title:a("renameTerminal"),onClick:s=>{s.stopPropagation(),$(e.title),g(e.id)},children:n.jsx(H,{})}),n.jsx("button",{type:"button",className:"term-tab-close",title:a("closeTerminal"),onClick:()=>D(e.id),children:n.jsx(se,{})})]},e.id),G=()=>{C(!0),y(null),N(q)},L=e=>{const s=t.commands[e];s&&(C(!1),y(e),N({name:s.name,command:s.command,cwd:s.cwd??""}))},K=()=>{C(!1),y(null)},A=()=>{const e=o.name.trim(),s=o.command.trim();if(!e||!s)return;const i=o.cwd.trim(),w={name:e,command:s,cwd:i||void 0},Q=h?[...t.commands,w]:T!==null?t.commands.map((U,V)=>V===T?w:U):t.commands;c({type:"save_commands",commands:Q}),K()},J=e=>{if(E===e){const s=t.commands.filter((i,w)=>w!==e);c({type:"save_commands",commands:s}),F(null),f.current&&clearTimeout(f.current)}else F(e),f.current&&clearTimeout(f.current),f.current=setTimeout(()=>F(null),2500)},X=h||T!==null;return n.jsxs("div",{className:"terminal-view",children:[n.jsxs("aside",{className:`term-side term-commands ${v?"open":""}`,children:[n.jsxs("div",{className:"panel-header",children:[n.jsx("span",{className:"panel-title",children:a("commands")}),n.jsxs("div",{className:"panel-header-actions",children:[n.jsx("button",{type:"button",className:"panel-refresh",title:a("rerun"),onClick:()=>c({type:"list_commands"}),children:n.jsx(Y,{})}),n.jsx("button",{type:"button",className:"panel-new",title:a("newCommand"),onClick:G,children:n.jsx(z,{})})]})]}),n.jsx("div",{className:"panel-body",children:X?n.jsxs("div",{className:"cmd-form",children:[n.jsx("label",{htmlFor:"cmd-name",children:a("name")}),n.jsx("input",{id:"cmd-name",className:"cmd-input",value:o.name,placeholder:a("exampleName"),autoFocus:!0,onChange:e=>N({...o,name:e.target.value})}),n.jsx("label",{htmlFor:"cmd-command",children:a("command")}),n.jsx("input",{id:"cmd-command",className:"cmd-input",value:o.command,placeholder:a("exampleCommand"),onChange:e=>N({...o,command:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&A()}}),n.jsxs("label",{htmlFor:"cmd-cwd",children:[a("directory")," ",n.jsx("span",{className:"cmd-hint",children:a("cwdHint")})]}),n.jsx("input",{id:"cmd-cwd",className:"cmd-input",value:o.cwd,placeholder:"${pwd}",onChange:e=>N({...o,cwd:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&A()}}),n.jsxs("div",{className:"cmd-form-actions",children:[n.jsx("button",{type:"button",className:"btn",onClick:K,children:a("cancel")}),n.jsx("button",{type:"button",className:"btn primary",disabled:!o.name.trim()||!o.command.trim(),onClick:A,children:a("save")})]})]}):n.jsxs(n.Fragment,{children:[t.commands.length===0&&n.jsx("div",{className:"panel-empty",children:a("noCommands")}),t.commands.map((e,s)=>n.jsxs("div",{className:"cmd-item",children:[n.jsx("button",{type:"button",className:"cmd-run",title:a("clickToRun"),onClick:()=>S(e),children:n.jsx(Z,{})}),n.jsxs("button",{type:"button",className:"cmd-main",title:a("clickToRun"),onClick:()=>S(e),children:[n.jsx("span",{className:"cmd-name",children:e.name}),n.jsx("span",{className:"cmd-command",children:e.command}),e.cwd&&n.jsx("span",{className:"cmd-cwd",children:e.cwd})]}),n.jsx("button",{type:"button",className:"cmd-act",title:a("edit"),onClick:()=>L(s),children:n.jsx(H,{})}),n.jsx("button",{type:"button",className:`cmd-act del ${E===s?"confirm":""}`,title:a("delete"),onClick:()=>J(s),children:E===s?a("confirmQ"):n.jsx(ee,{})})]},s))]})}),n.jsxs("div",{className:"term-tabs-block",children:[n.jsxs("div",{className:"panel-header",children:[n.jsx("span",{className:"panel-title",children:a("terminal")}),n.jsx("button",{type:"button",className:"panel-new",title:a("newTerminal"),onClick:d,children:n.jsx(z,{})})]}),n.jsxs("div",{className:"panel-body",children:[t.terminals.length===0&&n.jsx("div",{className:"panel-empty",children:a("noTerminal")}),B.map(I),R.length>0&&n.jsxs("div",{className:"term-folder",children:[n.jsxs("button",{type:"button",className:`term-folder-header ${m?"open":""}`,title:a("aiBashGroup"),onClick:()=>r(e=>!e),children:[n.jsx("span",{className:"term-folder-caret",children:m?"▾":"▸"}),n.jsx("span",{className:"term-folder-title",children:a("aiBashGroup")}),n.jsx("span",{className:"term-folder-count",children:R.length})]}),m&&n.jsx("div",{className:"term-folder-body",children:R.map(I)})]})]})]})]}),n.jsxs("div",{className:"term-main",children:[v&&n.jsx("div",{className:"drawer-backdrop",onClick:()=>j(!1)}),n.jsx("button",{type:"button",className:"term-side-toggle",title:a("commands"),onClick:()=>j(e=>!e),children:n.jsx(ne,{})}),t.terminals.length===0?n.jsxs("div",{className:"term-empty",children:[n.jsx(te,{className:"term-empty-icon"}),n.jsx("div",{className:"term-empty-title",children:a("builtinTerminal")}),n.jsx("div",{className:"term-empty-sub",children:a("termEmptySub")})]}):t.terminals.map(e=>n.jsx(ce,{conversationId:e.conversationId,terminalId:e.id,command:e.command,cwd:e.cwd,title:e.title,active:e.id===x,running:e.running,exitCode:e.exitCode,send:c,register:p.register},`${e.conversationId}:${e.id}`))]})]})}export{pe as TerminalPanel};