pi-web 0.3.0 → 0.3.2

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-web.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import "../server.js";
2
+ import "../build/server/server.js";
@@ -33,7 +33,8 @@ const PORT = parseInt(getArg("port") || process.env.PORT || "8192", 10);
33
33
  const HOST = getArg("host") || process.env.HOST || "127.0.0.1";
34
34
  const PI_CMD = process.env.PI_CMD || "npx -y @mariozechner/pi-coding-agent@latest";
35
35
  const isDev = process.argv.includes("--watch") || process.env.NODE_ENV === "development";
36
- const distDir = join(__dirname, "dist");
36
+ const distDirCandidates = [join(__dirname, "dist"), join(__dirname, "..", "..", "dist")];
37
+ const distDir = distDirCandidates.find((candidate) => existsSync(join(candidate, "index.html"))) ?? distDirCandidates[0];
37
38
  const htmlPath = join(distDir, "index.html");
38
39
  const htmlCache = isDev || !existsSync(htmlPath) ? null : readFileSync(htmlPath, "utf-8");
39
40
  const contentTypes = {
@@ -44,6 +44,6 @@ Error generating stack: `+o.message+`
44
44
  transition-transform duration-200
45
45
  ${I?"translate-x-0":"-translate-x-full"}
46
46
  md:translate-x-0
47
- `,children:[y.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-pi-border-muted",children:[y.jsxs("h1",{className:"text-base font-semibold text-pi-accent",children:["pi-web ",y.jsxs("span",{className:"text-pi-dim font-normal text-xs",children:["v","0.2.0"]})]}),y.jsxs("div",{className:"flex items-center gap-2",children:[y.jsx("button",{onClick:Oc,title:"New session",className:"bg-pi-accent text-white p-1.5 rounded-lg hover:opacity-85 cursor-pointer",children:y.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"8",y1:"3",x2:"8",y2:"13"}),y.jsx("line",{x1:"3",y1:"8",x2:"13",y2:"8"})]})}),y.jsx("button",{onClick:()=>ue(!1),className:"md:hidden text-pi-muted p-1.5 cursor-pointer",children:y.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"3",y1:"3",x2:"13",y2:"13"}),y.jsx("line",{x1:"13",y1:"3",x2:"3",y2:"13"})]})})]})]}),y.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:Wc.map(m=>y.jsx(Ep,{folder:m,expanded:k.has(m.cwd),activeSessionFile:n,onToggle:()=>Dc(m.cwd),onNewSession:()=>{S(T=>new Set([...T,m.cwd])),lu(m.cwd),ue(!1)},onSelectSession:T=>{Mc(T),ue(!1)},onDeleteSession:Ac},m.cwd))})]}),y.jsxs("main",{className:"flex-1 flex flex-col min-h-0",children:[y.jsxs("div",{className:"md:hidden flex items-center gap-2 px-3 py-2 border-b border-pi-border-muted bg-pi-card-bg",children:[y.jsx("button",{onClick:()=>ue(!0),className:"text-pi-muted p-1 cursor-pointer",children:y.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"2",y1:"4",x2:"16",y2:"4"}),y.jsx("line",{x1:"2",y1:"9",x2:"16",y2:"9"}),y.jsx("line",{x1:"2",y1:"14",x2:"16",y2:"14"})]})}),y.jsx("span",{className:"text-pi-muted truncate",children:n?n.split("/").pop():"No session selected"})]}),y.jsx("div",{ref:Be,className:"flex-1 overflow-y-auto px-4 py-4 md:px-6",children:l.length===0?y.jsx("div",{className:"flex items-center justify-center h-full text-pi-muted text-base",children:"Start a new session or select one from the list."}):l.filter(m=>m.role==="user"||m.parts.some(T=>(T.content??"").trim()||T.type==="toolCall")).map(m=>y.jsx(Sp,{msg:m},m.id))}),y.jsxs("div",{className:"flex items-center gap-3 px-4 py-1.5 border-t border-pi-border-muted bg-pi-card-bg text-xs text-pi-muted flex-wrap",children:[y.jsxs("span",{className:"flex items-center gap-1.5",children:[y.jsx("span",{className:`inline-block w-2 h-2 rounded-full ${Bc}`}),s?"Streaming":i?"Connected":"Disconnected"]}),$.length>0&&y.jsxs("span",{className:"flex items-center gap-1.5",children:[y.jsx("select",{value:g,onChange:m=>$c(m.target.value),disabled:s,className:"text-xs font-mono text-gray-700 bg-white border border-pi-border-muted rounded px-1 py-0.5 cursor-pointer disabled:opacity-50 max-w-[120px]",children:it.map(m=>y.jsx("option",{value:m,children:m},m))}),y.jsx("select",{value:(a==null?void 0:a.provider)===g?a.id:"",onChange:m=>Uc(m.target.value),disabled:s,className:"text-xs font-mono text-gray-700 bg-white border border-pi-border-muted rounded px-1 py-0.5 cursor-pointer disabled:opacity-50 max-w-[160px]",children:Tn.map(m=>y.jsx("option",{value:m.id,children:m.name},m.id))})]}),$.length===0&&a&&y.jsx("span",{children:a.name}),C&&y.jsxs("span",{className:"flex items-center gap-2 text-pi-dim ml-auto flex-wrap",children:[C.tokens.input>0&&y.jsxs("span",{children:["↑",An(C.tokens.input)]}),C.tokens.output>0&&y.jsxs("span",{children:["↓",An(C.tokens.output)]}),C.tokens.cacheRead>0&&y.jsxs("span",{children:["R",An(C.tokens.cacheRead)]}),C.tokens.cacheWrite>0&&y.jsxs("span",{children:["W",An(C.tokens.cacheWrite)]}),C.cost>0&&y.jsxs("span",{children:["$",C.cost.toFixed(3)]}),(a==null?void 0:a.contextWindow)&&C.tokens.input>0&&(()=>{const m=C.tokens.input/a.contextWindow*100,T=m>90?"text-pi-error":m>70?"text-pi-warning":"";return y.jsxs("span",{className:T,children:[m.toFixed(1),"%/",An(a.contextWindow)]})})()]}),s&&y.jsxs("span",{children:["responding",j.length>0?` · ${j.length} queued`:""]})]}),y.jsx("div",{className:"px-4 pb-4 pt-3 md:px-6 border-t border-pi-border-muted bg-pi-card-bg",children:y.jsxs("div",{className:"flex gap-2 items-center",children:[y.jsx("textarea",{ref:qe,rows:1,placeholder:p?"Send a message...":"Select a session to start",disabled:!p,value:v,onChange:m=>h(m.target.value),onKeyDown:m=>{m.key==="Enter"&&!m.shiftKey&&(m.preventDefault(),ou())},className:"flex-1 bg-white border border-pi-border-muted rounded-lg px-3 py-2.5 text-base md:text-sm font-mono resize-none min-h-[42px] max-h-[200px] outline-none focus:border-pi-accent disabled:opacity-50 disabled:cursor-default"}),y.jsxs("div",{className:"flex flex-row gap-1 flex-shrink-0",children:[y.jsxs("button",{onClick:ou,disabled:!i||!p,title:s?"Queue message":"Send",className:"relative bg-pi-accent text-white p-2 rounded-lg cursor-pointer disabled:opacity-40 disabled:cursor-default hover:opacity-85",children:[y.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"2",y1:"9",x2:"16",y2:"9"}),y.jsx("polyline",{points:"10,3 16,9 10,15"})]}),j.length>0&&y.jsx("span",{className:"absolute -top-1.5 -right-1.5 bg-pi-warning text-white text-[10px] w-4 h-4 rounded-full flex items-center justify-center leading-none",children:j.length})]}),y.jsx("button",{onClick:Fc,disabled:!s||!p,title:"Stop",className:"bg-pi-error text-white p-2 rounded-lg cursor-pointer disabled:opacity-40 disabled:cursor-default hover:opacity-85",children:y.jsx("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"currentColor",children:y.jsx("rect",{x:"4",y:"4",width:"10",height:"10",rx:"1.5"})})})]})]})})]})]})}function Sp({msg:e}){const t=e.role==="user";return y.jsxs("div",{className:"mb-4 min-w-0",children:[y.jsxs("div",{className:"flex items-center gap-2 mb-1 min-w-0",children:[y.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-wide text-pi-muted shrink-0",children:t?"You":"Assistant"}),!t&&(e.model||e.provider)&&y.jsx("span",{className:"text-[10px] text-pi-dim truncate",children:[e.provider,e.model].filter(Boolean).join(" / ")}),e.timestamp!=null&&y.jsx("span",{className:"text-[10px] text-pi-dim ml-auto shrink-0",children:jp(e.timestamp)})]}),y.jsx("div",{className:`rounded-lg px-4 py-3 min-w-0 overflow-hidden ${t?"bg-pi-user-bg":"bg-pi-card-bg border border-pi-border-muted"}`,children:y.jsx("div",{className:"text-xs md:text-sm leading-relaxed break-words min-w-0",children:e.parts.map((n,r)=>y.jsx(_p,{part:n},`${e.id}-${r}`))})})]})}function Ep({folder:e,expanded:t,activeSessionFile:n,onToggle:r,onNewSession:l,onSelectSession:o,onDeleteSession:i}){const u=e.sessions.some(s=>s.file===n);return y.jsxs("div",{className:"mb-1",children:[y.jsxs("div",{className:"flex items-center gap-1 rounded-lg",children:[y.jsxs("button",{onClick:r,className:`flex-1 flex items-center gap-1.5 text-left px-2 py-1.5 rounded-lg text-xs font-semibold hover:bg-pi-user-bg cursor-pointer min-w-0 ${u?"text-pi-accent":"text-gray-700"}`,children:[y.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",className:`text-pi-muted transition-transform duration-150 flex-shrink-0 ${t?"rotate-90":""}`,children:y.jsx("polyline",{points:"3,2 9,6 3,10"})}),y.jsx("span",{className:"flex-1 truncate min-w-0",children:e.label}),y.jsx("span",{className:"text-[11px] text-pi-dim font-normal flex-shrink-0",children:e.sessions.length})]}),y.jsx("button",{onClick:l,title:"New session here",className:"text-pi-muted hover:text-pi-accent hover:bg-pi-user-bg p-1.5 rounded-lg cursor-pointer flex-shrink-0",children:y.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 13 13",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"6.5",y1:"1.5",x2:"6.5",y2:"11.5"}),y.jsx("line",{x1:"1.5",y1:"6.5",x2:"11.5",y2:"6.5"})]})})]}),t&&y.jsx("div",{className:"pl-3 mt-0.5",children:e.sessions.map(s=>{const c=s.file===n,v=s.firstPrompt||s.id.slice(0,8),h=s.timestamp?new Date(s.timestamp).toLocaleString():"";return y.jsxs("div",{onClick:()=>o(s.file),className:`group relative px-2.5 py-2 rounded-lg cursor-pointer mb-0.5 border ${c?"border-pi-accent bg-pi-user-bg":"border-transparent hover:bg-pi-user-bg"}`,children:[y.jsx("div",{className:"text-xs truncate pr-5",children:v}),y.jsxs("div",{className:"text-[11px] text-pi-dim mt-0.5",children:[s.messageCount," msgs · ",h]}),y.jsx("button",{onClick:p=>{p.stopPropagation(),i(s.file)},title:"Delete session",className:"absolute top-1/2 right-1.5 -translate-y-1/2 hidden group-hover:flex active:flex items-center justify-center w-5 h-5 rounded text-pi-muted bg-pi-user-bg hover:text-pi-error hover:bg-pi-tool-error cursor-pointer",children:y.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"1.5",y1:"1.5",x2:"8.5",y2:"8.5"}),y.jsx("line",{x1:"8.5",y1:"1.5",x2:"1.5",y2:"8.5"})]})})]},s.file)})})]})}function _p({part:e}){return e.type==="text"?y.jsx("div",{dangerouslySetInnerHTML:{__html:Np(e.content||"")}}):e.type==="thinking"?y.jsx("div",{className:"text-pi-muted italic border-l-2 border-pi-border-muted pl-3 my-1.5 text-xs",children:e.content}):e.type==="tool"?y.jsx(Cp,{part:e}):null}function Cp({part:e}){const[t,n]=O.useState(!1),r=e.args?typeof e.args=="string"?e.args:JSON.stringify(e.args,null,2):"",l=e.content||"",o=r||l;return y.jsxs("div",{className:"bg-pi-tool-success border border-pi-border-muted rounded-lg my-1.5 text-xs overflow-hidden",children:[y.jsxs("button",{onClick:()=>o&&n(i=>!i),className:`w-full flex items-center gap-2 px-3 py-2 text-left ${o?"cursor-pointer hover:brightness-95":"cursor-default"}`,children:[y.jsx("span",{className:"text-pi-success font-semibold",children:e.name}),!t&&r&&y.jsxs("span",{className:"text-pi-muted truncate flex-1",children:[r.slice(0,80),r.length>80?"…":""]}),o&&y.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",className:`ml-auto text-pi-dim flex-shrink-0 transition-transform duration-150 ${t?"rotate-180":""}`,children:y.jsx("polyline",{points:"1,3 5,7 9,3"})})]}),t&&y.jsxs("div",{className:"border-t border-pi-border-muted",children:[r&&y.jsxs("div",{className:"px-3 py-2 border-b border-pi-border-muted/40",children:[y.jsx("div",{className:"text-[10px] font-semibold text-pi-muted uppercase mb-1",children:"Input"}),y.jsx("pre",{className:"whitespace-pre-wrap break-all text-pi-muted font-mono",children:r})]}),l&&y.jsxs("div",{className:"px-3 py-2",children:[y.jsx("div",{className:"text-[10px] font-semibold text-pi-muted uppercase mb-1",children:"Output"}),y.jsx("pre",{className:"whitespace-pre-wrap break-all text-pi-tool-output max-h-48 overflow-y-auto font-mono",children:l})]})]})]})}function Np(e){const t=e.split(`
47
+ `,children:[y.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-pi-border-muted",children:[y.jsxs("h1",{className:"text-base font-semibold text-pi-accent",children:["pi-web ",y.jsxs("span",{className:"text-pi-dim font-normal text-xs",children:["v","0.3.1"]})]}),y.jsxs("div",{className:"flex items-center gap-2",children:[y.jsx("button",{onClick:Oc,title:"New session",className:"bg-pi-accent text-white p-1.5 rounded-lg hover:opacity-85 cursor-pointer",children:y.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"8",y1:"3",x2:"8",y2:"13"}),y.jsx("line",{x1:"3",y1:"8",x2:"13",y2:"8"})]})}),y.jsx("button",{onClick:()=>ue(!1),className:"md:hidden text-pi-muted p-1.5 cursor-pointer",children:y.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"3",y1:"3",x2:"13",y2:"13"}),y.jsx("line",{x1:"13",y1:"3",x2:"3",y2:"13"})]})})]})]}),y.jsx("div",{className:"flex-1 overflow-y-auto p-2",children:Wc.map(m=>y.jsx(Ep,{folder:m,expanded:k.has(m.cwd),activeSessionFile:n,onToggle:()=>Dc(m.cwd),onNewSession:()=>{S(T=>new Set([...T,m.cwd])),lu(m.cwd),ue(!1)},onSelectSession:T=>{Mc(T),ue(!1)},onDeleteSession:Ac},m.cwd))})]}),y.jsxs("main",{className:"flex-1 flex flex-col min-h-0",children:[y.jsxs("div",{className:"md:hidden flex items-center gap-2 px-3 py-2 border-b border-pi-border-muted bg-pi-card-bg",children:[y.jsx("button",{onClick:()=>ue(!0),className:"text-pi-muted p-1 cursor-pointer",children:y.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"2",y1:"4",x2:"16",y2:"4"}),y.jsx("line",{x1:"2",y1:"9",x2:"16",y2:"9"}),y.jsx("line",{x1:"2",y1:"14",x2:"16",y2:"14"})]})}),y.jsx("span",{className:"text-pi-muted truncate",children:n?n.split("/").pop():"No session selected"})]}),y.jsx("div",{ref:Be,className:"flex-1 overflow-y-auto px-4 py-4 md:px-6",children:l.length===0?y.jsx("div",{className:"flex items-center justify-center h-full text-pi-muted text-base",children:"Start a new session or select one from the list."}):l.filter(m=>m.role==="user"||m.parts.some(T=>(T.content??"").trim()||T.type==="toolCall")).map(m=>y.jsx(Sp,{msg:m},m.id))}),y.jsxs("div",{className:"flex items-center gap-3 px-4 py-1.5 border-t border-pi-border-muted bg-pi-card-bg text-xs text-pi-muted flex-wrap",children:[y.jsxs("span",{className:"flex items-center gap-1.5",children:[y.jsx("span",{className:`inline-block w-2 h-2 rounded-full ${Bc}`}),s?"Streaming":i?"Connected":"Disconnected"]}),$.length>0&&y.jsxs("span",{className:"flex items-center gap-1.5",children:[y.jsx("select",{value:g,onChange:m=>$c(m.target.value),disabled:s,className:"text-xs font-mono text-gray-700 bg-white border border-pi-border-muted rounded px-1 py-0.5 cursor-pointer disabled:opacity-50 max-w-[120px]",children:it.map(m=>y.jsx("option",{value:m,children:m},m))}),y.jsx("select",{value:(a==null?void 0:a.provider)===g?a.id:"",onChange:m=>Uc(m.target.value),disabled:s,className:"text-xs font-mono text-gray-700 bg-white border border-pi-border-muted rounded px-1 py-0.5 cursor-pointer disabled:opacity-50 max-w-[160px]",children:Tn.map(m=>y.jsx("option",{value:m.id,children:m.name},m.id))})]}),$.length===0&&a&&y.jsx("span",{children:a.name}),C&&y.jsxs("span",{className:"flex items-center gap-2 text-pi-dim ml-auto flex-wrap",children:[C.tokens.input>0&&y.jsxs("span",{children:["↑",An(C.tokens.input)]}),C.tokens.output>0&&y.jsxs("span",{children:["↓",An(C.tokens.output)]}),C.tokens.cacheRead>0&&y.jsxs("span",{children:["R",An(C.tokens.cacheRead)]}),C.tokens.cacheWrite>0&&y.jsxs("span",{children:["W",An(C.tokens.cacheWrite)]}),C.cost>0&&y.jsxs("span",{children:["$",C.cost.toFixed(3)]}),(a==null?void 0:a.contextWindow)&&C.tokens.input>0&&(()=>{const m=C.tokens.input/a.contextWindow*100,T=m>90?"text-pi-error":m>70?"text-pi-warning":"";return y.jsxs("span",{className:T,children:[m.toFixed(1),"%/",An(a.contextWindow)]})})()]}),s&&y.jsxs("span",{children:["responding",j.length>0?` · ${j.length} queued`:""]})]}),y.jsx("div",{className:"px-4 pb-4 pt-3 md:px-6 border-t border-pi-border-muted bg-pi-card-bg",children:y.jsxs("div",{className:"flex gap-2 items-center",children:[y.jsx("textarea",{ref:qe,rows:1,placeholder:p?"Send a message...":"Select a session to start",disabled:!p,value:v,onChange:m=>h(m.target.value),onKeyDown:m=>{m.key==="Enter"&&!m.shiftKey&&(m.preventDefault(),ou())},className:"flex-1 bg-white border border-pi-border-muted rounded-lg px-3 py-2.5 text-base md:text-sm font-mono resize-none min-h-[42px] max-h-[200px] outline-none focus:border-pi-accent disabled:opacity-50 disabled:cursor-default"}),y.jsxs("div",{className:"flex flex-row gap-1 flex-shrink-0",children:[y.jsxs("button",{onClick:ou,disabled:!i||!p,title:s?"Queue message":"Send",className:"relative bg-pi-accent text-white p-2 rounded-lg cursor-pointer disabled:opacity-40 disabled:cursor-default hover:opacity-85",children:[y.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[y.jsx("line",{x1:"2",y1:"9",x2:"16",y2:"9"}),y.jsx("polyline",{points:"10,3 16,9 10,15"})]}),j.length>0&&y.jsx("span",{className:"absolute -top-1.5 -right-1.5 bg-pi-warning text-white text-[10px] w-4 h-4 rounded-full flex items-center justify-center leading-none",children:j.length})]}),y.jsx("button",{onClick:Fc,disabled:!s||!p,title:"Stop",className:"bg-pi-error text-white p-2 rounded-lg cursor-pointer disabled:opacity-40 disabled:cursor-default hover:opacity-85",children:y.jsx("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"currentColor",children:y.jsx("rect",{x:"4",y:"4",width:"10",height:"10",rx:"1.5"})})})]})]})})]})]})}function Sp({msg:e}){const t=e.role==="user";return y.jsxs("div",{className:"mb-4 min-w-0",children:[y.jsxs("div",{className:"flex items-center gap-2 mb-1 min-w-0",children:[y.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-wide text-pi-muted shrink-0",children:t?"You":"Assistant"}),!t&&(e.model||e.provider)&&y.jsx("span",{className:"text-[10px] text-pi-dim truncate",children:[e.provider,e.model].filter(Boolean).join(" / ")}),e.timestamp!=null&&y.jsx("span",{className:"text-[10px] text-pi-dim ml-auto shrink-0",children:jp(e.timestamp)})]}),y.jsx("div",{className:`rounded-lg px-4 py-3 min-w-0 overflow-hidden ${t?"bg-pi-user-bg":"bg-pi-card-bg border border-pi-border-muted"}`,children:y.jsx("div",{className:"text-xs md:text-sm leading-relaxed break-words min-w-0",children:e.parts.map((n,r)=>y.jsx(_p,{part:n},`${e.id}-${r}`))})})]})}function Ep({folder:e,expanded:t,activeSessionFile:n,onToggle:r,onNewSession:l,onSelectSession:o,onDeleteSession:i}){const u=e.sessions.some(s=>s.file===n);return y.jsxs("div",{className:"mb-1",children:[y.jsxs("div",{className:"flex items-center gap-1 rounded-lg",children:[y.jsxs("button",{onClick:r,className:`flex-1 flex items-center gap-1.5 text-left px-2 py-1.5 rounded-lg text-xs font-semibold hover:bg-pi-user-bg cursor-pointer min-w-0 ${u?"text-pi-accent":"text-gray-700"}`,children:[y.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",className:`text-pi-muted transition-transform duration-150 flex-shrink-0 ${t?"rotate-90":""}`,children:y.jsx("polyline",{points:"3,2 9,6 3,10"})}),y.jsx("span",{className:"flex-1 truncate min-w-0",children:e.label}),y.jsx("span",{className:"text-[11px] text-pi-dim font-normal flex-shrink-0",children:e.sessions.length})]}),y.jsx("button",{onClick:l,title:"New session here",className:"text-pi-muted hover:text-pi-accent hover:bg-pi-user-bg p-1.5 rounded-lg cursor-pointer flex-shrink-0",children:y.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 13 13",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"6.5",y1:"1.5",x2:"6.5",y2:"11.5"}),y.jsx("line",{x1:"1.5",y1:"6.5",x2:"11.5",y2:"6.5"})]})})]}),t&&y.jsx("div",{className:"pl-3 mt-0.5",children:e.sessions.map(s=>{const c=s.file===n,v=s.firstPrompt||s.id.slice(0,8),h=s.timestamp?new Date(s.timestamp).toLocaleString():"";return y.jsxs("div",{onClick:()=>o(s.file),className:`group relative px-2.5 py-2 rounded-lg cursor-pointer mb-0.5 border ${c?"border-pi-accent bg-pi-user-bg":"border-transparent hover:bg-pi-user-bg"}`,children:[y.jsx("div",{className:"text-xs truncate pr-5",children:v}),y.jsxs("div",{className:"text-[11px] text-pi-dim mt-0.5",children:[s.messageCount," msgs · ",h]}),y.jsx("button",{onClick:p=>{p.stopPropagation(),i(s.file)},title:"Delete session",className:"absolute top-1/2 right-1.5 -translate-y-1/2 hidden group-hover:flex active:flex items-center justify-center w-5 h-5 rounded text-pi-muted bg-pi-user-bg hover:text-pi-error hover:bg-pi-tool-error cursor-pointer",children:y.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:[y.jsx("line",{x1:"1.5",y1:"1.5",x2:"8.5",y2:"8.5"}),y.jsx("line",{x1:"8.5",y1:"1.5",x2:"1.5",y2:"8.5"})]})})]},s.file)})})]})}function _p({part:e}){return e.type==="text"?y.jsx("div",{dangerouslySetInnerHTML:{__html:Np(e.content||"")}}):e.type==="thinking"?y.jsx("div",{className:"text-pi-muted italic border-l-2 border-pi-border-muted pl-3 my-1.5 text-xs",children:e.content}):e.type==="tool"?y.jsx(Cp,{part:e}):null}function Cp({part:e}){const[t,n]=O.useState(!1),r=e.args?typeof e.args=="string"?e.args:JSON.stringify(e.args,null,2):"",l=e.content||"",o=r||l;return y.jsxs("div",{className:"bg-pi-tool-success border border-pi-border-muted rounded-lg my-1.5 text-xs overflow-hidden",children:[y.jsxs("button",{onClick:()=>o&&n(i=>!i),className:`w-full flex items-center gap-2 px-3 py-2 text-left ${o?"cursor-pointer hover:brightness-95":"cursor-default"}`,children:[y.jsx("span",{className:"text-pi-success font-semibold",children:e.name}),!t&&r&&y.jsxs("span",{className:"text-pi-muted truncate flex-1",children:[r.slice(0,80),r.length>80?"…":""]}),o&&y.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",className:`ml-auto text-pi-dim flex-shrink-0 transition-transform duration-150 ${t?"rotate-180":""}`,children:y.jsx("polyline",{points:"1,3 5,7 9,3"})})]}),t&&y.jsxs("div",{className:"border-t border-pi-border-muted",children:[r&&y.jsxs("div",{className:"px-3 py-2 border-b border-pi-border-muted/40",children:[y.jsx("div",{className:"text-[10px] font-semibold text-pi-muted uppercase mb-1",children:"Input"}),y.jsx("pre",{className:"whitespace-pre-wrap break-all text-pi-muted font-mono",children:r})]}),l&&y.jsxs("div",{className:"px-3 py-2",children:[y.jsx("div",{className:"text-[10px] font-semibold text-pi-muted uppercase mb-1",children:"Output"}),y.jsx("pre",{className:"whitespace-pre-wrap break-all text-pi-tool-output max-h-48 overflow-y-auto font-mono",children:l})]})]})]})}function Np(e){const t=e.split(`
48
48
  `),n=[];let r=0;for(;r<t.length;){const l=t[r];if(/^```/.test(l)){const i=l.slice(3).trim(),u=[];for(r++;r<t.length&&!/^```/.test(t[r]);)u.push(ui(t[r])),r++;n.push(`<pre class="bg-pi-page-bg border border-pi-border-muted rounded-lg p-3 overflow-x-auto my-2 text-xs font-mono text-pi-md-code-block"><code${i?` class="language-${ui(i)}"`:""}>${u.join(`
49
49
  `)}</code></pre>`),r++;continue}if(/^\|/.test(l)&&r+1<t.length&&/^\|[\s\-:|]+\|/.test(t[r+1])){const i=ys(t[r]),u=Pp(t[r+1]);r+=2;const s=[];for(;r<t.length&&/^\|/.test(t[r]);)s.push(ys(t[r])),r++;const c=i.map((h,p)=>`<th class="border border-pi-border-muted px-3 py-1.5 bg-pi-page-bg font-semibold text-left" style="${gs(u[p])}">${Ar(h)}</th>`).join(""),v=s.map(h=>`<tr>${h.map((p,x)=>`<td class="border border-pi-border-muted px-3 py-1.5" style="${gs(u[x])}">${Ar(p)}</td>`).join("")}</tr>`).join("");n.push(`<div class="overflow-x-auto my-2"><table class="border-collapse text-xs w-full"><thead><tr>${c}</tr></thead><tbody>${v}</tbody></table></div>`);continue}const o=l.match(/^(#{1,6})\s+(.*)/);if(o){const i=o[1].length,u=["text-lg","text-base","text-sm","text-sm","text-xs","text-xs"];n.push(`<h${i} class="font-semibold ${u[i-1]} mt-3 mb-1 text-pi-md-heading">${Ar(o[2])}</h${i}>`),r++;continue}if(/^(-{3,}|\*{3,}|_{3,})$/.test(l.trim())){n.push('<hr class="border-t border-pi-border-muted my-3">'),r++;continue}if(l.trim()===""){n.push("<br>"),r++;continue}n.push(`<span>${Ar(l)}</span><br>`),r++}return n.join("")}function ys(e){return e.replace(/^\||\|$/g,"").split("|").map(t=>t.trim())}function Pp(e){return e.replace(/^\||\|$/g,"").split("|").map(t=>(t=t.trim(),t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"))}function gs(e){return`text-align:${e}`}function Ar(e){let t=ui(e);return t=t.replace(/`([^`]+)`/g,'<code class="bg-pi-page-bg text-pi-md-code px-1 py-0.5 rounded text-xs font-mono">$1</code>'),t=t.replace(/\*\*\*([^*]+)\*\*\*/g,"<strong><em>$1</em></strong>"),t=t.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),t=t.replace(/\*([^*\n]+)\*/g,"<em>$1</em>"),t=t.replace(/~~([^~]+)~~/g,"<del class='opacity-60'>$1</del>"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener" class="text-pi-md-link underline">$1</a>'),t}function ui(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function jp(e){return new Date(e).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}function An(e){return e<1e3?String(e):e<1e4?`${(e/1e3).toFixed(1)}k`:e<1e6?`${Math.round(e/1e3)}k`:e<1e7?`${(e/1e6).toFixed(1)}M`:`${Math.round(e/1e6)}M`}mo.createRoot(document.getElementById("root")).render(y.jsx(of.StrictMode,{children:y.jsx(kp,{})}));
package/dist/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>pi-web</title>
7
- <script type="module" crossorigin src="/assets/index-BTCqWdZs.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-Ucv3Z3Cr.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-DCUMk7mY.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-web",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "description": "Web UI for the pi coding agent",
6
6
  "repository": {
@@ -13,32 +13,30 @@
13
13
  "files": [
14
14
  "bin",
15
15
  "dist",
16
- "server.js",
17
- "rpc.js",
18
- "sessions.js",
16
+ "build/server",
19
17
  "README.md"
20
18
  ],
21
19
  "scripts": {
22
20
  "dev": "concurrently \"vite\" \"node --watch --experimental-strip-types server.ts\"",
23
21
  "build": "vite build && tsc -p tsconfig.server.json",
24
22
  "preview": "vite preview",
25
- "start": "node server.js",
23
+ "start": "node build/server/server.js",
26
24
  "prepublishOnly": "npm run build"
27
25
  },
28
26
  "dependencies": {
29
- "@tailwindcss/vite": "^4.2.1",
30
- "react": "^18.3.1",
31
- "react-dom": "^18.3.1",
32
- "tailwindcss": "^4.2.1",
33
27
  "ws": "^8.18.0"
34
28
  },
35
29
  "devDependencies": {
30
+ "@tailwindcss/vite": "^4.2.1",
36
31
  "@types/node": "^22.0.0",
37
32
  "@types/react": "^18.3.3",
38
33
  "@types/react-dom": "^18.3.0",
39
34
  "@types/ws": "^8.5.14",
40
35
  "@vitejs/plugin-react": "^4.3.1",
41
36
  "concurrently": "^8.2.2",
37
+ "react": "^18.3.1",
38
+ "react-dom": "^18.3.1",
39
+ "tailwindcss": "^4.2.1",
42
40
  "typescript": "^5.6.3",
43
41
  "vite": "^5.4.8"
44
42
  }
File without changes
File without changes