@timqi/pier 0.0.20 → 0.0.21

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.
Files changed (56) hide show
  1. package/dist/config-sync-fetch.js +66 -79
  2. package/dist/web/public/assets/{activity-DYo7QS7k.js → activity-Cw0LRVNI.js} +1 -1
  3. package/dist/web/public/assets/activity-Cw0LRVNI.js.br +0 -0
  4. package/dist/web/public/assets/activity-Cw0LRVNI.js.gz +0 -0
  5. package/dist/web/public/assets/{boards-CwohTbtv.js → boards-DMVbV84c.js} +1 -1
  6. package/dist/web/public/assets/boards-DMVbV84c.js.br +0 -0
  7. package/dist/web/public/assets/boards-DMVbV84c.js.gz +0 -0
  8. package/dist/web/public/assets/{code-p-Tq1bMK.js → code-C86xKk2k.js} +1 -1
  9. package/dist/web/public/assets/{explorer-50no_DrD.js → explorer-DTvsy5Rs.js} +1 -1
  10. package/dist/web/public/assets/explorer-DTvsy5Rs.js.br +0 -0
  11. package/dist/web/public/assets/explorer-DTvsy5Rs.js.gz +0 -0
  12. package/dist/web/public/assets/{ghostty-web-Bvhh3ZFk.js → ghostty-web-CvSZragH.js} +1 -1
  13. package/dist/web/public/assets/ghostty-web-CvSZragH.js.br +0 -0
  14. package/dist/web/public/assets/ghostty-web-CvSZragH.js.gz +0 -0
  15. package/dist/web/public/assets/{index-WrsNstrb.js → index-DHxoYoeq.js} +2 -2
  16. package/dist/web/public/assets/index-DHxoYoeq.js.br +0 -0
  17. package/dist/web/public/assets/index-DHxoYoeq.js.gz +0 -0
  18. package/dist/web/public/assets/{runs-BAXZF-6r.js → runs-jY40JBP-.js} +1 -1
  19. package/dist/web/public/assets/runs-jY40JBP-.js.br +0 -0
  20. package/dist/web/public/assets/runs-jY40JBP-.js.gz +0 -0
  21. package/dist/web/public/assets/{settings-BmNXgRne.js → settings-Dux7PIKF.js} +1 -1
  22. package/dist/web/public/assets/settings-Dux7PIKF.js.br +0 -0
  23. package/dist/web/public/assets/settings-Dux7PIKF.js.gz +0 -0
  24. package/dist/web/public/assets/{task-runs-CpgHxFLf.js → task-runs-DKvtBVxS.js} +1 -1
  25. package/dist/web/public/assets/task-runs-DKvtBVxS.js.br +0 -0
  26. package/dist/web/public/assets/task-runs-DKvtBVxS.js.gz +0 -0
  27. package/dist/web/public/assets/{tasks-DybtogPF.js → tasks-CqfrOVIt.js} +1 -1
  28. package/dist/web/public/assets/tasks-CqfrOVIt.js.br +0 -0
  29. package/dist/web/public/assets/tasks-CqfrOVIt.js.gz +0 -0
  30. package/dist/web/public/assets/{terminal-m2_WYu5W.js → terminal-DL_0yEy7.js} +2 -2
  31. package/dist/web/public/assets/terminal-DL_0yEy7.js.br +0 -0
  32. package/dist/web/public/assets/terminal-DL_0yEy7.js.gz +0 -0
  33. package/dist/web/public/index.html +1 -1
  34. package/dist/web/public/index.html.br +0 -0
  35. package/dist/web/public/index.html.gz +0 -0
  36. package/package.json +1 -1
  37. package/dist/web/public/assets/activity-DYo7QS7k.js.br +0 -0
  38. package/dist/web/public/assets/activity-DYo7QS7k.js.gz +0 -0
  39. package/dist/web/public/assets/boards-CwohTbtv.js.br +0 -0
  40. package/dist/web/public/assets/boards-CwohTbtv.js.gz +0 -0
  41. package/dist/web/public/assets/explorer-50no_DrD.js.br +0 -0
  42. package/dist/web/public/assets/explorer-50no_DrD.js.gz +0 -0
  43. package/dist/web/public/assets/ghostty-web-Bvhh3ZFk.js.br +0 -0
  44. package/dist/web/public/assets/ghostty-web-Bvhh3ZFk.js.gz +0 -0
  45. package/dist/web/public/assets/index-WrsNstrb.js.br +0 -0
  46. package/dist/web/public/assets/index-WrsNstrb.js.gz +0 -0
  47. package/dist/web/public/assets/runs-BAXZF-6r.js.br +0 -0
  48. package/dist/web/public/assets/runs-BAXZF-6r.js.gz +0 -0
  49. package/dist/web/public/assets/settings-BmNXgRne.js.br +0 -0
  50. package/dist/web/public/assets/settings-BmNXgRne.js.gz +0 -0
  51. package/dist/web/public/assets/task-runs-CpgHxFLf.js.br +0 -0
  52. package/dist/web/public/assets/task-runs-CpgHxFLf.js.gz +0 -0
  53. package/dist/web/public/assets/tasks-DybtogPF.js.br +0 -0
  54. package/dist/web/public/assets/tasks-DybtogPF.js.gz +0 -0
  55. package/dist/web/public/assets/terminal-m2_WYu5W.js.br +0 -0
  56. package/dist/web/public/assets/terminal-m2_WYu5W.js.gz +0 -0
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tasks-DybtogPF.js","assets/task-runs-CpgHxFLf.js","assets/runs-BAXZF-6r.js","assets/explorer-50no_DrD.js","assets/code-p-Tq1bMK.js","assets/settings-BmNXgRne.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tasks-CqfrOVIt.js","assets/task-runs-DKvtBVxS.js","assets/runs-jY40JBP-.js","assets/explorer-DTvsy5Rs.js","assets/code-C86xKk2k.js","assets/settings-Dux7PIKF.js"])))=>i.map(i=>d[i]);
2
2
  (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=/[\u201c\u201d"\u2018\u2019'()\uff08\uff09\u300c\u300d\u300e\u300f\u3010\u3011\u300a\u300b\u3008\u3009[\]]/;function t(t){let n=[],r=e=>`\uE010${n.push(e)-1}\uE011`,i=t.replace(/```[\s\S]*?```/g,e=>r(e)).replace(/`[^`\n]+`/g,e=>r(e));return i=i.replace(/\*\*(\S|\S[\s\S]*?\S)\*\*/g,(t,n)=>{let r=``,i=``,a=n;for(;a.length>1&&e.test(a[0]);)r+=a[0],a=a.slice(1);for(;a.length>1&&e.test(a.at(-1));)i=a.at(-1)+i,a=a.slice(0,-1);return r||i?`${r}**${a}**${i}`:t}),i.replace(/\uE010(\d+)\uE011/g,(e,t)=>n[Number(t)]??``)}var n=e=>!e.text.trim()&&e.suggestions.length===0,r=e=>e===`xhigh`?`Extra high`:e[0].toUpperCase()+e.slice(1),i=e=>{if(e<1e3)return String(e);let t=e/1e3;return t>=9.95?`${Math.round(t)}K`:`${t.toFixed(1)}K`},a=/(?:^|\n)[ \t]*-{3,}[ \t]*\r?\n((?:[ \t]*\[[^\]\r\n]+\][ \t]*(?:[||][ \t]*)?)+)\s*$/,o=/\[([^\]\r\n]+)\]/g,s=5,c=/<silent>([\s\S]*?)<\/silent>/gi;function l(e){let t=[...e.matchAll(c)].map(e=>(e[1]??``).trim()).filter(Boolean);return t.length?t.join(` · `):void 0}function u(e,n){let r=t(e.replace(c,``).trim()),i=l(e),u=a.exec(r);if(!u?.[1])return{text:r,suggestions:[],meta:n,silence:i};let d=[...u[1].matchAll(o)].map(e=>(e[1]??``).trim()).filter(Boolean).slice(0,s);return d.length?{text:r.slice(0,u.index).trimEnd(),suggestions:d,meta:n,silence:i}:{text:r,suggestions:[],meta:n,silence:i}}var d=e=>t(e.replace(c,``).trim()),ee=/^(?:\s|[-*+>]|\d+[.)])/;function f(e,t=0){let n=e.lastIndexOf(`
3
3
  `)+1,r=``,i=!1,a=t,o=-1,s=``;for(let c=t;c<n;){let t=e.indexOf(`
4
4
  `,c),n=e.slice(c,t);c=t+1;let l=/^\s*(`{3,}|~{3,})(.*)$/.exec(n);if(!r&&!i&&!n.trim()){o<0&&s&&(o=c);continue}!r&&!i&&o>=0&&!(ee.test(s)&&ee.test(n))&&(a=o);let u=l?.[1]??``;if(!r&&u&&!i?r=u:r&&u[0]===r[0]&&u.length>=r.length&&!l?.[2]?.trim()&&(r=``),!r&&(!u||i))for(let e of n.matchAll(/<(\/?)silent>/gi))i=!e[1];o=-1,s=n}return a}var p=/^\[(?:([^\n[\]<>]*)<([^\n[\]<>]+)>)? ?((?:\d{4}-\d{2}-\d{2} )?\d{1,2}:\d{2})?\]\n/;function te(e){let t=p.exec(e);return!t?.[2]&&!t?.[3]?{text:e}:{...t[1]?{name:t[1]}:{},...t[2]?{id:t[2]}:{},...t[3]?{when:t[3]}:{},text:e.slice(t[0].length)}}function ne(e){if(!e)return e;let{text:t}=te(e);return t===e?e:t.replace(/\s+/g,` `).trim()||e}function re(e){let t,n=!1;return()=>(n=!0,t??=(async()=>{for(;n;)n=!1,await e()})().finally(()=>{t=void 0}))}var m=(e,t,n=`POST`)=>fetch(e,{method:n,headers:{"content-type":`application/json`},body:JSON.stringify(t)});async function h(e,t){return(await e.json().catch(()=>({}))).error??`${t} (${e.status})`}async function ie(e,t,n){let r;try{r=await fetch(e,n)}catch(e){return{ok:!1,error:`${t}: ${String(e)}`}}if(!r.ok)return{ok:!1,error:await h(r,t)};try{return{ok:!0,value:await r.json()}}catch(e){return{ok:!1,error:`${t}: ${String(e)}`}}}async function ae(e,t,n){let r=await ie(e,t,n);if(!r.ok)throw Error(r.error);return r.value}async function oe(e,t,n){try{let r=await fetch(e,{method:t});return r.ok?void 0:await h(r,n)}catch(e){return`${n}: ${String(e)}`}}async function se(e,t,n,r){let i=window.prompt(e);if(!i?.trim())return{sent:!1};try{let e=await m(t,{message:i,...n});return{sent:!0,...e.ok?{response:e}:{error:await h(e,r)}}}catch(e){return{sent:!0,error:`${r}: ${String(e)}`}}}function g(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function ce(e){if(Array.isArray(e))return e}function le(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t!==0)for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function ue(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
@@ -76,4 +76,4 @@ Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error
76
76
  `),o=W.sessionState()===`idle`&&e===`auto`;o?W.setState(`streaming`):Qo(),(o||e===`steer`)&&(Xo(a),H(`user`,a,!1,Date.now()),ya(!0));let s=await m(`/api/sessions/${i}/messages`,{text:a,mode:e});if(!s.ok){let e=await h(s,`send failed`);await W.reload(i),H(`error`,e)}}finally{t===void 0&&(ds=!1)}}}async function ps(e){let t=W.sessionId();if(!t)return;ts([],[]);let n=await m(`/api/sessions/${t}/queue/deliver`,{mode:e});if(!n.ok){let r=await h(n,`Queue ${e} failed`);await W.reload(t),W.sessionId()===t&&H(`error`,r)}}async function ms(){let e=W.sessionId();if(!e||Wo.has(e))return;Wo.add(e);let t=Uo,n=ss,r=document.activeElement;try{cs();let i=await fetch(`/api/sessions/${e}/queue/recall`,{method:`POST`});if(!i.ok){let t=await h(i,`Could not recall queued messages`);W.sessionId()===e&&H(`error`,t);return}let{messages:a}=await i.json(),o=W.sessionId()===e;if(a.length)try{let t=o?G.value:localStorage.getItem(os(e))??``,i=(t?[t,...a]:a).join(`
77
77
  `);o&&(G.value=i,us(),n===ss&&W.chatVisible()&&document.activeElement===r&&G.focus()),cs(e,i)}catch(t){H(`error`,`Could not save recalled messages for session ${e}: ${String(t)}\nRecalled messages (not saved):\n${a.join(`
78
78
  `)}`)}o&&t===Uo&&ts([],[])}finally{Wo.delete(e)}}function hs(e){W=e,qo();let t=()=>{let e=W.sessionId();e&&fetch(`/api/sessions/${e}/abort`,{method:`POST`})};Fo.onclick=t,Do(Fo,`Stop the running turn`,t,()=>W.sessionState()===`streaming`&&W.chatVisible()),R(`#queue-steer`).onclick=()=>void ps(`steer`),R(`#queue-restart`).onclick=()=>void ps(`restart`),R(`#queue-recall`).onclick=()=>void ms(),jo.onsubmit=e=>{e.preventDefault(),fs(`auto`)},ko(G,[`/`],`Write a message`,Jo,W.chatVisible),G.onfocus=va,G.oninput=()=>{us(),cs()};let n=!matchMedia(`(pointer: coarse)`).matches;G.onkeydown=e=>{e.isComposing||e.keyCode===229||n&&e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),fs(`auto`))},G.onpaste=e=>{for(let t of e.clipboardData?.items??[]){let e=t.kind===`file`?t.getAsFile():null;e&&is(e)}let t=e.clipboardData?.getData(`text/plain`)??``,n=t.trim();!n||n===t||(e.preventDefault(),G.setRangeText(n,G.selectionStart??0,G.selectionEnd??0,`end`),us(),cs())},V.ondragover=e=>e.preventDefault(),V.ondrop=e=>{e.preventDefault();for(let t of e.dataTransfer?.files??[])is(t)},R(`#attach`).onclick=()=>Vo.click(),Vo.onchange=()=>{for(let e of Vo.files??[])is(e);Vo.value=``},Qo()}var gs=`pier.push`,_s=`/sw.js`,vs=()=>/iPad|iPhone|iPod/.test(navigator.userAgent)||navigator.maxTouchPoints>1&&/Macintosh/.test(navigator.userAgent),ys=()=>matchMedia(`(display-mode: standalone)`).matches||navigator.standalone===!0;function bs(){return window.isSecureContext?vs()&&!ys()?`On iPhone and iPad, notifications work only from the installed app: Share → Add to Home Screen, then open Pier from that icon.`:!(`serviceWorker`in navigator)||!(`PushManager`in window)||!(`Notification`in window)?`This browser has no Web Push support.`:``:`Notifications need HTTPS. Reach this Pier through its public URL, not over plain http.`}var xs=[[/iPhone/,`iPhone`],[/iPad/,`iPad`],[/Android/,`Android`],[/Macintosh/,`Mac`],[/Windows/,`Windows`]],Ss=[[/Edg\//,`Edge`],[/Chrome\//,`Chrome`],[/Firefox\//,`Firefox`],[/Safari\//,`Safari`]];function Cs(){let e=navigator.userAgent,t=(t,n)=>t.find(([t])=>t.test(e))?.[1]??n;return`${t(xs,`Linux`)} · ${t(Ss,`browser`)}${ys()?` (installed)`:``}`}var ws=e=>{let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n},Ts=null;async function Es(){return!(`serviceWorker`in navigator)||!window.isSecureContext?null:(Ts??=await navigator.serviceWorker.register(_s,{scope:`/`}).catch(e=>(console.warn(`service worker registration failed`,e),null)),Ts)}var Ds=(e,t)=>{let n=e?new Uint8Array(e):null;return n?.length===t.length&&n.every((e,n)=>e===t[n])};async function Os(e){let{publicKey:t}=await ae(`/api/push`,`Could not read this instance's push key`),n=ws(t),r=await e.pushManager.getSubscription();if(r){if(Ds(r.options.applicationServerKey,n))return r;await r.unsubscribe()}return e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:n})}async function ks(e){return m(`/api/push/subscribe`,{...e.toJSON(),label:Cs()})}async function As(){Ns();let e=await Es();if(!(!e||localStorage.getItem(gs)!==`on`)&&!(!(`Notification`in window)||Notification.permission!==`granted`))try{await ks(await Os(e))}catch(e){console.warn(`re-registering this browser for notifications failed`,e)}}var js=null,Ms=null;function Ns(){window.addEventListener(`beforeinstallprompt`,e=>{e.preventDefault(),js=e,Ms?.()}),window.addEventListener(`appinstalled`,()=>{js=null,Ms?.()})}function Ps(e){let t=navigator;(e>0?t.setAppBadge?.(e):t.clearAppBadge?.())?.catch(()=>{})}function Fs(){let e=z(`span`,`text-[11.5px]`,``),t=fr(`Send a test notification`),n=z(`div`,`flex items-center gap-3`,t,e),r=z(`div`,`flex flex-col gap-4`),i=()=>localStorage.getItem(gs)===`on`;async function a(){Tr(e,`saving`,`asking this browser…`);let t=await Notification.requestPermission();if(t!==`granted`)return localStorage.setItem(gs,`off`),c(),Tr(e,`failed`,t===`denied`?`Notifications are blocked for this site — allow them in the browser's site settings, then try again.`:`No answer to the permission prompt.`);let n=await Es();if(!n)return Tr(e,`failed`,`This browser refused to register a service worker.`);try{let t=await ks(await Os(n));if(!t.ok)return Tr(e,`failed`,await h(t,`Could not register this browser`));localStorage.setItem(gs,`on`),c(),Tr(e,`saved`,`This browser will be notified when a turn finishes unseen.`)}catch(t){Tr(e,`failed`,`Could not subscribe: ${String(t)}`)}}async function o(){localStorage.setItem(gs,`off`),c();let t=await(await Es())?.pushManager.getSubscription();t&&(await m(`/api/push/unsubscribe`,{endpoint:t.endpoint}),await t.unsubscribe()),Tr(e,`idle`,`This browser will not be notified.`)}t.onclick=()=>{Tr(e,`saving`,`sending…`),(async()=>{let t=await m(`/api/push/test`,{});if(!t.ok)return Tr(e,`failed`,await h(t,`Could not send`));let{sent:n,failed:r}=await t.json();Tr(e,r?`failed`:`saved`,`Handed ${String(n)} device(s) to their push service${r?`, ${String(r)} refused`:``}.`)})()};function s(){if(!js)return[];let e=fr(`Install Pier`,!0);return e.onclick=()=>{let e=js;e&&e.prompt().then(()=>e.userChoice).finally(()=>{js=null,c()})},[z(`div`,`flex items-center gap-3`,e,z(`span`,`text-[11.5px] leading-snug text-neutral-500`,`Its own window and icon — and where notifications look like an app's.`))]}function c(){let e=bs();if(e){r.replaceChildren(...s(),z(`p`,`text-[12.5px] leading-snug text-neutral-500`,e));return}let c=i()&&Notification.permission===`granted`;t.disabled=!c,r.replaceChildren(...s(),Cr(`Notify this device`,`A turn that finishes while nobody is looking at it becomes a notification here. Per browser — each device is enabled on its own.`,c,e=>void(e?a():o())),n)}return Ms=c,c(),gr(`Notifications`,`Web Push, so a finished turn reaches you with the workbench closed. Installed — Chrome's address-bar icon, or Share → Add to Home Screen on iOS — Pier notifies you the way an app does.`,r)}var K=null;function Is(e){K&&!K.contains(e.target)&&q()}function Ls(e){e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),q())}function Rs(e){K&&!K.contains(e.target)&&q()}function q(){K&&=(document.removeEventListener(`pointerdown`,Is,!0),document.removeEventListener(`keydown`,Ls,!0),window.removeEventListener(`scroll`,Rs,!0),window.removeEventListener(`resize`,q),K.remove(),null)}var zs=null;function Bs(e){let t=e.getBoundingClientRect(),n={top:t.bottom+4,left:t.left};return t.width||t.height?n:zs?.anchor===e?{top:zs.top,left:zs.left}:n}var Vs=()=>window.innerWidth<640;function Hs(e,t){q();let n=Vs();if(K=z(`div`,`fixed z-50 rounded-lg border border-neutral-200 bg-white py-1 shadow-lg ${n?`inset-x-2 bottom-2 max-h-[70dvh] overflow-y-auto pb-[calc(0.25rem+env(safe-area-inset-bottom))] text-[16px]`:`min-w-52 max-w-[min(42rem,calc(100vw-1rem))] text-[13px]`}`),K.append(t),(e.closest(`dialog[open]`)??document.body).append(K),!n){let t=Bs(e);zs={anchor:e,...t},K.style.top=`${Math.max(8,Math.min(t.top,window.innerHeight-K.offsetHeight-8))}px`,K.style.left=`${Math.max(8,Math.min(t.left,window.innerWidth-K.offsetWidth-8))}px`}document.addEventListener(`pointerdown`,Is,!0),document.addEventListener(`keydown`,Ls,!0),window.addEventListener(`scroll`,Rs,!0),window.addEventListener(`resize`,q)}function Us(e){let t=z(`button`,`flex w-full cursor-pointer items-center gap-2 px-3 text-left hover:bg-neutral-100 active:bg-neutral-100 ${Vs()?`py-3`:`py-1.5`}`,z(`span`,`flex-none w-3 text-indigo-600`,e.checked?`✓`:``),z(`span`,`truncate`,e.label));return e.hint&&t.append(z(`span`,`ml-auto flex-none text-[11.5px] text-neutral-400`,e.hint)),t.onclick=()=>e.onSelect(),t}function Ws(e,t){Hs(e,z(`div`,``,...t.map(Us)))}var Gs=e=>`${e.provider}/${e.id}`,Ks=`pier.modelFavorites`,qs=e=>`${Gs(e)}@${e.thinking}`,Js=null;async function Ys(){let{modelMenu:e}=await ae(`/api/settings`,`Could not read the pinned model menu`);return e}function Xs(){try{let e=JSON.parse(localStorage.getItem(Ks)??`[]`);return Array.isArray(e)?e.filter(e=>{let t=e;return!!t&&typeof t==`object`&&typeof t.provider==`string`&&typeof t.id==`string`&&typeof t.thinking==`string`}):[]}catch{return[]}}function Zs(e){let t=z(`button`,`flex min-w-0 flex-1 cursor-pointer items-center gap-2 px-3 py-1.5 text-left`,z(`span`,`w-3 flex-none text-indigo-600`,e.checked?`✓`:``),z(`span`,`truncate`,e.label));e.hint&&t.append(z(`span`,`ml-auto flex-none text-[11.5px] text-neutral-400`,e.hint)),e.title&&(t.title=e.title),t.onclick=()=>e.onSelect();let n=z(`button`,`flex-none cursor-pointer px-2 py-1.5 leading-none ${e.starred?`text-amber-500`:`text-neutral-300 opacity-0 hover:text-amber-500 group-hover/row:opacity-100`}`,e.starred?`★`:`☆`);return n.title=e.starred?`Unstar`:`Star this model + reasoning`,n.onclick=t=>{t.stopPropagation(),e.onStar()},z(`div`,`group/row flex w-full items-center hover:bg-neutral-100`,t,n)}function Qs({models:e,current:t,thinkingLevel:n,thinkingLevels:i,onPick:a,onThinkingPick:o}){let s=Xs(),c=n,l=z(`div`,`flex w-72 flex-col`),u=z(`div`,`flex flex-col gap-2 border-b border-neutral-200 px-2 py-2`),d=document.createElement(`input`);if(d.type=`search`,d.placeholder=`Search models`,d.setAttribute(`aria-label`,`Search models`),d.className=`w-full rounded-md border border-neutral-300 px-2 py-1.5 text-[12.5px] focus:border-indigo-400 focus:outline-none`,u.append(d),i.length){let e=z(`label`,`flex items-center gap-2 px-1 text-[12px] text-neutral-500`),t=document.createElement(`select`);t.className=`select ml-auto rounded-md border border-neutral-300 px-2 py-1 text-[12px] text-neutral-700 focus:border-indigo-400 focus:outline-none`,t.setAttribute(`aria-label`,`Reasoning level`);for(let e of i){let n=document.createElement(`option`);n.value=e,n.textContent=r(e),t.append(n)}t.value=n,t.onchange=()=>{c=t.value,re(d.value),o(c)},e.append(z(`span`,`font-medium`,`Reasoning`),t),u.append(e)}let ee=e=>{let t=qs(e);s=s.some(e=>qs(e)===t)?s.filter(e=>qs(e)!==t):[...s,e],localStorage.setItem(Ks,JSON.stringify(s)),re(d.value)},f=(e,t)=>s.some(n=>qs(n)===`${Gs(e)}@${t}`),p=z(`div`,`max-h-72 overflow-y-auto py-1`),te=new Map(e.map(e=>[Gs(e),e])),ne=(e,n,i)=>{let o=n.map(e=>({e,model:te.get(Gs(e))})).filter(e=>!!e.model&&(!i||Gs(e.model).toLowerCase().includes(i)));o.length&&p.append(z(`div`,`px-3 pb-0.5 pt-1 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),...o.map(({e,model:n})=>{let i=e.thinking??c;return Zs({label:n.id,hint:e.thinking?r(e.thinking):void 0,title:e.note,checked:!!t&&Gs(t)===Gs(n)&&c===i,starred:f(n,i),onSelect:()=>a(n,e.thinking),onStar:()=>ee({provider:n.provider,id:n.id,thinking:i})})}),z(`div`,`my-1 border-t border-neutral-100`))},re=n=>{p.replaceChildren();let r=n.trim().toLowerCase();ne(`Pinned`,Js??[],r),ne(`Starred`,s,r);let i=new Map;for(let t of e){if(r&&!Gs(t).toLowerCase().includes(r))continue;let e=i.get(t.provider);e?e.push(t):i.set(t.provider,[t])}if(!i.size){p.append(z(`div`,`px-3 py-2 text-[12.5px] text-neutral-400`,e.length?`No matching models.`:`No models available.`));return}for(let[e,n]of i){let i=n.some(e=>!!t&&Gs(t)===Gs(e)),o=document.createElement(`details`);o.open=i||r.length>0;let s=z(`summary`,`flex cursor-pointer select-none items-center gap-1.5 px-3 py-1 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400 hover:bg-neutral-100`,z(`span`,`chev`,`▶`),z(`span`,`truncate`,e),z(`span`,`ml-auto flex-none normal-case text-neutral-300`,String(n.length)));o.append(s,...n.map(e=>Zs({label:e.id,checked:!!t&&Gs(t)===Gs(e),starred:f(e,c),onSelect:()=>a(e),onStar:()=>ee({provider:e.provider,id:e.id,thinking:c})}))),p.append(o)}};return d.oninput=()=>re(d.value),re(``),Ys().then(e=>{let t=JSON.stringify(e)!==JSON.stringify(Js);Js=e,t&&re(d.value)}).catch(e=>po(`model menu unavailable`,e)),l.append(u,p),queueMicrotask(()=>d.focus()),l}function $s(e,t,n,i){let a=pr(t.model?`${t.model.id}${t.thinking?` · ${r(t.thinking)}`:``}`:t.thinking?`Pi default · ${r(t.thinking)}`:`Pi default`,`${vr} flex cursor-pointer items-center gap-1.5 truncate text-left hover:bg-neutral-50 ${t.model?`text-neutral-700`:`text-neutral-400`}`);return a.title=t.model?`${t.model.provider}/${t.model.id}`:`Whatever the project and Pi pick`,a.onclick=()=>{let e=Qs({models:n,current:t.model,thinkingLevel:t.thinking??`medium`,thinkingLevels:[...wi],onPick:(e,n)=>{q(),i({model:e,thinking:n??t.thinking})},onThinkingPick:e=>i({...t,thinking:e})}),r=pr(`Pi default`,`w-full cursor-pointer px-3 py-1.5 text-left text-[12.5px] text-neutral-500 hover:bg-neutral-100`);r.onclick=()=>{q(),i({model:null,thinking:null})};let o=z(`div`,`flex flex-col`);o.append(e,z(`div`,`border-t border-neutral-200`),r),Hs(a,o)},_r(e,a)}var ec=async e=>{let t=await ie(`/api/fs/ls${e?.startsWith(`/`)?`?path=${encodeURIComponent(e)}`:``}`,`Could not list directories`);return t.ok?t.value:null},tc=e=>e.entries.filter(e=>e.dir&&!e.name.startsWith(`.`)).map(e=>e.name),nc=(e,t,n)=>{let r=pr(e,`flex w-full cursor-pointer items-center gap-1.5 px-3 py-1 text-left ${t}`);return r.onclick=n,r};function rc(e,t){let n=z(`div`,`flex-none border-t border-neutral-200`),r=nc(`+ New folder`,`text-[12px] text-neutral-500 hover:bg-neutral-100`,()=>{let r=document.createElement(`input`);r.className=`w-full border-0 bg-transparent px-3 py-1 font-mono text-[12.5px] focus:outline-none`,r.placeholder=`folder-name`;let i=z(`p`,`hidden px-3 pb-1 text-[11.5px] text-red-600`);r.onkeydown=async n=>{if(n.key!==`Enter`)return;n.preventDefault();let a=await m(`/api/fs/mkdir`,{path:e,name:r.value});if(!a.ok){i.textContent=(await a.json()).error??`could not create`,i.classList.remove(`hidden`);return}t((await a.json()).path)},n.replaceChildren(r,i),r.focus()});return n.append(r),n}function ic(e,t,n){let r=e=>{n(e),q()};async function i(t){let n=await ec(t);if(!n)return;let a=z(`div`,`flex max-h-80 w-80 flex-col`),o=pr(`Use`,`ml-auto flex-none cursor-pointer rounded bg-indigo-600 px-2 py-0.5 text-[11.5px] text-white dark:text-neutral-50`);o.onclick=()=>r(n.path);let s=document.createElement(`input`);s.className=`min-w-0 flex-1 border-0 bg-transparent font-mono text-[11.5px] text-neutral-500 focus:outline-none`,s.value=n.path,s.spellcheck=!1,s.title=`Type or paste a path, then Enter`,s.onfocus=()=>s.select();let c=z(`p`,`hidden flex-none px-3 pb-1 text-[11.5px] text-red-600`);s.onkeydown=async e=>{if(e.key!==`Enter`)return;e.preventDefault(),e.stopPropagation();let t=s.value.trim();if(!t)return;let n=await ec(t);if(!n){c.textContent=`${t} is not a folder this can read`,c.classList.remove(`hidden`);return}r(n.path)};let l=z(`div`,`flex flex-none items-center gap-2 border-b border-neutral-200 px-3 py-1.5`,s,o),u=z(`div`,`min-h-0 flex-1 overflow-y-auto py-0.5 text-[12.5px]`);n.parent&&u.append(nc(`../`,`font-mono text-neutral-500 hover:bg-neutral-100`,()=>void i(n.parent)));let d=tc(n);for(let e of d)u.append(nc(e,`truncate hover:bg-neutral-100`,()=>void i(`${n.path}/${e}`.replace(`//`,`/`))));d.length||u.append(z(`p`,`px-3 py-1.5 text-[12px] text-neutral-400`,`No sub-folders.`)),a.append(l,c,u,rc(n.path,e=>void i(e))),Hs(e,a)}i(t)}function ac(e,t,n,r){Ws(e,[...t.map(e=>({label:e.path,...e.hint?{hint:e.hint}:{},checked:e.path===n,onSelect:()=>{q(),r(e.path)}})),{label:`Browse…`,onSelect:()=>ic(e,n||void 0,r)}])}var oc=(e,t)=>n=>{e.value=n,e.dispatchEvent(new Event(`input`,{bubbles:!0})),t?.(n)};function sc(e,t){let n=pr(`Browse…`,`flex-none cursor-pointer rounded-md border border-neutral-300 px-2 py-1 text-[12px] text-neutral-600 hover:bg-neutral-100`);return n.onclick=()=>ic(n,e.value.trim()||void 0,oc(e,t)),n}function cc(e,t){let n=oc(e);e.classList.add(`select`),e.title=`Pick a project folder, or type a path`,e.onclick=()=>{let r=e.value.trim()||void 0,i=t();if(i.length)return ac(e,i,r,n);ic(e,r,n)},e.addEventListener(`input`,()=>q())}function lc(e,t,n){let r=document.createElement(`input`);return r.className=`min-w-0 flex-1 rounded-md border border-neutral-300 bg-white px-2 py-1 font-mono text-[12.5px] focus:border-indigo-400 focus:outline-none`,r.value=e,r.placeholder=t,r.oninput=()=>n(r.value),{el:z(`div`,`flex items-center gap-1.5`,r,sc(r,n)),input:r}}var uc=R(`#sidebar`),dc=R(`#drawer-scrim`),fc=R(`#mobile-title`),pc=R(`#mobile-menu`);function mc(){delete uc.dataset.open,dc.classList.add(`hidden`)}function hc(e,t){fc.textContent=e,fc.classList.toggle(`cursor-pointer`,t),pc.classList.toggle(`hidden`,!t)}var gc=`pier.railClosed`;localStorage.getItem(gc)===`1`&&(document.body.dataset.rail=`closed`);function _c(e){document.body.dataset.rail=e?`closed`:``,localStorage.setItem(gc,e?`1`:`0`)}function vc(){if(uc.dataset.open!==void 0)return mc();uc.dataset.open=``,dc.classList.remove(`hidden`)}var yc=()=>window.innerWidth<768,bc=[R(`#rail-toggle`),R(`#drawer-toggle`)],xc=`attention absolute -right-0.5 -top-0.5 rounded-full bg-amber-500`,Sc=e=>e===1?z(`span`,`${xc} h-2 w-2`):z(`span`,`${xc} flex h-3.5 min-w-3.5 items-center justify-center px-0.5 text-[9px] font-semibold text-white`,e>9?`9+`:String(e));function Cc(e){for(let t of bc)t.querySelector(`.attention`)?.remove(),e&&t.append(Sc(e))}var wc=20,Tc=.35,Ec=8;function Dc(){let e=-1,t=0,n=!1,r=!1,i=1,a=e=>{uc.style.transition=`none`,uc.style.transform=`translateX(${String(e-i)}px)`,dc.classList.remove(`hidden`),dc.style.opacity=String(e/i)},o=t=>{uc.style.transition=``,uc.style.transform=``,dc.style.opacity=``,t?(uc.dataset.open=``,dc.classList.remove(`hidden`)):mc(),e=-1,r=!1};window.addEventListener(`touchstart`,a=>{if(r||(e=-1,!yc()||a.touches.length!==1))return;let o=a.touches[0],s=uc.dataset.open!==void 0;if(i=uc.offsetWidth||1,s){if(o.clientX>i)return}else{if(o.clientX>wc||a.target?.closest(`button, a, input, textarea, select`))return;a.preventDefault()}e=o.clientX,t=o.clientY,n=!s},{passive:!1}),window.addEventListener(`touchmove`,o=>{if(e<0)return;let s=o.touches[0],c=s.clientX-e;if(!r){if(Math.abs(s.clientY-t)>Math.abs(c))return void(e=-1);if(Math.abs(c)<Ec)return;r=!0}o.preventDefault(),a(Math.max(0,Math.min(i,n?c:i+c)))},{passive:!1});let s=()=>{if(e<0)return;if(!r)return void(e=-1);let t=uc.getBoundingClientRect().right;o(n?t>i*Tc:t>i*.65)};window.addEventListener(`touchend`,s),window.addEventListener(`touchcancel`,s)}function Oc(e){Dc(),R(`#drawer-toggle`).onclick=vc,dc.onclick=mc,pc.onclick=()=>e.sessionMenu(pc),fc.onclick=()=>{pc.classList.contains(`hidden`)||e.sessionInfo(fc)};let t=R(`#rail-toggle`);t.onclick=()=>_c(document.body.dataset.rail!==`closed`),Eo(t,`meta+b`,`Toggle sidebar`,()=>yc()?vc():_c(document.body.dataset.rail!==`closed`))}var J,kc=R(`#project-tree`),Ac=R(`#archive-dialog`),jc=R(`#archive-list`),Mc=R(`#archive-search`),Nc=R(`#archive-count`),Pc=R(`#new-dialog`),Fc=`pier.collapsedProjects`,Ic=new Set(Lc());function Lc(){try{let e=JSON.parse(localStorage.getItem(Fc)??`[]`);return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}catch{return[]}}function Rc(e,t){t?Ic.add(e):Ic.delete(e),localStorage.setItem(Fc,JSON.stringify([...Ic]))}function zc(e,t){let n=new Map;for(let r of e){let e=t(r),i=n.get(e);i?i.push(r):n.set(e,[r])}return n}var Bc=e=>zc(e,e=>e.cwd),Vc=e=>e.repo??e.cwd,Hc=e=>e.endsWith(`/.git`)?e.slice(0,-5):void 0,Uc=(e,t)=>tr(Hc(e)??t[0]?.cwd??e);function Wc(e,t){let n=Hc(e),r=[...new Set(t.map(e=>e.cwd))];return n&&r.includes(n)?[n,...r.filter(e=>e!==n)]:r}function Gc(e,t){return e===t?0:e===void 0?-1:t===void 0?1:e-t}function Kc(e){let t=[...zc(e,Vc)].map(([e,t])=>[e,[...t].sort((e,t)=>(e.branch??e.cwd).localeCompare(t.branch??t.cwd)||Gc(e.sort,t.sort)||t.createdAt-e.createdAt)]),n=e=>{let t=e.map(e=>e.projectSort).filter(e=>e!==void 0);return t.length?Math.min(...t):void 0},r=e=>Math.min(...e.map(e=>e.createdAt));return t.sort(([,e],[,t])=>Gc(n(e),n(t))||r(t)-r(e))}function qc(e,t,n,r){let i=e.filter(e=>e!==t);return i.splice(i.indexOf(n)+ +!!r,0,t),i}var Jc=()=>Kc(J.sessions().filter(e=>e.listed)),Yc=()=>Jc().flatMap(([e,t])=>Wc(e,t).map(e=>{let n=t.find(t=>t.cwd===e)?.branch;return{path:e,...n?{hint:n}:{}}}));function Xc(e,t,n,r){let i=new Map(e.map((e,t)=>[e,t]));for(let e of J.sessions()){let r=i.get(t(e));r!==void 0&&n(e,r)}gl();let a=()=>void J.loadSessions();m(`/api/projects/order`,r).then(e=>{e.ok||a()},a)}function Zc(e,t,n,r){let i=Jc().find(([t])=>t===e);if(!i)return;let a=qc(i[1].map(e=>e.id),t,n,r);Xc(a,e=>e.id,(e,t)=>e.sort=t,{sessions:a})}function Qc(e,t,n){let r=Jc(),i=qc(r.map(([e])=>e),e,t,n);Xc(i,Vc,(e,t)=>e.projectSort=t,{projects:i.flatMap(e=>{let t=r.find(([t])=>t===e);return t?Wc(e,t[1]):[]})})}var $c=null;function el(e,t){e.style.boxShadow=t===null?``:`inset 0 ${t?-2:2}px 0 0 #818cf8`}function tl(e,t,n,r){e.draggable=!0,e.ondragstart=e=>{e.stopPropagation(),$c={list:t,key:n},e.dataTransfer?.setData(`text/plain`,n)},e.ondragend=()=>{$c=null,gl(!0)};let i=t=>{let n=e.getBoundingClientRect();return t.clientY>n.top+n.height/2},a=e=>!$c||$c.list!==t||$c.key===n?!1:(e.preventDefault(),e.stopPropagation(),!0);e.ondragover=t=>{a(t)&&el(e,i(t))},e.ondragleave=()=>el(e,null),e.ondrop=t=>{let n=$c?.key;el(e,null),a(t)&&n&&r(n,i(t))}}var nl=`hidden flex-none rounded px-1 leading-none text-neutral-400 hover:bg-neutral-200 hover:text-neutral-700 group-hover:block pointer-coarse:block`,rl=e=>e.unread&&e.listed;function il(e){let[t,n]=e.state===`streaming`?[`bg-green-500 animate-pulse`,`working…`]:rl(e)?[`bg-amber-500`,`turn finished — not viewed yet`]:e.activeRuns>0?[`bg-sky-500`,`${e.activeRuns} subagent${e.activeRuns>1?`s`:``} running`]:[`bg-neutral-300`,`idle`],r=z(`span`,`h-2 w-2 flex-none rounded-full ${t}`);return r.title=n,r}async function al(e,t,n,r,i){let a=t=>{e(t),gl(),J.onPinsChanged()};a(t),(await m(r,i)).ok||a(n)}async function ol(e){let t=window.prompt(`Session name — empty resets it to the first message`,e.title??``);t!==null&&await al(t=>e.title=t,t.trim()||void 0,e.title,`/api/sessions/${e.id}/rename`,{name:t})}var sl=(e,t)=>al(t=>e.listed=t,t,!t,`/api/sessions/${e.id}/pin`,{pinned:t}),cl=(e,t)=>e.find(e=>e.cwd===t)?.branch??tr(t),ll=`flex-none truncate rounded bg-neutral-200/70 px-1 font-mono text-[10px] leading-[15px] text-neutral-500`,ul={telegram:`tg`};function dl(e){if(!e.channel||e.channel===`web`)return[];let t=z(`span`,ll,ul[e.channel]??e.channel);return t.title=`answering ${e.channel}`,[t]}function fl(e){let t=z(`li`,`group flex cursor-pointer items-center gap-1.5 py-1.5 pl-6 pr-3 hover:bg-neutral-100 ${e.id===J.currentId()?`bg-indigo-50 hover:bg-indigo-50`:``}`),n=z(`button`,nl,`⋯`);n.title=`Session actions`,n.onclick=t=>{t.stopPropagation(),J.sessionMenu(n,e)};let r=z(`button`,nl,`✓`);r.title=`Done — remove from Projects (the session and its transcript stay)`,r.onclick=t=>{t.stopPropagation(),sl(e,!1)},t.append(il(e),z(`span`,`truncate`,e.title??`untitled`),z(`div`,`ml-auto flex flex-none items-center gap-1`,...dl(e),r,n)),t.onclick=()=>J.select(e.id),t.title=`Drag to reorder`;let i=Vc(e);return tl(t,i,e.id,(t,n)=>Zc(i,t,e.id,n)),t}function pl(e,t){let n=Wc(e,t),r=n[0]??e,i=z(`span`,`flex-none text-[11px] text-neutral-400 group-hover:hidden`,String(t.length)),a=z(`button`,nl,`⋯`);a.title=`Project actions`,a.onclick=e=>{e.preventDefault(),e.stopPropagation(),Ws(a,[...n.map(e=>({label:n.length>1?`New session in ${cl(t,e)}`:`New session here`,hint:tr(e),onSelect:()=>{q(),J.createSession(e)}})),{label:`Browse files`,onSelect:()=>{q(),J.openFiles(r)}},{label:`Terminal here`,onSelect:()=>{q(),J.openTerminal(r)}},{label:`Remove ${t.length} session${t.length>1?`s`:``} from Projects`,onSelect:()=>{q();for(let e of t)sl(e,!1)}}])};let{el:o,summary:s}=ur(`border-b border-neutral-200/70`,[z(`span`,`truncate font-mono text-[11px] font-semibold uppercase tracking-wide text-neutral-500`,Uc(e,t)),z(`div`,`ml-auto flex flex-none items-center gap-1.5`,i,a)]);s.className+=` group px-3 py-1.5 hover:bg-neutral-100`,s.title=`${n.join(`
79
- `)}\nDrag to reorder`,tl(s,``,e,(t,n)=>Qc(t,e,n)),o.open=!Ic.has(e),o.ontoggle=()=>Rc(e,!o.open);let c=z(`ul`,`pb-1`);return c.append(...t.map(fl)),o.append(c),o}var ml=()=>`${J.currentId()??``}\n${JSON.stringify(J.sessions())}`,hl=``;function gl(e=!1){let t=ml();if(t===hl&&!e)return;hl=t;let n=J.sessions().filter(rl);Cc(n.length),Ps(n.filter(e=>e.channel===`web`).length);let r=Jc();kc.replaceChildren(...r.length?r.map(([e,t])=>pl(e,t)):[z(`p`,`px-3 py-2 text-[12.5px] leading-snug text-neutral-400`,`No projects yet — create a session, or pin one from All sessions.`)]),Ac.open&&El()}var _l=[{name:`tasks`,label:`Tasks`,detail:`Console — task definitions and schedules`},{name:`runs`,label:`Runs`,detail:`Console — executions, subagents, decisions and callbacks`},{name:`activity`,label:`Activity`,detail:`Console — sessions and relationships`},{name:`boards`,label:`Boards`,detail:`Console — the static pages Pier publishes`},{name:`settings`,label:`Settings`,detail:`Console — models and providers, agent files and extensions, channels, password, sign out, security`}],vl=[],yl=0,bl={ArrowDown:1,ArrowUp:-1},xl={n:1,j:1,p:-1,k:-1};function Sl(e){if(vl.length){yl=(e+vl.length)%vl.length;for(let[e,{el:t}]of vl.entries())t.classList.toggle(`bg-indigo-100`,e===yl),t.classList.toggle(`border-indigo-500`,e===yl);vl[yl]?.el.scrollIntoView({block:`nearest`})}}function Cl(e){let t=z(`button`,`flex-none rounded px-1.5 py-0.5 text-[11.5px] ${e.listed?`bg-indigo-50 text-indigo-600`:`text-neutral-400 hover:bg-neutral-200 hover:text-neutral-700`}`,e.listed?`pinned`:`pin`);return t.title=e.listed?`Remove from Projects`:`Pin to Projects`,t.onclick=t=>{t.stopPropagation(),sl(e,!e.listed)},t}function wl(e){let t=z(`li`,`flex cursor-pointer items-center gap-2 border-l-2 border-transparent px-3 py-1.5 hover:bg-neutral-100`);return t.append(e.session?il(e.session):z(`span`,`h-2 w-2 flex-none`)),t.append(z(`span`,`min-w-0 flex-1 truncate`,e.label),z(`span`,`max-w-[45%] flex-none truncate text-[11.5px] text-neutral-400`,e.detail)),e.session&&t.append(z(`span`,`flex-none text-[11px] text-neutral-400`,$n(e.session.createdAt)),Cl(e.session)),t.onclick=e.open,t}var Tl=e=>z(`li`,`px-3 pb-0.5 pt-2 text-[11px] font-semibold uppercase tracking-wide text-neutral-400`,e);function El(){let e=Mc.value.trim().toLowerCase(),t=t=>!e||t.toLowerCase().includes(e),n=e=>()=>{Ac.close(),e()},r=e=>e.channel&&e.channel!==`web`?e.channel:``,i=J.sessions().filter(e=>t(`${e.title??``} ${e.cwd} ${r(e)}`)),a=(e,t)=>t.createdAt-e.createdAt,o=e=>({label:e.title??nr(e.cwd),detail:[tr(e.cwd),r(e)].filter(Boolean).join(` · `),open:n(()=>J.select(e.id)),session:e}),s=i.filter(e=>e.state===`streaming`),c=i.filter(e=>e.state!==`streaming`),l=[`Console`,_l.filter(e=>t(`${e.label} ${e.detail}`)).map(({name:e,label:t,detail:r})=>({label:t,detail:r,open:n(()=>J.openConsole(e))}))],u=[[`Running`,s.sort(a).map(o)],[`Projects`,c.filter(e=>e.listed).sort(a).map(o)],[`Other sessions`,c.filter(e=>!e.listed).sort(a).map(o)]];e?u.unshift(l):u.push(l),vl=[];let d=[];for(let[e,t]of u)if(t.length){d.push(Tl(e));for(let e of t){let t=wl(e);vl.push({el:t,open:e.open}),d.push(t)}}jc.replaceChildren(...d.length?d:[z(`li`,`px-3 py-3 text-[13px] text-neutral-400`,`Nothing matches.`)]),Nc.textContent=String(vl.length),Sl(yl)}function Dl(){if(Ac.open)return Ac.close();Mc.value=``,yl=0,El(),Ac.showModal(),Mc.focus(),J.loadSessions().then(()=>{Ac.open&&El()})}function Ol(e){J=e,cc(R(`#new-cwd`),Yc);let t=R(`#new-session`),n=()=>{let e=J.sessions().find(e=>e.id===J.currentId())?.cwd??``,t=R(`#new-cwd`);t.value=e,Pc.showModal(),t.select()};t.onclick=n,Eo(t,`shift+o`,`New session`,n,()=>Pc.open),R(`#new-cancel`).onclick=()=>Pc.close(),R(`#new-form`).onsubmit=()=>void J.createSession(R(`#new-cwd`).value.trim());let r=R(`#open-archive`);r.onclick=Dl,Eo(r,`k`,`Search sessions and Console`,Dl,()=>Ac.open),R(`#archive-close`).onclick=()=>Ac.close(),Mc.oninput=()=>{yl=0,El()},Mc.onkeydown=e=>{let t=e.altKey||e.metaKey||e.shiftKey||!e.key?void 0:e.ctrlKey?xl[e.key.toLowerCase()]:bl[e.key];if(t!==void 0){e.preventDefault(),Sl(yl+t);return}e.key===`Enter`&&!e.ctrlKey&&(e.preventDefault(),vl[yl]?.open())}}var Y;function kl(e){Y=e,Ao(jl,()=>{let e=Y.currentSession();e&&(q(),sl(e,!e.listed))},Al),Ao(Ml,()=>{Y.currentSession()&&(q(),Y.toggleFiles())},Al)}var Al=()=>document.querySelector(`dialog[open]`)!==null,jl=`d`,Ml=`i`,Nl=R(`#chat-title`),Pl=R(`#chat-menu`),Fl=R(`#session-meta`),Il=null,Ll=null,Rl=null,zl=null;function Bl(){Il=null,Ll=null,Rl=null,zl=null,Jl()}function Vl(e,t,n,r){Il=e,Ll=t,Rl=n,zl=r,Gl()}function Hl(e){zl=e.completedAt,Ll&&={...Ll,tokens:e.tokens},Jl()}var Ul=null;function Wl(e){Ul=e===null?null:nr(e),Gl()}function Gl(){let e=Y.currentSession();e&&(Ul=null),Nl.textContent=e?e.title??nr(e.cwd):Ul??`no session`,Nl.classList.toggle(`cursor-pointer`,!!e),Nl.title=e?`Session info`:``,Nl.onclick=e?()=>Yl(Nl,e):null,Pl.classList.toggle(`hidden`,!e),e&&(Pl.onclick=()=>tu(Pl,e)),Jl(),Y.syncBar()}var Kl=(e,t)=>Math.min(100,Math.round(e/t.contextWindow*100)),ql=e=>e.tokens===null?`?/${i(e.contextWindow)}`:`${i(e.tokens)}/${i(e.contextWindow)} · ${100-Kl(e.tokens,e)}% left`;function Jl(){let e=Ll,t=e?.tokens??null,n=Y.currentId(),r=[];if(!n&&Ul&&r.push(z(`span`,`flex flex-none items-center gap-1.5 text-neutral-500`,z(`span`,`spinner`),`starting…`)),n){let e=(e,t)=>{let r=z(`button`,`flex-none cursor-pointer font-mono ${t}`,e);return r.title=`Change model or reasoning`,r.onclick=()=>void Xl(r,n),r};Il&&r.push(e(Il.id,`rounded bg-indigo-50 px-1.5 py-px font-medium text-indigo-700 hover:bg-indigo-100`)),Rl&&r.push(e(Rl,`text-neutral-500 hover:text-indigo-700`))}if(e&&t!==null){let n=Kl(t,e),a=n>=90?`text-red-700`:n>=70?`text-amber-700`:`text-neutral-500`;r.push(z(`span`,`flex-none font-mono ${a}`,i(t).toLowerCase()))}let a=r.flatMap((e,t)=>t===0?[e]:[z(`span`,`text-neutral-300`,`·`),e]);Fl.replaceChildren(...a),Fl.classList.toggle(`hidden`,r.length===0),Fl.classList.toggle(`flex`,r.length>0)}function Yl(e,t){let n=[[`Title`,t.title??`untitled`],[`Directory`,t.cwd],[`Session`,t.id]],r=t.id===Y.currentId();if(r&&(n.push([`Model`,Il?.id??`—`]),n.push([`Reasoning`,Rl??`—`]),n.push([`Context`,Ll?ql(Ll):`—`])),n.push([`Created`,rr(t.createdAt),er(t.createdAt)]),r){let e=zl;n.push(e===null?[`Last reply`,`—`]:[`Last reply`,rr(e),er(e)])}let i=z(`div`,`flex max-w-80 flex-col gap-1.5 px-3 py-2`);for(let[e,t,r]of n){let n=z(`div`,`flex items-center gap-1.5`,z(`span`,`text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),lr(`cursor-pointer text-[10.5px] uppercase tracking-wide text-neutral-400 opacity-0 hover:text-neutral-700 focus:opacity-100 group-hover:opacity-100 pointer-coarse:opacity-100`,()=>t)),a=z(`span`,`break-all font-mono text-[12px] text-neutral-700`,t);r&&a.append(z(`span`,`ml-1.5 font-sans text-[11px] text-neutral-400`,r)),i.append(z(`div`,`group flex flex-col`,n,a))}Hs(e,i)}async function Xl(e,t){try{let[n,r]=await Promise.all([ae(`/api/sessions/${t}/models`,`Could not load models`),ae(`/api/sessions/${t}/thinking`,`Could not read the reasoning level`)]);Hs(e,Qs({models:n,current:t===Y.currentId()?Il:null,thinkingLevel:r.level,thinkingLevels:r.levels,onPick:(e,n)=>{q(),Zl(t,e,n)},onThinkingPick:e=>void $l(t,e)}))}catch(e){H(`error`,`model options failed: ${String(e)}`)}}async function Zl(e,t,n){await Ql(e,t)&&n&&await $l(e,n)}async function Ql(e,t){let n=Il;e===Y.currentId()&&(Il=t,Gl());let r=await m(`/api/sessions/${e}/model`,t);if(!r.ok){let{error:t}=await r.json().catch(()=>({}));return e===Y.currentId()&&(Il=n,Gl()),H(`error`,`model change failed: ${t??r.status}`),!1}let{model:i}=await r.json();return e===Y.currentId()&&i&&(Il=i,Gl()),!0}async function $l(e,t){let n=await m(`/api/sessions/${e}/thinking`,{level:t});if(!n.ok){H(`error`,`reasoning change failed: ${n.status}`);return}let{level:r}=await n.json();e===Y.currentId()&&(Rl=r,Jl())}async function eu(e){let t=await m(`/api/sessions/${e}/compact`,{});t.ok||H(`error`,`compact failed: ${await h(t,`no reason given`)}`)}function tu(e,t){let n=t.id===Y.currentId();Ws(e,[{label:`Session info`,onSelect:()=>Yl(e,t)},{label:`Rename…`,onSelect:()=>{q(),ol(t)}},{label:t.listed?`Done — remove from Projects`:`Pin to Projects`,hint:n?Co(jl):``,onSelect:()=>{q(),sl(t,!t.listed)}},{label:`Model`,hint:n?Il?.id??`…`:``,onSelect:()=>void Xl(e,t.id)},{label:`Compact context`,onSelect:()=>{q(),eu(t.id)}},{label:`New session here`,hint:tr(t.cwd),onSelect:()=>{q(),Y.createSession(t.cwd)}},{label:`Browse files`,hint:n?Co(Ml):``,onSelect:()=>{q(),Y.openFiles(n?void 0:t.cwd)}}])}var nu=`pier.theme`,ru=[`system`,`light`,`dark`],iu=window.matchMedia(`(prefers-color-scheme: dark)`),au={system:`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" class="h-3.5 w-3.5"><circle cx="8" cy="8" r="5.25"/><path d="M8 2.75a5.25 5.25 0 0 0 0 10.5z" fill="currentColor" stroke="none"/></svg>`,light:`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" class="h-3.5 w-3.5"><circle cx="8" cy="8" r="3.1"/><path d="M8 1.5v1.4M8 13.1v1.4M1.5 8h1.4M13.1 8h1.4M3.4 3.4l1 1M11.6 11.6l1 1M12.6 3.4l-1 1M4.4 11.6l-1 1"/></svg>`,dark:`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" class="h-3.5 w-3.5"><path d="M13 9.4A5.6 5.6 0 0 1 6.6 3a5.6 5.6 0 1 0 6.4 6.4z"/></svg>`},ou=()=>{let e=null;try{e=localStorage.getItem(nu)}catch{return`system`}return e===`light`||e===`dark`?e:`system`},su=()=>{let e=ou();return e===`system`?iu.matches?`dark`:`light`:e};function cu(){let e=su();document.documentElement.dataset.theme=e,R(`meta[name="theme-color"]`).setAttribute(`content`,e===`dark`?`#1c1c1c`:`#fafafa`),window.dispatchEvent(new Event(`pier:theme`))}function lu(){let e=R(`#theme-toggle`),t=()=>{let t=ou();e.title=`Theme: ${t}${t===`system`?` (${su()})`:``}`,e.innerHTML=au[t],cu()};e.onclick=()=>{let e=ru[(ru.indexOf(ou())+1)%ru.length];try{e===`system`?localStorage.removeItem(nu):localStorage.setItem(nu,e)}catch{}t()},iu.addEventListener(`change`,t),t()}var uu=`https://github.com/timqi/pier`,du=[`text-neutral-400`,`hover:text-neutral-700`],fu=[`rounded-full`,`bg-emerald-50`,`px-1.5`,`text-emerald-700`,`ring-1`,`ring-inset`,`ring-emerald-600/20`,`hover:bg-emerald-100`],pu=18e5,mu=null,hu=R(`#version`);function gu(e){let t=mu?.available===!0&&mu.latest!==null;hu.textContent=`v${e}`,hu.title=t?`Pier ${mu?.latest} is out`:``,hu.classList.remove(...t?du:fu),hu.classList.add(...t?fu:du)}var _u=e=>z(`p`,`px-3 py-1 text-[12px] leading-snug text-neutral-500`,e);function vu(){let e=z(`div`,`flex w-72 flex-col gap-1 py-1`);if(!mu)return e.append(_u(`Checking the registry…`)),e;let{current:t,latest:n,available:r,canApply:i,problem:a}=mu;e.append(z(`p`,`px-3 py-1 text-[12.5px] font-medium text-neutral-700`,r?`Pier ${n} is out`:`Pier ${t}`)),e.append(_u(r?`You are running ${t}.`:n===null?`The registry could not be reached, so this may not be the latest.`:`This is the latest release.`));let o=z(`span`,`px-3 text-[11.5px] text-neutral-400`,``),s=z(`div`,`flex items-center gap-2 px-3 py-1.5`);if(a&&e.append(z(`p`,`mx-3 my-1 rounded-md bg-red-50 px-2 py-1.5 text-[11.5px] leading-snug text-red-700`,a)),r&&i&&!a){let e=fr(`Update now`,!0);e.onclick=()=>{e.disabled=!0,o.className=`px-3 text-[11.5px] text-neutral-400`,o.textContent=`starting the updater…`,(async()=>{let t=await m(`/api/update`,{});if(!t.ok){e.disabled=!1,o.className=`px-3 text-[11.5px] text-red-600`,o.textContent=await h(t,`Could not update`);return}let{draining:n}=await t.json();o.textContent=n?`Waiting for running work to finish — Pier then stops, installs and starts again.`:`Pier is stopping, installing and starting again — this page reconnects on its own.`})()},s.append(e)}let c=z(`a`,`btn text-[12.5px] no-underline`,`Source`);c.href=r?`${uu}/releases`:uu,c.target=`_blank`,c.rel=`noreferrer`,c.title=`Pier is free software (AGPL-3.0)`,s.append(c),e.append(s,o),r&&!i&&!a&&e.append(_u(`No service manager owns this Pier, so it cannot restart itself — update it with: pier update`));let l=Cr(`Update automatically`,i?`Installs a new release once nothing is running — no turn in flight, no task run.`:`Needs the systemd service (pier service install); nothing here can restart Pier.`,mu.autoUpdate,e=>{mu&&(mu.autoUpdate=e),(async()=>{let t=await m(`/api/settings`,{autoUpdate:e},`PUT`);if(t.ok)return;mu&&(mu.autoUpdate=!e);let n=l.querySelector(`input`);n&&(n.checked=!e),o.className=`px-3 text-[11.5px] text-red-600`,o.textContent=await h(t,`Could not save`)})()});if(!i){let e=l.querySelector(`input`);e&&(e.disabled=!0)}return e.append(z(`div`,`mt-1 border-t border-neutral-200 px-3 pb-1 pt-2`,l)),e}async function yu(e){let t=await ie(`/api/update`,`Update check failed`);t.ok&&(mu=t.value,gu(mu.current||e))}function bu(e){gu(e),hu.onclick=e=>{e.preventDefault(),Hs(hu,vu())};let t=()=>void yu(e).catch(()=>{});t(),setInterval(t,pu)}var X,xu=R(`#chat-header`),Su=R(`#chat-title`),Cu=[xu,V,R(`#composer`)],wu=()=>ju===null,Tu,Eu,Du,Ou=new Map,ku=new Map,Au=new Map,ju=null,Mu=0,Nu=[`files`,`terminal`],Pu=new Map,Fu={tasks:`Tasks`,runs:`Runs`,activity:`Activity`,boards:`Boards`,settings:`Settings`,files:`Files`,terminal:`Terminal`},Iu=e=>Tu?.refresh(e),Lu=()=>Eu?.refresh(),Ru=()=>Du?.refresh();function zu(){ju?hc(Fu[ju],!1):hc(Su.textContent??``,X.currentSession()!==void 0)}function Z(e,t,n){if(Nu.includes(e)){let t=$u();t&&(t.kind!==`console`||t.name!==e)&&Pu.set(e,t)}td({kind:`console`,name:e,arg:t,query:n}),mc(),ju=e;for(let e of Cu)e.classList.add(`hidden`);$o();for(let[t,n]of Ou)t!==e&&n.hide();for(let[t,n]of Au)n.classList.toggle(`bg-indigo-50`,t===e);zu(),Bu(e,t,n,++Mu)}async function Bu(e,t,n,r){let i=Ou.get(e);if(!i){let t=ku.get(e);if(!t){let n=R(`#${e}-view`);t=id[e](n).catch(t=>(console.warn(`${e} view failed to load`,t),ar(n,()=>n.replaceChildren(z(`p`,`p-4 text-[13px] text-red-600`,`Could not load ${Fu[e]} — reload the page.`))))),ku.set(e,t)}i=await t,Ou.set(e,i),ku.delete(e)}ju===e&&r===Mu&&i.show(t,n)}var Vu=e=>Z(`tasks`,e),Hu=(e={},t)=>Z(`runs`,t,new URLSearchParams(e).toString()),Uu=e=>Hu({},e),Wu=e=>Z(`files`,e),Gu=e=>Z(`terminal`,e),Ku=(e,t)=>{ju===e?Yu(e):Z(e,t)},qu=e=>Ku(`files`,e),Ju=e=>Ku(`terminal`,e);function Yu(e){let t=X.currentId(),n=Pu.get(e)??(t?{kind:`session`,id:t}:null);Pu.delete(e),n?td(n):(history.replaceState(null,``,`#/`),Xu())}function Xu(){if(ju){ju=null;for(let e of Ou.values())e.hide();for(let e of Au.values())e.classList.remove(`bg-indigo-50`);for(let e of Cu)e.classList.remove(`hidden`);$o(),zu(),X.maybeAckRead()}}var Zu=e=>e.kind===`session`?`#/session/${encodeURIComponent(e.id)}`:`#/${e.name}${e.arg?`/${encodeURIComponent(e.arg)}`:``}${e.query?`?${e.query}`:``}`,Qu={config:`files`,channels:`channels`,providers:`models`};function $u(){let e=location.hash.replace(/^#\/?/,``),t=e.indexOf(`?`),[n=``,r]=(t<0?e:e.slice(0,t)).split(`/`),i=t<0?void 0:e.slice(t+1)||void 0,a;try{a=r?decodeURIComponent(r):void 0}catch{return null}return Qu[n]?{kind:`console`,name:`settings`,arg:Qu[n]}:Object.hasOwn(Fu,n)?{kind:`console`,name:n,arg:a,query:i}:n===`session`&&a?{kind:`session`,id:a}:null}var ed=!1;function td(e,t=!1){if(ed)return;let n=Zu(e);location.hash!==n&&(t?history.replaceState(null,``,n):location.hash=n)}var nd=e=>td({kind:`session`,id:e});function rd(){let e=$u(),t=X.sessions(),n=X.currentId(),r=(e?.kind===`session`?e.id:null)??n??(t.find(e=>e.listed)??t[0])?.id??null;ed=!0;try{r&&r!==n&&X.select(r),e?.kind===`console`?Z(e.name,e.arg,e.query):Xu(),r||Gl()}finally{ed=!1}e?.kind!==`console`&&r&&td({kind:`session`,id:r},!0)}var id={tasks:async e=>Tu=(await di(async()=>{let{createTasksView:e}=await import(`./tasks-DybtogPF.js`);return{createTasksView:e}},__vite__mapDeps([0,1]))).createTasksView(e,()=>X.sessions().map(({id:e,cwd:t,title:n})=>({id:e,cwd:t,title:n})),X.loadSessions,X.select,()=>X.currentId(),Hu,Vu),runs:async e=>Eu=(await di(async()=>{let{createRunsView:e}=await import(`./runs-BAXZF-6r.js`);return{createRunsView:e}},__vite__mapDeps([2,1]))).createRunsView(e,X.select,()=>X.currentId(),Hu,Vu),activity:async e=>Du=(await di(async()=>{let{createActivityView:e}=await import(`./activity-DYo7QS7k.js`);return{createActivityView:e}},[])).createActivityView(e,X.select,Uu),boards:async e=>(await di(async()=>{let{createBoardsView:e}=await import(`./boards-CwohTbtv.js`);return{createBoardsView:e}},[])).createBoardsView(e,X.select),files:async e=>(await di(async()=>{let{createExplorerView:e}=await import(`./explorer-50no_DrD.js`);return{createExplorerView:e}},__vite__mapDeps([3,4]))).createExplorerView(e,()=>X.currentSession(),e=>Z(`files`,e),e=>Z(`terminal`,e),()=>Yu(`files`)),terminal:async e=>(await di(async()=>{let{createTerminalView:e}=await import(`./terminal-m2_WYu5W.js`);return{createTerminalView:e}},[])).createTerminalView(e,()=>[...Bc(X.sessions()).keys()],()=>X.currentSession()?.cwd,e=>Z(`terminal`,e),e=>Z(`files`,e),()=>Yu(`terminal`)),settings:async e=>(await di(async()=>{let{createSettingsView:e}=await import(`./settings-BmNXgRne.js`);return{createSettingsView:e}},__vite__mapDeps([5,4]))).createSettingsView(e,()=>[...Bc(X.sessions()).keys()],e=>Z(`settings`,e))};function ad(e){X=e;let t=R(`#open-terminal`);t.onclick=()=>Ju(),Eo(t,`meta+;`,`Terminal`,()=>Ju());for(let e of[`tasks`,`runs`,`activity`,`boards`,`settings`]){let t=R(`#open-${e}`);Au.set(e,t),t.onclick=()=>Z(e)}let n=R(`#console-section`);n.open=localStorage.getItem(`pier.consoleCollapsed`)!==`1`,n.ontoggle=()=>localStorage.setItem(`pier.consoleCollapsed`,n.open?`0`:`1`),window.onhashchange=rd}var Q=[],od=0,sd=0,cd=!1,$=null,ld=`idle`,ud=null,dd=0,fd=!1,pd=!1;async function md(e){let t=++od;++sd,cd=!1,Xu(),mc(),$=null,ud?.close(),ud=null,ro(),es([]),Bl(),Wl(e),io(!0),pd=!0,Qo();let n=await m(`/api/sessions`,{cwd:e});if(t!==od)return;if(pd=!1,!n.ok){io(!1),Wl(null),Qo(),H(`error`,`session create failed: ${n.status}`);return}let{id:r}=await n.json();if(t!==od)return;let{repo:i,branch:a}=Q.find(t=>t.cwd===e)??{};Q.unshift({id:r,cwd:e,createdAt:Date.now(),state:`idle`,listed:!0,unread:!1,channel:`web`,activeRuns:0,repo:i,branch:a}),await Td(r),$===r&&Jo()}function hd(e,t){let n=e.map(e=>({...e,title:ne(e.title)}));if(t)Q=n;else{let e=new Map(n.map(e=>[e.id,e]));Q=Q.map(t=>e.get(t.id)??(t.listed?{...t,listed:!1}:t));let t=new Set(Q.map(e=>e.id));Q.push(...n.filter(e=>!t.has(e.id)))}Q.sort((e,t)=>t.createdAt-e.createdAt),gl(),vd()}var gd=re(async()=>{hd(await ae(`/api/projects`,`Could not load projects`),!1)}),_d=re(async()=>{hd(await ae(`/api/sessions`,`Could not load sessions`),!0)});function vd(){if(document.hidden||!document.hasFocus()||!wu())return;let e=Q.find(e=>e.id===$);e?.unread&&(e.unread=!1,gl(),fetch(`/api/sessions/${e.id}/read`,{method:`POST`}))}function yd(){return Q.find(e=>e.id===$)}function bd(e,t){let n=Q.find(t=>t.id===e);!n||n.title||!t.trim()||(n.title=t.trim().slice(0,80),gl(),Gl())}function xd(e){ld=e;let t=Q.find(e=>e.id===$);t&&(t.state=e),gl(),Gl(),Qo(),e===`idle`&&gd()}function Sd(e){if(!(e.sessionId!==$||e.seq<=dd))switch(dd=e.seq,e.type){case`turn-start`:fd=!0;break;case`system-input`:eo(),Da(e.text,e.origin);break;case`task-status`:Pi(e.run);break;case`user-message`:{let t=te(e.text).text;if(bd(e.sessionId,t),Yo(t))break;eo(),H(`user`,e.text,!1,e.ts),ya();break}case`text-delta`:$a(e.text);break;case`thinking-delta`:oa(e.ts,e.text);break;case`tool-start`:eo(),ia(e.ts,e.toolCallId,e.toolName,e.args);break;case`tool-end`:aa(e.toolCallId,e.isError,e.output);break;case`turn-end`:fd=!1,to(e.text,e.meta),e.meta&&Hl(e.meta);break;case`queue-state`:ts(e.steering,e.followUp);break;case`queue-recovery`:es(e.batches,e.uncertain);break;case`context-compacted`:eo(),H(`system`,`Context compacted — ${i(e.before)} → ${i(e.after)}`,!1,e.ts),ya();break;case`error`:na(),H(`error`,e.message);break;case`state`:e.state===`idle`&&fd&&(fd=!1,no()),e.state===`idle`&&ts([],[]),xd(e.state)}}function Cd(){let e=new EventSource(`/api/events`);e.onopen=()=>void gd(),e.onerror=()=>vo(e,`Workspace`),e.onmessage=e=>{let t=JSON.parse(e.data);if(t.type===`sessions-changed`){gd();return}if(t.type===`tasks-changed`||t.type===`task-run-changed`||t.type===`task-message-changed`||t.type===`task-group-changed`){Iu(t.type===`task-run-changed`?t.taskId:void 0),Lu(),Ru(),t.type===`task-run-changed`&&gd();return}if(Ru(),t.sessionId===$)return;let n=Q.find(e=>e.id===t.sessionId);n&&(n.state=t.state,gl())}}function wd(e,t,n){ud?.close();let r=new EventSource(`/api/sessions/${e}/events?after=${t}`),i=()=>ud===r&&$===e&&n===sd;r.onmessage=e=>{i()&&Sd(JSON.parse(e.data))},r.addEventListener(`reset`,()=>{i()&&Ed(e)}),r.onerror=()=>{i()&&vo(r,`Session`)},ud=r}async function Td(e){Xu(),mc(),nd(e);let t=Q.some(t=>t.id===e);if(e===$&&t&&(ud||cd))return;let n=++od;if(++sd,pd=!1,cs(),$=e,ld=Q.find(t=>t.id===e)?.state??`idle`,ls(e),gl(),Gl(),vd(),t)return await Ed(e);ud?.close(),ud=null,ro(),io(!0),await _d(),n===od&&$===e&&await Ed(e,!Q.some(t=>t.id===e))}async function Ed(e,t=!1){if($!==e)return;let n=++sd;if(ud?.close(),ud=null,cd=!0,ro(),ts([],[]),es([]),Bl(),fd=!1,Zo(),dd=0,io(!0),t){cd=!1,io(!1),H(`error`,`session not found: ${e}`);return}let r=await ie(`/api/sessions/${e}/history`,`failed to load session`);if($!==e||n!==sd)return;if(cd=!1,!r.ok){io(!1),H(`error`,r.error);return}let i=r.value;ao(i.turns,i.state,i.backgroundRuns),dd=i.lastSeq,fd=i.state===`streaming`,xd(i.state),ts(i.queue.steering,i.queue.followUp),es(i.queueRecovery,i.queueUncertain);let a=i.turns.reduce((e,t)=>t.meta?.completedAt??e,null);Vl(i.model,i.context,i.thinkingLevel,a),wd(e,`${i.epoch}:${i.lastSeq}`,n)}mo(),_o(),lu();var Dd=async e=>{$===e&&await Ed(e)};fa({sessionId:()=>$,sessionState:()=>ld,select:e=>void Td(e),showRun:Uu,send:(e,t)=>void fs(e,t),ownTurn:e=>{Xo(e),xd(`streaming`)},reload:Dd}),hs({sessionId:()=>$,starting:()=>pd,sessionState:()=>ld,chatVisible:wu,setState:xd,reload:Dd}),Oc({sessionMenu:e=>{let t=yd();t&&tu(e,t)},sessionInfo:e=>{let t=yd();t&&Yl(e,t)}}),Ol({sessions:()=>Q,loadSessions:_d,currentId:()=>$,select:e=>void Td(e),sessionMenu:tu,createSession:md,openFiles:Wu,openTerminal:Gu,openConsole:Z,onPinsChanged:Gl}),kl({currentId:()=>$,currentSession:yd,createSession:e=>void md(e),syncBar:zu,openFiles:Wu,toggleFiles:qu}),ad({sessions:()=>Q,loadSessions:_d,currentId:()=>$,currentSession:yd,select:e=>void Td(e),maybeAckRead:vd}),bu(`0.0.20`),As(),document.addEventListener(`visibilitychange`,vd),window.addEventListener(`focus`,vd),Cd(),gd().then(rd);export{er as A,h as B,xr as C,Sr as D,yr as E,ir as F,m as G,ae as H,z as I,ne as K,$n as L,ar as M,lr as N,Cr as O,ur as P,nr as R,hr as S,mr as T,se as U,ie as V,oe as W,gr as _,Hs as a,Or as b,wi as c,di as d,vr as f,fr as g,pr as h,q as i,tr as j,kr as k,_i as l,Er as m,ac as n,Fs as o,wr as p,r as q,$s as r,ko as s,lc as t,vi as u,Dr as v,Tr as w,br as x,_r as y,re as z};
79
+ `)}\nDrag to reorder`,tl(s,``,e,(t,n)=>Qc(t,e,n)),o.open=!Ic.has(e),o.ontoggle=()=>Rc(e,!o.open);let c=z(`ul`,`pb-1`);return c.append(...t.map(fl)),o.append(c),o}var ml=()=>`${J.currentId()??``}\n${JSON.stringify(J.sessions())}`,hl=``;function gl(e=!1){let t=ml();if(t===hl&&!e)return;hl=t;let n=J.sessions().filter(rl);Cc(n.length),Ps(n.filter(e=>e.channel===`web`).length);let r=Jc();kc.replaceChildren(...r.length?r.map(([e,t])=>pl(e,t)):[z(`p`,`px-3 py-2 text-[12.5px] leading-snug text-neutral-400`,`No projects yet — create a session, or pin one from All sessions.`)]),Ac.open&&El()}var _l=[{name:`tasks`,label:`Tasks`,detail:`Console — task definitions and schedules`},{name:`runs`,label:`Runs`,detail:`Console — executions, subagents, decisions and callbacks`},{name:`activity`,label:`Activity`,detail:`Console — sessions and relationships`},{name:`boards`,label:`Boards`,detail:`Console — the static pages Pier publishes`},{name:`settings`,label:`Settings`,detail:`Console — models and providers, agent files and extensions, channels, password, sign out, security`}],vl=[],yl=0,bl={ArrowDown:1,ArrowUp:-1},xl={n:1,j:1,p:-1,k:-1};function Sl(e){if(vl.length){yl=(e+vl.length)%vl.length;for(let[e,{el:t}]of vl.entries())t.classList.toggle(`bg-indigo-100`,e===yl),t.classList.toggle(`border-indigo-500`,e===yl);vl[yl]?.el.scrollIntoView({block:`nearest`})}}function Cl(e){let t=z(`button`,`flex-none rounded px-1.5 py-0.5 text-[11.5px] ${e.listed?`bg-indigo-50 text-indigo-600`:`text-neutral-400 hover:bg-neutral-200 hover:text-neutral-700`}`,e.listed?`pinned`:`pin`);return t.title=e.listed?`Remove from Projects`:`Pin to Projects`,t.onclick=t=>{t.stopPropagation(),sl(e,!e.listed)},t}function wl(e){let t=z(`li`,`flex cursor-pointer items-center gap-2 border-l-2 border-transparent px-3 py-1.5 hover:bg-neutral-100`);return t.append(e.session?il(e.session):z(`span`,`h-2 w-2 flex-none`)),t.append(z(`span`,`min-w-0 flex-1 truncate`,e.label),z(`span`,`max-w-[45%] flex-none truncate text-[11.5px] text-neutral-400`,e.detail)),e.session&&t.append(z(`span`,`flex-none text-[11px] text-neutral-400`,$n(e.session.createdAt)),Cl(e.session)),t.onclick=e.open,t}var Tl=e=>z(`li`,`px-3 pb-0.5 pt-2 text-[11px] font-semibold uppercase tracking-wide text-neutral-400`,e);function El(){let e=Mc.value.trim().toLowerCase(),t=t=>!e||t.toLowerCase().includes(e),n=e=>()=>{Ac.close(),e()},r=e=>e.channel&&e.channel!==`web`?e.channel:``,i=J.sessions().filter(e=>t(`${e.title??``} ${e.cwd} ${r(e)}`)),a=(e,t)=>t.createdAt-e.createdAt,o=e=>({label:e.title??nr(e.cwd),detail:[tr(e.cwd),r(e)].filter(Boolean).join(` · `),open:n(()=>J.select(e.id)),session:e}),s=i.filter(e=>e.state===`streaming`),c=i.filter(e=>e.state!==`streaming`),l=[`Console`,_l.filter(e=>t(`${e.label} ${e.detail}`)).map(({name:e,label:t,detail:r})=>({label:t,detail:r,open:n(()=>J.openConsole(e))}))],u=[[`Running`,s.sort(a).map(o)],[`Projects`,c.filter(e=>e.listed).sort(a).map(o)],[`Other sessions`,c.filter(e=>!e.listed).sort(a).map(o)]];e?u.unshift(l):u.push(l),vl=[];let d=[];for(let[e,t]of u)if(t.length){d.push(Tl(e));for(let e of t){let t=wl(e);vl.push({el:t,open:e.open}),d.push(t)}}jc.replaceChildren(...d.length?d:[z(`li`,`px-3 py-3 text-[13px] text-neutral-400`,`Nothing matches.`)]),Nc.textContent=String(vl.length),Sl(yl)}function Dl(){if(Ac.open)return Ac.close();Mc.value=``,yl=0,El(),Ac.showModal(),Mc.focus(),J.loadSessions().then(()=>{Ac.open&&El()})}function Ol(e){J=e,cc(R(`#new-cwd`),Yc);let t=R(`#new-session`),n=()=>{let e=J.sessions().find(e=>e.id===J.currentId())?.cwd??``,t=R(`#new-cwd`);t.value=e,Pc.showModal(),t.select()};t.onclick=n,Eo(t,`shift+o`,`New session`,n,()=>Pc.open),R(`#new-cancel`).onclick=()=>Pc.close(),R(`#new-form`).onsubmit=()=>void J.createSession(R(`#new-cwd`).value.trim());let r=R(`#open-archive`);r.onclick=Dl,Eo(r,`k`,`Search sessions and Console`,Dl,()=>Ac.open),R(`#archive-close`).onclick=()=>Ac.close(),Mc.oninput=()=>{yl=0,El()},Mc.onkeydown=e=>{let t=e.altKey||e.metaKey||e.shiftKey||!e.key?void 0:e.ctrlKey?xl[e.key.toLowerCase()]:bl[e.key];if(t!==void 0){e.preventDefault(),Sl(yl+t);return}e.key===`Enter`&&!e.ctrlKey&&(e.preventDefault(),vl[yl]?.open())}}var Y;function kl(e){Y=e,Ao(jl,()=>{let e=Y.currentSession();e&&(q(),sl(e,!e.listed))},Al),Ao(Ml,()=>{Y.currentSession()&&(q(),Y.toggleFiles())},Al)}var Al=()=>document.querySelector(`dialog[open]`)!==null,jl=`d`,Ml=`i`,Nl=R(`#chat-title`),Pl=R(`#chat-menu`),Fl=R(`#session-meta`),Il=null,Ll=null,Rl=null,zl=null;function Bl(){Il=null,Ll=null,Rl=null,zl=null,Jl()}function Vl(e,t,n,r){Il=e,Ll=t,Rl=n,zl=r,Gl()}function Hl(e){zl=e.completedAt,Ll&&={...Ll,tokens:e.tokens},Jl()}var Ul=null;function Wl(e){Ul=e===null?null:nr(e),Gl()}function Gl(){let e=Y.currentSession();e&&(Ul=null),Nl.textContent=e?e.title??nr(e.cwd):Ul??`no session`,Nl.classList.toggle(`cursor-pointer`,!!e),Nl.title=e?`Session info`:``,Nl.onclick=e?()=>Yl(Nl,e):null,Pl.classList.toggle(`hidden`,!e),e&&(Pl.onclick=()=>tu(Pl,e)),Jl(),Y.syncBar()}var Kl=(e,t)=>Math.min(100,Math.round(e/t.contextWindow*100)),ql=e=>e.tokens===null?`?/${i(e.contextWindow)}`:`${i(e.tokens)}/${i(e.contextWindow)} · ${100-Kl(e.tokens,e)}% left`;function Jl(){let e=Ll,t=e?.tokens??null,n=Y.currentId(),r=[];if(!n&&Ul&&r.push(z(`span`,`flex flex-none items-center gap-1.5 text-neutral-500`,z(`span`,`spinner`),`starting…`)),n){let e=(e,t)=>{let r=z(`button`,`flex-none cursor-pointer font-mono ${t}`,e);return r.title=`Change model or reasoning`,r.onclick=()=>void Xl(r,n),r};Il&&r.push(e(Il.id,`rounded bg-indigo-50 px-1.5 py-px font-medium text-indigo-700 hover:bg-indigo-100`)),Rl&&r.push(e(Rl,`text-neutral-500 hover:text-indigo-700`))}if(e&&t!==null){let n=Kl(t,e),a=n>=90?`text-red-700`:n>=70?`text-amber-700`:`text-neutral-500`;r.push(z(`span`,`flex-none font-mono ${a}`,i(t).toLowerCase()))}let a=r.flatMap((e,t)=>t===0?[e]:[z(`span`,`text-neutral-300`,`·`),e]);Fl.replaceChildren(...a),Fl.classList.toggle(`hidden`,r.length===0),Fl.classList.toggle(`flex`,r.length>0)}function Yl(e,t){let n=[[`Title`,t.title??`untitled`],[`Directory`,t.cwd],[`Session`,t.id]],r=t.id===Y.currentId();if(r&&(n.push([`Model`,Il?.id??`—`]),n.push([`Reasoning`,Rl??`—`]),n.push([`Context`,Ll?ql(Ll):`—`])),n.push([`Created`,rr(t.createdAt),er(t.createdAt)]),r){let e=zl;n.push(e===null?[`Last reply`,`—`]:[`Last reply`,rr(e),er(e)])}let i=z(`div`,`flex max-w-80 flex-col gap-1.5 px-3 py-2`);for(let[e,t,r]of n){let n=z(`div`,`flex items-center gap-1.5`,z(`span`,`text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),lr(`cursor-pointer text-[10.5px] uppercase tracking-wide text-neutral-400 opacity-0 hover:text-neutral-700 focus:opacity-100 group-hover:opacity-100 pointer-coarse:opacity-100`,()=>t)),a=z(`span`,`break-all font-mono text-[12px] text-neutral-700`,t);r&&a.append(z(`span`,`ml-1.5 font-sans text-[11px] text-neutral-400`,r)),i.append(z(`div`,`group flex flex-col`,n,a))}Hs(e,i)}async function Xl(e,t){try{let[n,r]=await Promise.all([ae(`/api/sessions/${t}/models`,`Could not load models`),ae(`/api/sessions/${t}/thinking`,`Could not read the reasoning level`)]);Hs(e,Qs({models:n,current:t===Y.currentId()?Il:null,thinkingLevel:r.level,thinkingLevels:r.levels,onPick:(e,n)=>{q(),Zl(t,e,n)},onThinkingPick:e=>void $l(t,e)}))}catch(e){H(`error`,`model options failed: ${String(e)}`)}}async function Zl(e,t,n){await Ql(e,t)&&n&&await $l(e,n)}async function Ql(e,t){let n=Il;e===Y.currentId()&&(Il=t,Gl());let r=await m(`/api/sessions/${e}/model`,t);if(!r.ok){let{error:t}=await r.json().catch(()=>({}));return e===Y.currentId()&&(Il=n,Gl()),H(`error`,`model change failed: ${t??r.status}`),!1}let{model:i}=await r.json();return e===Y.currentId()&&i&&(Il=i,Gl()),!0}async function $l(e,t){let n=await m(`/api/sessions/${e}/thinking`,{level:t});if(!n.ok){H(`error`,`reasoning change failed: ${n.status}`);return}let{level:r}=await n.json();e===Y.currentId()&&(Rl=r,Jl())}async function eu(e){let t=await m(`/api/sessions/${e}/compact`,{});t.ok||H(`error`,`compact failed: ${await h(t,`no reason given`)}`)}function tu(e,t){let n=t.id===Y.currentId();Ws(e,[{label:`Session info`,onSelect:()=>Yl(e,t)},{label:`Rename…`,onSelect:()=>{q(),ol(t)}},{label:t.listed?`Done — remove from Projects`:`Pin to Projects`,hint:n?Co(jl):``,onSelect:()=>{q(),sl(t,!t.listed)}},{label:`Model`,hint:n?Il?.id??`…`:``,onSelect:()=>void Xl(e,t.id)},{label:`Compact context`,onSelect:()=>{q(),eu(t.id)}},{label:`New session here`,hint:tr(t.cwd),onSelect:()=>{q(),Y.createSession(t.cwd)}},{label:`Browse files`,hint:n?Co(Ml):``,onSelect:()=>{q(),Y.openFiles(n?void 0:t.cwd)}}])}var nu=`pier.theme`,ru=[`system`,`light`,`dark`],iu=window.matchMedia(`(prefers-color-scheme: dark)`),au={system:`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" class="h-3.5 w-3.5"><circle cx="8" cy="8" r="5.25"/><path d="M8 2.75a5.25 5.25 0 0 0 0 10.5z" fill="currentColor" stroke="none"/></svg>`,light:`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" class="h-3.5 w-3.5"><circle cx="8" cy="8" r="3.1"/><path d="M8 1.5v1.4M8 13.1v1.4M1.5 8h1.4M13.1 8h1.4M3.4 3.4l1 1M11.6 11.6l1 1M12.6 3.4l-1 1M4.4 11.6l-1 1"/></svg>`,dark:`<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round" class="h-3.5 w-3.5"><path d="M13 9.4A5.6 5.6 0 0 1 6.6 3a5.6 5.6 0 1 0 6.4 6.4z"/></svg>`},ou=()=>{let e=null;try{e=localStorage.getItem(nu)}catch{return`system`}return e===`light`||e===`dark`?e:`system`},su=()=>{let e=ou();return e===`system`?iu.matches?`dark`:`light`:e};function cu(){let e=su();document.documentElement.dataset.theme=e,R(`meta[name="theme-color"]`).setAttribute(`content`,e===`dark`?`#1c1c1c`:`#fafafa`),window.dispatchEvent(new Event(`pier:theme`))}function lu(){let e=R(`#theme-toggle`),t=()=>{let t=ou();e.title=`Theme: ${t}${t===`system`?` (${su()})`:``}`,e.innerHTML=au[t],cu()};e.onclick=()=>{let e=ru[(ru.indexOf(ou())+1)%ru.length];try{e===`system`?localStorage.removeItem(nu):localStorage.setItem(nu,e)}catch{}t()},iu.addEventListener(`change`,t),t()}var uu=`https://github.com/timqi/pier`,du=[`text-neutral-400`,`hover:text-neutral-700`],fu=[`rounded-full`,`bg-emerald-50`,`px-1.5`,`text-emerald-700`,`ring-1`,`ring-inset`,`ring-emerald-600/20`,`hover:bg-emerald-100`],pu=18e5,mu=null,hu=R(`#version`);function gu(e){let t=mu?.available===!0&&mu.latest!==null;hu.textContent=`v${e}`,hu.title=t?`Pier ${mu?.latest} is out`:``,hu.classList.remove(...t?du:fu),hu.classList.add(...t?fu:du)}var _u=e=>z(`p`,`px-3 py-1 text-[12px] leading-snug text-neutral-500`,e);function vu(){let e=z(`div`,`flex w-72 flex-col gap-1 py-1`);if(!mu)return e.append(_u(`Checking the registry…`)),e;let{current:t,latest:n,available:r,canApply:i,problem:a}=mu;e.append(z(`p`,`px-3 py-1 text-[12.5px] font-medium text-neutral-700`,r?`Pier ${n} is out`:`Pier ${t}`)),e.append(_u(r?`You are running ${t}.`:n===null?`The registry could not be reached, so this may not be the latest.`:`This is the latest release.`));let o=z(`span`,`px-3 text-[11.5px] text-neutral-400`,``),s=z(`div`,`flex items-center gap-2 px-3 py-1.5`);if(a&&e.append(z(`p`,`mx-3 my-1 rounded-md bg-red-50 px-2 py-1.5 text-[11.5px] leading-snug text-red-700`,a)),r&&i&&!a){let e=fr(`Update now`,!0);e.onclick=()=>{e.disabled=!0,o.className=`px-3 text-[11.5px] text-neutral-400`,o.textContent=`starting the updater…`,(async()=>{let t=await m(`/api/update`,{});if(!t.ok){e.disabled=!1,o.className=`px-3 text-[11.5px] text-red-600`,o.textContent=await h(t,`Could not update`);return}let{draining:n}=await t.json();o.textContent=n?`Waiting for running work to finish — Pier then stops, installs and starts again.`:`Pier is stopping, installing and starting again — this page reconnects on its own.`})()},s.append(e)}let c=z(`a`,`btn text-[12.5px] no-underline`,`Source`);c.href=r?`${uu}/releases`:uu,c.target=`_blank`,c.rel=`noreferrer`,c.title=`Pier is free software (AGPL-3.0)`,s.append(c),e.append(s,o),r&&!i&&!a&&e.append(_u(`No service manager owns this Pier, so it cannot restart itself — update it with: pier update`));let l=Cr(`Update automatically`,i?`Installs a new release once nothing is running — no turn in flight, no task run.`:`Needs the systemd service (pier service install); nothing here can restart Pier.`,mu.autoUpdate,e=>{mu&&(mu.autoUpdate=e),(async()=>{let t=await m(`/api/settings`,{autoUpdate:e},`PUT`);if(t.ok)return;mu&&(mu.autoUpdate=!e);let n=l.querySelector(`input`);n&&(n.checked=!e),o.className=`px-3 text-[11.5px] text-red-600`,o.textContent=await h(t,`Could not save`)})()});if(!i){let e=l.querySelector(`input`);e&&(e.disabled=!0)}return e.append(z(`div`,`mt-1 border-t border-neutral-200 px-3 pb-1 pt-2`,l)),e}async function yu(e){let t=await ie(`/api/update`,`Update check failed`);t.ok&&(mu=t.value,gu(mu.current||e))}function bu(e){gu(e),hu.onclick=e=>{e.preventDefault(),Hs(hu,vu())};let t=()=>void yu(e).catch(()=>{});t(),setInterval(t,pu)}var X,xu=R(`#chat-header`),Su=R(`#chat-title`),Cu=[xu,V,R(`#composer`)],wu=()=>ju===null,Tu,Eu,Du,Ou=new Map,ku=new Map,Au=new Map,ju=null,Mu=0,Nu=[`files`,`terminal`],Pu=new Map,Fu={tasks:`Tasks`,runs:`Runs`,activity:`Activity`,boards:`Boards`,settings:`Settings`,files:`Files`,terminal:`Terminal`},Iu=e=>Tu?.refresh(e),Lu=()=>Eu?.refresh(),Ru=()=>Du?.refresh();function zu(){ju?hc(Fu[ju],!1):hc(Su.textContent??``,X.currentSession()!==void 0)}function Z(e,t,n){if(Nu.includes(e)){let t=$u();t&&(t.kind!==`console`||t.name!==e)&&Pu.set(e,t)}td({kind:`console`,name:e,arg:t,query:n}),mc(),ju=e;for(let e of Cu)e.classList.add(`hidden`);$o();for(let[t,n]of Ou)t!==e&&n.hide();for(let[t,n]of Au)n.classList.toggle(`bg-indigo-50`,t===e);zu(),Bu(e,t,n,++Mu)}async function Bu(e,t,n,r){let i=Ou.get(e);if(!i){let t=ku.get(e);if(!t){let n=R(`#${e}-view`);t=id[e](n).catch(t=>(console.warn(`${e} view failed to load`,t),ar(n,()=>n.replaceChildren(z(`p`,`p-4 text-[13px] text-red-600`,`Could not load ${Fu[e]} — reload the page.`))))),ku.set(e,t)}i=await t,Ou.set(e,i),ku.delete(e)}ju===e&&r===Mu&&i.show(t,n)}var Vu=e=>Z(`tasks`,e),Hu=(e={},t)=>Z(`runs`,t,new URLSearchParams(e).toString()),Uu=e=>Hu({},e),Wu=e=>Z(`files`,e),Gu=e=>Z(`terminal`,e),Ku=(e,t)=>{ju===e?Yu(e):Z(e,t)},qu=e=>Ku(`files`,e),Ju=e=>Ku(`terminal`,e);function Yu(e){let t=X.currentId(),n=Pu.get(e)??(t?{kind:`session`,id:t}:null);Pu.delete(e),n?td(n):(history.replaceState(null,``,`#/`),Xu())}function Xu(){if(ju){ju=null;for(let e of Ou.values())e.hide();for(let e of Au.values())e.classList.remove(`bg-indigo-50`);for(let e of Cu)e.classList.remove(`hidden`);$o(),zu(),X.maybeAckRead()}}var Zu=e=>e.kind===`session`?`#/session/${encodeURIComponent(e.id)}`:`#/${e.name}${e.arg?`/${encodeURIComponent(e.arg)}`:``}${e.query?`?${e.query}`:``}`,Qu={config:`files`,channels:`channels`,providers:`models`};function $u(){let e=location.hash.replace(/^#\/?/,``),t=e.indexOf(`?`),[n=``,r]=(t<0?e:e.slice(0,t)).split(`/`),i=t<0?void 0:e.slice(t+1)||void 0,a;try{a=r?decodeURIComponent(r):void 0}catch{return null}return Qu[n]?{kind:`console`,name:`settings`,arg:Qu[n]}:Object.hasOwn(Fu,n)?{kind:`console`,name:n,arg:a,query:i}:n===`session`&&a?{kind:`session`,id:a}:null}var ed=!1;function td(e,t=!1){if(ed)return;let n=Zu(e);location.hash!==n&&(t?history.replaceState(null,``,n):location.hash=n)}var nd=e=>td({kind:`session`,id:e});function rd(){let e=$u(),t=X.sessions(),n=X.currentId(),r=(e?.kind===`session`?e.id:null)??n??(t.find(e=>e.listed)??t[0])?.id??null;ed=!0;try{r&&r!==n&&X.select(r),e?.kind===`console`?Z(e.name,e.arg,e.query):Xu(),r||Gl()}finally{ed=!1}e?.kind!==`console`&&r&&td({kind:`session`,id:r},!0)}var id={tasks:async e=>Tu=(await di(async()=>{let{createTasksView:e}=await import(`./tasks-CqfrOVIt.js`);return{createTasksView:e}},__vite__mapDeps([0,1]))).createTasksView(e,()=>X.sessions().map(({id:e,cwd:t,title:n})=>({id:e,cwd:t,title:n})),X.loadSessions,X.select,()=>X.currentId(),Hu,Vu),runs:async e=>Eu=(await di(async()=>{let{createRunsView:e}=await import(`./runs-jY40JBP-.js`);return{createRunsView:e}},__vite__mapDeps([2,1]))).createRunsView(e,X.select,()=>X.currentId(),Hu,Vu),activity:async e=>Du=(await di(async()=>{let{createActivityView:e}=await import(`./activity-Cw0LRVNI.js`);return{createActivityView:e}},[])).createActivityView(e,X.select,Uu),boards:async e=>(await di(async()=>{let{createBoardsView:e}=await import(`./boards-DMVbV84c.js`);return{createBoardsView:e}},[])).createBoardsView(e,X.select),files:async e=>(await di(async()=>{let{createExplorerView:e}=await import(`./explorer-DTvsy5Rs.js`);return{createExplorerView:e}},__vite__mapDeps([3,4]))).createExplorerView(e,()=>X.currentSession(),e=>Z(`files`,e),e=>Z(`terminal`,e),()=>Yu(`files`)),terminal:async e=>(await di(async()=>{let{createTerminalView:e}=await import(`./terminal-DL_0yEy7.js`);return{createTerminalView:e}},[])).createTerminalView(e,()=>[...Bc(X.sessions()).keys()],()=>X.currentSession()?.cwd,e=>Z(`terminal`,e),e=>Z(`files`,e),()=>Yu(`terminal`)),settings:async e=>(await di(async()=>{let{createSettingsView:e}=await import(`./settings-Dux7PIKF.js`);return{createSettingsView:e}},__vite__mapDeps([5,4]))).createSettingsView(e,()=>[...Bc(X.sessions()).keys()],e=>Z(`settings`,e))};function ad(e){X=e;let t=R(`#open-terminal`);t.onclick=()=>Ju(),Eo(t,`meta+;`,`Terminal`,()=>Ju());for(let e of[`tasks`,`runs`,`activity`,`boards`,`settings`]){let t=R(`#open-${e}`);Au.set(e,t),t.onclick=()=>Z(e)}let n=R(`#console-section`);n.open=localStorage.getItem(`pier.consoleCollapsed`)!==`1`,n.ontoggle=()=>localStorage.setItem(`pier.consoleCollapsed`,n.open?`0`:`1`),window.onhashchange=rd}var Q=[],od=0,sd=0,cd=!1,$=null,ld=`idle`,ud=null,dd=0,fd=!1,pd=!1;async function md(e){let t=++od;++sd,cd=!1,Xu(),mc(),$=null,ud?.close(),ud=null,ro(),es([]),Bl(),Wl(e),io(!0),pd=!0,Qo();let n=await m(`/api/sessions`,{cwd:e});if(t!==od)return;if(pd=!1,!n.ok){io(!1),Wl(null),Qo(),H(`error`,`session create failed: ${n.status}`);return}let{id:r}=await n.json();if(t!==od)return;let{repo:i,branch:a}=Q.find(t=>t.cwd===e)??{};Q.unshift({id:r,cwd:e,createdAt:Date.now(),state:`idle`,listed:!0,unread:!1,channel:`web`,activeRuns:0,repo:i,branch:a}),await Td(r),$===r&&Jo()}function hd(e,t){let n=e.map(e=>({...e,title:ne(e.title)}));if(t)Q=n;else{let e=new Map(n.map(e=>[e.id,e]));Q=Q.map(t=>e.get(t.id)??(t.listed?{...t,listed:!1}:t));let t=new Set(Q.map(e=>e.id));Q.push(...n.filter(e=>!t.has(e.id)))}Q.sort((e,t)=>t.createdAt-e.createdAt),gl(),vd()}var gd=re(async()=>{hd(await ae(`/api/projects`,`Could not load projects`),!1)}),_d=re(async()=>{hd(await ae(`/api/sessions`,`Could not load sessions`),!0)});function vd(){if(document.hidden||!document.hasFocus()||!wu())return;let e=Q.find(e=>e.id===$);e?.unread&&(e.unread=!1,gl(),fetch(`/api/sessions/${e.id}/read`,{method:`POST`}))}function yd(){return Q.find(e=>e.id===$)}function bd(e,t){let n=Q.find(t=>t.id===e);!n||n.title||!t.trim()||(n.title=t.trim().slice(0,80),gl(),Gl())}function xd(e){ld=e;let t=Q.find(e=>e.id===$);t&&(t.state=e),gl(),Gl(),Qo(),e===`idle`&&gd()}function Sd(e){if(!(e.sessionId!==$||e.seq<=dd))switch(dd=e.seq,e.type){case`turn-start`:fd=!0;break;case`system-input`:eo(),Da(e.text,e.origin);break;case`task-status`:Pi(e.run);break;case`user-message`:{let t=te(e.text).text;if(bd(e.sessionId,t),Yo(t))break;eo(),H(`user`,e.text,!1,e.ts),ya();break}case`text-delta`:$a(e.text);break;case`thinking-delta`:oa(e.ts,e.text);break;case`tool-start`:eo(),ia(e.ts,e.toolCallId,e.toolName,e.args);break;case`tool-end`:aa(e.toolCallId,e.isError,e.output);break;case`turn-end`:fd=!1,to(e.text,e.meta),e.meta&&Hl(e.meta);break;case`queue-state`:ts(e.steering,e.followUp);break;case`queue-recovery`:es(e.batches,e.uncertain);break;case`context-compacted`:eo(),H(`system`,`Context compacted — ${i(e.before)} → ${i(e.after)}`,!1,e.ts),ya();break;case`error`:na(),H(`error`,e.message);break;case`state`:e.state===`idle`&&fd&&(fd=!1,no()),e.state===`idle`&&ts([],[]),xd(e.state)}}function Cd(){let e=new EventSource(`/api/events`);e.onopen=()=>void gd(),e.onerror=()=>vo(e,`Workspace`),e.onmessage=e=>{let t=JSON.parse(e.data);if(t.type===`sessions-changed`){gd();return}if(t.type===`tasks-changed`||t.type===`task-run-changed`||t.type===`task-message-changed`||t.type===`task-group-changed`){Iu(t.type===`task-run-changed`?t.taskId:void 0),Lu(),Ru(),t.type===`task-run-changed`&&gd();return}if(Ru(),t.sessionId===$)return;let n=Q.find(e=>e.id===t.sessionId);n&&(n.state=t.state,gl())}}function wd(e,t,n){ud?.close();let r=new EventSource(`/api/sessions/${e}/events?after=${t}`),i=()=>ud===r&&$===e&&n===sd;r.onmessage=e=>{i()&&Sd(JSON.parse(e.data))},r.addEventListener(`reset`,()=>{i()&&Ed(e)}),r.onerror=()=>{i()&&vo(r,`Session`)},ud=r}async function Td(e){Xu(),mc(),nd(e);let t=Q.some(t=>t.id===e);if(e===$&&t&&(ud||cd))return;let n=++od;if(++sd,pd=!1,cs(),$=e,ld=Q.find(t=>t.id===e)?.state??`idle`,ls(e),gl(),Gl(),vd(),t)return await Ed(e);ud?.close(),ud=null,ro(),io(!0),await _d(),n===od&&$===e&&await Ed(e,!Q.some(t=>t.id===e))}async function Ed(e,t=!1){if($!==e)return;let n=++sd;if(ud?.close(),ud=null,cd=!0,ro(),ts([],[]),es([]),Bl(),fd=!1,Zo(),dd=0,io(!0),t){cd=!1,io(!1),H(`error`,`session not found: ${e}`);return}let r=await ie(`/api/sessions/${e}/history`,`failed to load session`);if($!==e||n!==sd)return;if(cd=!1,!r.ok){io(!1),H(`error`,r.error);return}let i=r.value;ao(i.turns,i.state,i.backgroundRuns),dd=i.lastSeq,fd=i.state===`streaming`,xd(i.state),ts(i.queue.steering,i.queue.followUp),es(i.queueRecovery,i.queueUncertain);let a=i.turns.reduce((e,t)=>t.meta?.completedAt??e,null);Vl(i.model,i.context,i.thinkingLevel,a),wd(e,`${i.epoch}:${i.lastSeq}`,n)}mo(),_o(),lu();var Dd=async e=>{$===e&&await Ed(e)};fa({sessionId:()=>$,sessionState:()=>ld,select:e=>void Td(e),showRun:Uu,send:(e,t)=>void fs(e,t),ownTurn:e=>{Xo(e),xd(`streaming`)},reload:Dd}),hs({sessionId:()=>$,starting:()=>pd,sessionState:()=>ld,chatVisible:wu,setState:xd,reload:Dd}),Oc({sessionMenu:e=>{let t=yd();t&&tu(e,t)},sessionInfo:e=>{let t=yd();t&&Yl(e,t)}}),Ol({sessions:()=>Q,loadSessions:_d,currentId:()=>$,select:e=>void Td(e),sessionMenu:tu,createSession:md,openFiles:Wu,openTerminal:Gu,openConsole:Z,onPinsChanged:Gl}),kl({currentId:()=>$,currentSession:yd,createSession:e=>void md(e),syncBar:zu,openFiles:Wu,toggleFiles:qu}),ad({sessions:()=>Q,loadSessions:_d,currentId:()=>$,currentSession:yd,select:e=>void Td(e),maybeAckRead:vd}),bu(`0.0.21`),As(),document.addEventListener(`visibilitychange`,vd),window.addEventListener(`focus`,vd),Cd(),gd().then(rd);export{er as A,h as B,xr as C,Sr as D,yr as E,ir as F,m as G,ae as H,z as I,ne as K,$n as L,ar as M,lr as N,Cr as O,ur as P,nr as R,hr as S,mr as T,se as U,ie as V,oe as W,gr as _,Hs as a,Or as b,wi as c,di as d,vr as f,fr as g,pr as h,q as i,tr as j,kr as k,_i as l,Er as m,ac as n,Fs as o,wr as p,r as q,$s as r,ko as s,lc as t,vi as u,Dr as v,Tr as w,br as x,_r as y,re as z};
@@ -1 +1 @@
1
- import{C as e,I as t,M as n,V as r,W as i,g as a,z as o}from"./index-WrsNstrb.js";import{c as s,i as c,n as l,o as u,s as d}from"./task-runs-CpgHxFLf.js";function f(f,p,m,h,g){let _=new URLSearchParams,v=[],y=``,b=t(`div`,`min-h-0 flex-1 overflow-auto`),x=t(`div`,``),S={selectedId:null,rawOpen:!1,scrollTop:0,drawn:``},C=(e,t)=>h(Object.fromEntries(e),t),w=e=>{f.querySelector(`[role=alert]`)?.remove();let n=t(`p`,`p-4 text-[13px] text-red-600`,e);n.setAttribute(`role`,`alert`),f.append(n)},T={openSession:p,currentSessionId:m,onError:w,openTask:g,openRun:e=>C(_,e),reload:async()=>{await E()},mutate:async e=>{let t=await i(e,`POST`,`Run update failed`);t?w(t):await E()}},E=o(async()=>{let e=S.selectedId;if(e)return c(b,e,()=>C(_),T,S);let t=_.toString(),n=await r(`/api/task-runs?${t}`,`Could not load runs`);if(t!==_.toString()||S.selectedId)return;if(!n.ok)return w(n.error);f.querySelector(`[role=alert]`)?.remove();let i=JSON.stringify(n.value);y!==t+i&&(y=t+i,A(n.value))});function D(e,t){let n=new URLSearchParams(_);t?n.set(e,t):n.delete(e),n.delete(`cursor`),C(n)}function O(){if(y=``,b=t(`div`,`min-h-0 flex-1 overflow-auto`),S.selectedId){f.replaceChildren(b);return}let e=t(`header`,`flex min-h-10 flex-none flex-wrap items-center gap-2 border-b border-neutral-200 px-4 py-2`,t(`span`,`font-medium max-md:hidden`,`Runs`)),n=a(`Reset filters`);n.onclick=()=>h({}),e.append(n),x=k(),f.replaceChildren(e,x,b)}function k(){let n=t(`div`,`flex flex-none flex-wrap items-center gap-3 border-b border-neutral-200 px-4 py-2 text-[12px]`),r=(r,i,a)=>{let o=e(a,_.get(i)??``);o.classList.add(`!w-auto`,`max-w-full`,`pr-8`),o.setAttribute(`aria-label`,r),o.onchange=()=>D(i,o.value),n.append(t(`label`,`flex max-w-full items-center gap-2`,r,o))};r(`State`,`state`,[[`All states`,``],...[`queued`,`running`,`succeeded`,`failed`,`cancelled`,`interrupted`,`skipped`].map(e=>[e,e])]),r(`Source`,`source`,[[`All sources`,``],...[`manual`,`agent`,`cron`,`watch`,`task`].map(e=>[e,e])]);let i=v.map(e=>[e.name+(e.archived?` (archived)`:``),e.id]),a=_.get(`taskId`);a&&!v.some(e=>e.id===a)&&i.push([a,a]),r(`Task`,`taskId`,[[`All tasks`,``],...i]);for(let[e,r]of[[`From`,`since`],[`Through`,`until`]]){let i=t(`input`,`min-w-0 rounded border border-neutral-200 px-2 py-1`);i.type=`datetime-local`,i.setAttribute(`aria-label`,e);let a=_.get(r);if(a){let e=new Date(Number(a));Number.isFinite(e.getTime())&&(i.value=new Date(e.getTime()-e.getTimezoneOffset()*6e4).toISOString().slice(0,16))}i.onchange=()=>D(r,i.value?String(new Date(i.value).getTime()):``),n.append(t(`label`,`flex min-w-0 items-center gap-2`,e,i))}return n}function A(e){let n=t(`input`,``);n.type=`checkbox`,n.checked=_.get(`showUnmatched`)===`true`,n.onchange=()=>D(`showUnmatched`,n.checked?`true`:``);let r=t(`label`,`flex items-center gap-2 border-b border-neutral-100 px-4 py-2 text-[12px] text-neutral-500`,n,`Show unmatched probes`),i=t(`div`,`divide-y divide-neutral-100`);for(let n of e.runs){let e=t(`div`,`px-4 py-3 text-[12px]`),r=t(`button`,`grid w-full cursor-pointer grid-cols-[minmax(0,1fr)_auto] gap-x-4 gap-y-1 text-left hover:bg-neutral-50 md:grid-cols-[minmax(0,1fr)_8rem_12rem_5rem]`);r.setAttribute(`type`,`button`),r.onclick=()=>C(_,n.id),r.append(t(`span`,`min-w-0 truncate font-medium`,n.context.definition.name),t(`span`,`font-medium`,s(n)),t(`span`,`text-neutral-500`,l(n.queuedAt)),t(`span`,`text-neutral-500`,d(n)),t(`span`,`col-span-2 break-all font-mono text-[11px] text-neutral-400 md:col-span-4`,`${n.id} · ${n.triggerSource}`)),e.append(r);let a=u(n);a&&e.append(t(`p`,`mt-1 break-words text-amber-700`,a));let o=t(`div`,`mt-1 flex flex-wrap gap-x-4 gap-y-1 text-neutral-500`),c=(e,n)=>{let r=t(`button`,`max-w-full cursor-pointer break-all text-left hover:underline`,e);r.setAttribute(`type`,`button`),r.onclick=n,o.append(r)};if(n.parentRunId&&c(`Parent ${n.parentRunId}`,()=>C(_,n.parentRunId)),n.resumedFromRunId&&c(`Resumed from ${n.resumedFromRunId}`,()=>C(_,n.resumedFromRunId)),n.result?.type===`task`){let e=n.result.runId;c(`Child result ${e}`,()=>C(_,e))}n.groupId&&o.append(t(`span`,`break-all`,`Group ${n.groupId}`)),e.append(o),i.append(e)}e.runs.length||i.append(t(`p`,`p-4 text-[13px] text-neutral-500`,`No matching runs.`));let o=t(`div`,`flex items-center gap-3 border-t border-neutral-200 p-4`);if(_.has(`cursor`)){let e=a(`Newest`);e.onclick=()=>D(`cursor`,``),o.append(e)}if(e.nextCursor){let t=a(`Older runs`);t.onclick=()=>{let t=new URLSearchParams(_);t.set(`cursor`,JSON.stringify(e.nextCursor)),C(t)},o.append(t)}let c=b.scrollTop;b.replaceChildren(r,i,o),b.scrollTop=c}async function j(){let e=await r(`/api/tasks?kind=task`,`Could not load task filters`);if(!e.ok)return w(e.error);if(JSON.stringify(v)!==JSON.stringify(e.value)&&(v=e.value,!S.selectedId&&x.isConnected)){let e=k();x.replaceWith(e),x=e}}let M=n(f,(e,t)=>{_=new URLSearchParams(t),S.selectedId!==(e||null)&&(S.rawOpen=!1,S.scrollTop=0),S.selectedId=e||null,O(),E(),e||j()});return Object.assign(M,{refresh(){M.visible&&E()}})}export{f as createRunsView};
1
+ import{C as e,I as t,M as n,V as r,W as i,g as a,z as o}from"./index-DHxoYoeq.js";import{c as s,i as c,n as l,o as u,s as d}from"./task-runs-DKvtBVxS.js";function f(f,p,m,h,g){let _=new URLSearchParams,v=[],y=``,b=t(`div`,`min-h-0 flex-1 overflow-auto`),x=t(`div`,``),S={selectedId:null,rawOpen:!1,scrollTop:0,drawn:``},C=(e,t)=>h(Object.fromEntries(e),t),w=e=>{f.querySelector(`[role=alert]`)?.remove();let n=t(`p`,`p-4 text-[13px] text-red-600`,e);n.setAttribute(`role`,`alert`),f.append(n)},T={openSession:p,currentSessionId:m,onError:w,openTask:g,openRun:e=>C(_,e),reload:async()=>{await E()},mutate:async e=>{let t=await i(e,`POST`,`Run update failed`);t?w(t):await E()}},E=o(async()=>{let e=S.selectedId;if(e)return c(b,e,()=>C(_),T,S);let t=_.toString(),n=await r(`/api/task-runs?${t}`,`Could not load runs`);if(t!==_.toString()||S.selectedId)return;if(!n.ok)return w(n.error);f.querySelector(`[role=alert]`)?.remove();let i=JSON.stringify(n.value);y!==t+i&&(y=t+i,A(n.value))});function D(e,t){let n=new URLSearchParams(_);t?n.set(e,t):n.delete(e),n.delete(`cursor`),C(n)}function O(){if(y=``,b=t(`div`,`min-h-0 flex-1 overflow-auto`),S.selectedId){f.replaceChildren(b);return}let e=t(`header`,`flex min-h-10 flex-none flex-wrap items-center gap-2 border-b border-neutral-200 px-4 py-2`,t(`span`,`font-medium max-md:hidden`,`Runs`)),n=a(`Reset filters`);n.onclick=()=>h({}),e.append(n),x=k(),f.replaceChildren(e,x,b)}function k(){let n=t(`div`,`flex flex-none flex-wrap items-center gap-3 border-b border-neutral-200 px-4 py-2 text-[12px]`),r=(r,i,a)=>{let o=e(a,_.get(i)??``);o.classList.add(`!w-auto`,`max-w-full`,`pr-8`),o.setAttribute(`aria-label`,r),o.onchange=()=>D(i,o.value),n.append(t(`label`,`flex max-w-full items-center gap-2`,r,o))};r(`State`,`state`,[[`All states`,``],...[`queued`,`running`,`succeeded`,`failed`,`cancelled`,`interrupted`,`skipped`].map(e=>[e,e])]),r(`Source`,`source`,[[`All sources`,``],...[`manual`,`agent`,`cron`,`watch`,`task`].map(e=>[e,e])]);let i=v.map(e=>[e.name+(e.archived?` (archived)`:``),e.id]),a=_.get(`taskId`);a&&!v.some(e=>e.id===a)&&i.push([a,a]),r(`Task`,`taskId`,[[`All tasks`,``],...i]);for(let[e,r]of[[`From`,`since`],[`Through`,`until`]]){let i=t(`input`,`min-w-0 rounded border border-neutral-200 px-2 py-1`);i.type=`datetime-local`,i.setAttribute(`aria-label`,e);let a=_.get(r);if(a){let e=new Date(Number(a));Number.isFinite(e.getTime())&&(i.value=new Date(e.getTime()-e.getTimezoneOffset()*6e4).toISOString().slice(0,16))}i.onchange=()=>D(r,i.value?String(new Date(i.value).getTime()):``),n.append(t(`label`,`flex min-w-0 items-center gap-2`,e,i))}return n}function A(e){let n=t(`input`,``);n.type=`checkbox`,n.checked=_.get(`showUnmatched`)===`true`,n.onchange=()=>D(`showUnmatched`,n.checked?`true`:``);let r=t(`label`,`flex items-center gap-2 border-b border-neutral-100 px-4 py-2 text-[12px] text-neutral-500`,n,`Show unmatched probes`),i=t(`div`,`divide-y divide-neutral-100`);for(let n of e.runs){let e=t(`div`,`px-4 py-3 text-[12px]`),r=t(`button`,`grid w-full cursor-pointer grid-cols-[minmax(0,1fr)_auto] gap-x-4 gap-y-1 text-left hover:bg-neutral-50 md:grid-cols-[minmax(0,1fr)_8rem_12rem_5rem]`);r.setAttribute(`type`,`button`),r.onclick=()=>C(_,n.id),r.append(t(`span`,`min-w-0 truncate font-medium`,n.context.definition.name),t(`span`,`font-medium`,s(n)),t(`span`,`text-neutral-500`,l(n.queuedAt)),t(`span`,`text-neutral-500`,d(n)),t(`span`,`col-span-2 break-all font-mono text-[11px] text-neutral-400 md:col-span-4`,`${n.id} · ${n.triggerSource}`)),e.append(r);let a=u(n);a&&e.append(t(`p`,`mt-1 break-words text-amber-700`,a));let o=t(`div`,`mt-1 flex flex-wrap gap-x-4 gap-y-1 text-neutral-500`),c=(e,n)=>{let r=t(`button`,`max-w-full cursor-pointer break-all text-left hover:underline`,e);r.setAttribute(`type`,`button`),r.onclick=n,o.append(r)};if(n.parentRunId&&c(`Parent ${n.parentRunId}`,()=>C(_,n.parentRunId)),n.resumedFromRunId&&c(`Resumed from ${n.resumedFromRunId}`,()=>C(_,n.resumedFromRunId)),n.result?.type===`task`){let e=n.result.runId;c(`Child result ${e}`,()=>C(_,e))}n.groupId&&o.append(t(`span`,`break-all`,`Group ${n.groupId}`)),e.append(o),i.append(e)}e.runs.length||i.append(t(`p`,`p-4 text-[13px] text-neutral-500`,`No matching runs.`));let o=t(`div`,`flex items-center gap-3 border-t border-neutral-200 p-4`);if(_.has(`cursor`)){let e=a(`Newest`);e.onclick=()=>D(`cursor`,``),o.append(e)}if(e.nextCursor){let t=a(`Older runs`);t.onclick=()=>{let t=new URLSearchParams(_);t.set(`cursor`,JSON.stringify(e.nextCursor)),C(t)},o.append(t)}let c=b.scrollTop;b.replaceChildren(r,i,o),b.scrollTop=c}async function j(){let e=await r(`/api/tasks?kind=task`,`Could not load task filters`);if(!e.ok)return w(e.error);if(JSON.stringify(v)!==JSON.stringify(e.value)&&(v=e.value,!S.selectedId&&x.isConnected)){let e=k();x.replaceWith(e),x=e}}let M=n(f,(e,t)=>{_=new URLSearchParams(t),S.selectedId!==(e||null)&&(S.rawOpen=!1,S.scrollTop=0),S.selectedId=e||null,O(),E(),e||j()});return Object.assign(M,{refresh(){M.visible&&E()}})}export{f as createRunsView};
@@ -1,4 +1,4 @@
1
- import{A as e,B as t,C as n,D as r,E as i,G as a,I as o,M as s,N as c,O as l,S as u,V as d,_ as f,b as p,c as m,f as h,g,h as _,j as v,k as y,l as b,m as x,o as S,p as C,q as w,r as T,t as E,v as D,w as O,x as k,y as A}from"./index-WrsNstrb.js";import{n as j,t as M}from"./code-p-Tq1bMK.js";var N={display_information:{name:`Pier`,description:`Coding agent sessions in Slack threads`,background_color:`#262626`},features:{bot_user:{display_name:`Pier`,always_online:!1},app_home:{messages_tab_enabled:!0,messages_tab_read_only_enabled:!1}},oauth_config:{scopes:{bot:[`chat:write`,`reactions:write`,`channels:history`,`channels:read`,`groups:history`,`groups:read`,`im:history`,`im:write`,`mpim:history`,`mpim:read`,`mpim:write`,`users:read`,`files:read`,`files:write`]}},settings:{event_subscriptions:{bot_events:[`message.channels`,`message.groups`,`message.im`,`message.mpim`]},interactivity:{is_enabled:!0},socket_mode_enabled:!0,token_rotation_enabled:!1}},P=()=>`https://api.slack.com/apps?new_app=1&manifest_json=${encodeURIComponent(JSON.stringify(N))}`,F=()=>p(`Getting a bot token`,[`Open [@BotFather](https://t.me/BotFather) in Telegram.`,"Send `/newbot`, pick a display name, then a username ending in `bot`.","Copy the token it prints (`123456789:AA…`) and paste it here.","Send `/setprivacy` → `Disable` if the bot should see plain group messages. Left enabled it only ever receives mentions, replies and commands — the usual reason a bot looks dead in a group.","Send `/setjoingroups` → `Enable`, then add the bot to your group or forum."]),I=(e=`left`)=>p(`Enabling topics on a group`,["In Telegram open the group → `Edit` → turn on `Topics`. Owner only; group size no longer matters.","The group becomes a forum supergroup and the existing chat becomes its `General` topic.","Make the bot an admin with `Manage Topics`. That is the one right topic creation needs — without it Pier logs the failure and answers in General instead.","Send one message in the group so Pier discovers it, then enable it under `Chats` below.","After that, a message in General opens its own topic with its own session. A reply, or anything starting with `/`, stays where it was sent."],e);function L(){let e=g(`Create Slack app ↗`,!0);e.classList.add(`mt-1`,`w-fit`),e.onclick=()=>window.open(P(),`_blank`,`noreferrer`);let t=c(`btn w-fit text-[12.5px]`,()=>JSON.stringify(N,null,2));return p(`Creating a Slack app`,[y(`Opens Slack with every scope, event and Socket Mode already filled in. Pick your workspace → Create.`,e),"`Install to Workspace` → allow. Then `OAuth & Permissions` → copy the bot token (`xoxb-…`) into the field above.","`Basic Information` → `App-Level Tokens` → `Generate` with scope `connections:write`. Paste that `xapp-…` token below. The manifest cannot mint this one for you.","In Slack, invite the bot where you want it: `/invite @Pier`. It answers in threads only, so it never adds noise to the channel.",y(`Prefer to paste it yourself? Create the app from a manifest and use this:`,t)])}var R=()=>p(`What agent access allows`,["Gives agent sessions a `slack` tool: read a channel's history for a time range, read one thread, and post, edit or delete a message.",`Editing and deleting reach only what Pier's own bot posted — Slack refuses either on anyone else's message.`,`Pier performs every call itself — the bot token is never given to the agent, and Slack's own membership rules still apply, so the bot reaches only channels it was invited to.`,`Every read fetches live from Slack — Pier keeps no message archive.`,`This includes sessions started by tasks and subagents. Switch it off if an agent should never post to your workspace on its own.`,`The tool is only given to sessions opened while Slack is connected and this is on, so an unused tool costs no context. A session opened earlier keeps it, and a call made after you switch it off is refused with the reason.`]),z=(e=`left`)=>p(`How Slack threads work here`,[`Pier never posts in a channel's main flow. A message in the channel is answered in *its own thread*; a message in a thread is answered in that thread.`,`Each thread is its own Pi session, so one channel hosts many parallel sessions.`,`The same applies in a DM: every new message you send there starts its own thread and its own session. Reply *inside* a thread to continue that conversation.`,"Inside a thread Pier already owns, no `@mention` is needed — continuing that thread is addressing it.","Commands are bare words after a mention: `@bot settings`, `@bot stop`, `@bot bind <code>`. Slack's client swallows an unregistered `/command` before it ever reaches an app."],e),ee=()=>p(`Creating a Feishu app`,["On [open.feishu.cn](https://open.feishu.cn/app) create a 企业自建应用 (custom app). `Credentials & Basic Info` shows the App ID (`cli_…`) and App Secret — paste both here.","`Add Features` → enable **Bot** (机器人).","`Permissions` (权限管理), add: `im:message` (read messages), `im:message:send_as_bot` (send), `im:resource` (attachments, both directions), `im:message.reactions:create` + `:read` + `:delete` (the 👀 receipt), `im:chat:readonly` (chat names for this page), `contact:user.base:readonly` (speaker names).","`Events & Callbacks` → set the mode to **长连接 (long connection)** — no public URL needed. Under Events subscribe `im.message.receive_v1` (接收消息); Callbacks gain `card.action.trigger` automatically once cards are sent, add it if listed.",`**Publish a version** (版本管理与发布 → 创建版本 → 申请发布). Nothing above takes effect until this is approved — the usual reason a configured bot stays silent.`,`Add the bot to a group (群设置 → 群机器人), or DM it directly.`]),B=(e=`left`)=>p(`How Lark topics work here`,[`Pier never posts in a chat's main flow. A message in the chat is answered in *its own topic* (话题); a message inside a topic is answered there.`,`Each topic is its own Pi session, so one group hosts many parallel sessions.`,`The same applies in a DM: every new message starts its own topic and its own session. Reply *inside* a topic to continue that conversation.`,`Inside a topic Pier already owns, no @mention is needed — continuing that topic is addressing it.`,"Commands are slash words: `/stop`, `/settings`, `/bind <code>`. A bare @mention with nothing else also opens the settings panel."],e),V=[[`telegram`,`Telegram`],[`slack`,`Slack`],[`lark`,`Lark`]],H=(e,t)=>o(`span`,`flex items-center gap-1.5 text-[13px] text-neutral-400`,o(`span`,``,e),t),te={dm:`bg-sky-50 text-sky-700 ring-sky-200`,group:`bg-neutral-100 text-neutral-600 ring-neutral-200`,forum:`bg-violet-50 text-violet-700 ring-violet-200`},U=`pier.channelsPlatform`;function ne(e){let t=localStorage.getItem(U),n=V.some(([e])=>e===t)?t:`telegram`,r=null,c=[],p=o(`div`,`ml-auto flex items-center gap-1.5 text-[11.5px]`),m=o(`div`,`sticky top-0 z-30 flex items-center gap-1 border-b border-neutral-200 bg-white px-4 py-2`,p),h=o(`div`,`px-4 py-5`);e.append(o(`div`,`min-h-0 flex-1 overflow-y-auto bg-neutral-50/60`,m,h));function v(){m.replaceChildren(...V.map(([e,t])=>u(t,e===n,()=>{y&&M(),n=e,localStorage.setItem(U,e),N()})),p)}let y,b=!1,S=null;function w(e){if(p.replaceChildren(),e!==`clean`){if(p.className=`ml-auto flex items-center gap-1.5 text-[11.5px] ${C[e]}`,e===`saving`)p.append(o(`span`,`spinner`),o(`span`,``,`Saving…`));else if(e===`saved`)p.append(o(`span`,``,`✓`),o(`span`,``,`Saved`)),setTimeout(()=>{p.textContent?.includes(`Saved`)&&w(`clean`)},2e3);else{let e=_(`Retry`,`cursor-pointer underline`);e.onclick=M,p.append(o(`span`,``,`⚠`),o(`span`,``,`Save failed`),e)}}}function O(){w(`saving`),clearTimeout(y),y=setTimeout(M,500)}let k=e=>t=>{e(t),O()};async function j(e){b=!0,w(`saving`);try{w((await a(`/api/channels/${e.platform}`,e.config,`PUT`)).ok?`saved`:`failed`)}catch{w(`failed`)}finally{b=!1;let e=S;S=null,e&&j(e)}}function M(){if(clearTimeout(y),y=void 0,!r)return;let e={platform:n,config:r};b?S=e:j(e)}async function N(){if(!c.length){let e=await d(`/api/models`,`Could not load the model catalog`);e.ok&&(c=e.value)}let e=await d(`/api/channels/${n}`,`Failed to load`);if(!e.ok){r=null,v(),h.replaceChildren(D(e.error));return}r=e.value,w(`clean`),W()}function P(e){let t=n===`slack`,r=n===`lark`,a=i(e.token,t?`xoxb-…`:r?`cli_…`:`123456789:AA…`,k(t=>e.token=t),!0),o=i(e.appToken,r?``:`xapp-…`,k(t=>e.appToken=t),!0),s=E(e.cwd,`(pier process cwd)`,k(t=>e.cwd=t));return f(`Connection`,t?`Pier connects over Socket Mode; no public URL or webhook needed.`:r?`Pier connects over Feishu's WebSocket long connection; no public URL or webhook needed.`:`Pier polls Telegram for updates; no public URL or webhook needed.`,l(`Enabled`,`Start the adapter when Pier boots.`,e.enabled,k(t=>{e.enabled=t,v()})),A(r?`App ID`:`Bot token`,a,{hint:`Stored locally, shown masked once saved.`,help:n===`telegram`?F():t?L():ee()}),...t?[A(`App-level token`,o,{hint:`Opens the Socket Mode connection. Needs connections:write.`}),l(`Agent access`,`Let agent sessions read channel history and post through the slack tool. Off makes the tool refuse; inbound messages are unaffected.`,e.agentTool,k(t=>e.agentTool=t),R())]:[],...r?[A(`App Secret`,o,{hint:`From Credentials & Basic Info, beside the App ID.`})]:[],A(`Default working directory`,s.el,{hint:`Where sessions this channel opens start.`}))}function ne(e){return f(`Defaults for new chats`,`Copied into a group the first time the bot sees it; changing them here never touches a group that already exists. DMs are always bound-users-only.`,l(`Require mention in groups`,`Ignore group messages that do not @mention or reply to the bot.`,e.requireMention,k(t=>e.requireMention=t)),l(`Require bound user`,`Only users bound with a code below can drive the agent.`,e.requireBind,k(t=>e.requireBind=t)),...n===`slack`?[H(`Thread mode: always on`,z())]:n===`lark`?[H(`Thread mode: always on`,B())]:[l(`Topic mode`,`In a forum group, each new request opens its own topic and its own session.`,e.topicMode,k(t=>e.topicMode=t),I())],T(`Model & reasoning`,e,c,k(t=>{e.model=t.model,e.thinking=t.thinking,W()})))}function re(e){let t=o(`span`,`font-mono text-[15px] font-semibold tracking-widest`),r=o(`div`,`hidden items-center gap-2 rounded-lg bg-indigo-50 px-3 py-2 text-[12.5px] text-indigo-800`,t,o(`span`,`text-[11.5px] text-indigo-500`,`DM the bot /bind <code> · expires in 10 min`)),i=g(`Generate bind code`);i.onclick=async()=>{let e=await fetch(`/api/channels/${n}/bind-code`,{method:`POST`});if(!e.ok)return;let{code:i}=await e.json();t.textContent=i,r.classList.replace(`hidden`,`flex`)};let a=o(`div`,`flex flex-col`);e.users.length||a.append(D(`No bound users yet.`));for(let t of e.users){let e=_(`Remove`,`cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-red-600 group-hover:opacity-100`);e.onclick=async()=>{await fetch(`/api/channels/${n}/users/${encodeURIComponent(t.id)}`,{method:`DELETE`}),await N()},a.append(o(`div`,`group flex items-center gap-2.5 border-b border-neutral-100 py-2 last:border-0`,o(`span`,`flex h-6 w-6 flex-none items-center justify-center rounded-full bg-neutral-100 text-[11px] font-semibold text-neutral-500`,(t.name[0]??`?`).toUpperCase()),o(`span`,`min-w-0 flex-1 truncate text-[13px] text-neutral-700`,t.name),o(`span`,`flex-none font-mono text-[11.5px] text-neutral-400`,t.id),e))}return f(`Bound users`,`A code is single-use and expires; redeeming it in a DM binds that account.`,a,o(`div`,`flex flex-col gap-2`,i,r))}function ie(e,t){let r=o(`div`,`rounded-xl border px-3.5 py-3 transition-colors ${t.enabled?`border-neutral-200 bg-white`:`border-neutral-200 bg-neutral-50/60`}`),i=o(`div`,`flex items-center gap-2`,o(`span`,`min-w-0 flex-1 truncate text-[13px] font-medium ${t.enabled?`text-neutral-800`:`text-neutral-400`}`,t.name||t.id),x(t.kind,te[t.kind]),o(`span`,`flex-none font-mono text-[11px] text-neutral-400`,t.id)),a=l(``,``,t.enabled,k(e=>{t.enabled=e,W()}));a.classList.add(`flex-none`,`items-center`),i.append(a);let s=o(`div`,`mt-3 flex flex-wrap items-center gap-x-6 gap-y-2`);t.kind===`dm`?s.append(o(`span`,`text-[13px] text-neutral-400`,n===`telegram`?`Direct message · bound users only, mention and topics not applicable`:`Direct message · bound users only, mention not applicable`)):s.append(l(`Require mention`,``,t.requireMention,k(e=>t.requireMention=e)),l(`Require bind`,``,t.requireBind,k(e=>t.requireBind=e)),n===`slack`?H(`Thread mode: always on`,z(`right`)):n===`lark`?H(`Thread mode: always on`,B(`right`)):t.kind===`forum`?l(`Topic mode`,``,t.topicMode,k(e=>t.topicMode=e),I(`right`)):H(`Topic mode: forum groups only`,I(`right`)));let u=E(t.cwd,``,k(e=>t.cwd=e)),d=o(`div`,`mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2`,A(`Working directory`,u.el),T(`Model & reasoning`,t,c,k(e=>{t.model=e.model,t.thinking=e.thinking,W()})));return r.append(i,s,d),r}function ae(e){let t=o(`div`,`flex flex-col gap-2.5`);return e.chats.length?t.append(...e.chats.map(t=>ie(e,t))):t.append(D(`None yet. Chats appear here after the bot sees a message in them.`)),f(n===`slack`?`Channels`:`Chats`,`Discovered from inbound traffic — no platform reliably lists every chat a bot is in.`,t)}function W(){if(!r)return;v();let e=o(`div`,`mx-auto flex max-w-3xl flex-col gap-4`);e.append(P(r),ne(r),re(r),ae(r)),h.replaceChildren(e)}return s(e,()=>void N(),()=>{y&&M()})}function re(){let e=o(`div`,`min-h-0 min-w-0 flex-1 overflow-y-auto p-4`),n=o(`div`,`mx-auto flex max-w-3xl min-w-0 flex-col gap-4`),r=o(`p`,`text-[12px] break-words`),s=o(`section`,`flex min-w-0 flex-col gap-3 border-b border-neutral-200 pb-4`),u=o(`section`,`flex min-w-0 flex-col gap-3`);n.append(o(`h2`,`text-[14px] font-semibold text-neutral-700`,`Configuration sync`),r,s,u),e.append(n);let f=null,p=!1,m=!1,h=0,_=``,v=!1,y=e=>e?new Date(e).toLocaleString():`Never`;async function b(){let e=h,t=await d(`/api/config-sync`,`Could not load configuration sync`,{cache:`no-store`});if(!(m||e!==h)){if(!t.ok){O(r,`failed`,t.error);return}f=t.value,v||(_=f.sourceUrl),C()}}async function x(e){if(!p){++h,p=!0,C(),O(r,`saving`,`Working...`);try{let n=await a(`/api/config-sync`,{action:e,...e===`subscribe`?{url:_}:{}});if(!n.ok)throw Error(await t(n,`Configuration sync failed`));let i=await n.json();f=i,v=!1,_=i.sourceUrl,O(r,`saved`,i.result??`Saved`)}catch(e){O(r,`failed`,e instanceof Error?e.message:`Configuration sync failed`),await b()}finally{p=!1,m||C()}}}function S(e,t){let n=g(e);return n.disabled=p,n.onclick=()=>{x(t)},n}function C(){if(!f||m)return;if(s.replaceChildren(o(`h3`,`text-[13px] font-medium text-neutral-700`,`Publish`)),f.publishedPath){let e=`${f.publicUrl||window.location.origin}${f.publishedPath}`,t=i(e,``,()=>{},!0);t.readOnly=!0,t.setAttribute(`aria-label`,`Sharing URL`),s.append(t,o(`div`,`flex flex-wrap items-center gap-2`,c(`btn text-[12px]`,()=>e),S(`Revoke link`,`revoke`)))}else s.append(o(`div`,``,S(`Generate link`,`publish`)));s.append(o(`p`,`text-[12px] text-neutral-500`,`Anyone with the link can read shared prompts. Provider connections and credentials stay private.`));let e=i(_,`https://example.com/config-sync/...`,e=>{_=e,v=!0},!0);e.type=`url`,e.setAttribute(`aria-label`,`Configuration source URL`),e.disabled=p||f.enabled;let t=l(`Automatic sync`,``,f.enabled,e=>{x(e?`subscribe`:`pause`)});t.querySelector(`input`).disabled=p;let n=o(`div`,`flex flex-wrap items-center gap-3`,t);f.enabled&&n.append(S(`Sync now`,`sync`)),u.replaceChildren(o(`h3`,`text-[13px] font-medium text-neutral-700`,`Source`),A(`Source URL`,e),n);let r=o(`dl`,`grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1 text-[12px]`);for(let[e,t]of[[`Last checked`,y(f.lastChecked)],[`Last applied`,y(f.lastApplied)],[`Next check`,f.enabled?y(f.nextRunAt):`Paused`]])r.append(o(`dt`,`text-neutral-500`,e),o(`dd`,`min-w-0 break-words text-neutral-700`,t));if(u.append(r),f.error&&u.append(o(`p`,`text-[12px] break-words text-red-600`,f.error)),f.needsReload&&u.append(o(`p`,`text-[12px] text-amber-700`,`Reload pending; retry synchronization.`)),f.taskId){let e=o(`a`,`text-[12px] text-indigo-600 hover:underline`,`Sync task history`);e.href=`#/tasks/${encodeURIComponent(f.taskId)}`,u.append(e)}}b();let w=setInterval(()=>{!p&&!v&&b()},15e3);return{el:e,dispose:()=>{m=!0,clearInterval(w)}}}async function ie(e,n){let r;try{r=await a(`/api/settings`,e,`PUT`)}catch(e){return{outcome:{state:`failed`,text:`Could not save: ${String(e)}`}}}if(!r.ok)return{outcome:{state:`failed`,text:await t(r,`could not save`)}};let i;try{i=await r.json()}catch(e){return{outcome:{state:`failed`,text:`Saved, but the answer could not be read: ${String(e)}`}}}return i.toolsSync?.state===`refused`?{outcome:{state:`failed`,text:`Saved, but nothing will install it: ${i.toolsSync.reason}`},answer:i}:i.toolsSync?.state===`waiting`?{outcome:{state:`saved`,text:`Saved — a sync is already running; this change goes in the run right after it.`},answer:i}:{outcome:{state:`saved`,text:n},answer:i}}function ae(e,t){return e.enabled?{body:{tool:{name:e.name,on:!1}},saved:`Switched ${e.name} off — the next run uninstalls it. Remove it again once its binary is gone.`}:{body:{customTools:t.filter(t=>t.name!==e.name)},saved:`Removed ${e.name}.`}}function W(e,n){let r=`global`,c=null,u=0,f=0,p=``,m=null,g=[],_=``,y=null,S=null,C=()=>{S?.dispose(),S=null},w=()=>{C(),++f,S=re(),L.replaceChildren(S.el)},T=[],E=()=>g.filter(e=>e.kind===`extension`),D=e=>e.source===`binary`&&e.custom===!0,k=()=>g.filter(e=>e.kind===`tool`),N=document.createElement(`select`);N.className=`select w-full rounded-md border border-neutral-300 px-2 py-1 text-[12.5px] focus:border-indigo-400 focus:outline-none`,N.onchange=()=>{C(),r=N.value,c=null,K.clear(),te()};let P=o(`div`,`flex flex-none flex-col gap-1 border-b border-neutral-200 px-3 pb-2.5 pt-2`);P.append(o(`span`,`text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,`Scope`),N);let F=o(`div`,`min-h-0 flex-1 overflow-y-auto py-1`),I=o(`nav`,`flex w-64 flex-none flex-col border-r border-neutral-200 text-[13px] max-md:max-h-48 max-md:w-full max-md:border-r-0 max-md:border-b`);I.append(P,F);let L=o(`div`,`flex min-w-0 flex-1 flex-col`),R=o(`div`,`flex min-h-0 flex-1 max-md:flex-col`);R.append(I,L),e.append(R);let z=(e=``)=>`?scope=${encodeURIComponent(r)}${e}`;async function ee(){if(r!==`global`){g=[],_=``;return}let e=await d(`/api/settings`,`could not be loaded`,{cache:`no-store`});if(!e.ok){g=[],_=e.error;return}B(e.value),_=``}function B(e){g=e.catalog,T=e.customTools,y=e.toolsTaskId}async function V(e,t){let{outcome:n,answer:r}=await ie(e,t);return r&&(B(r),J(m)),n}function H(e,t){let n={name:e,on:t};return g.find(t=>t.name===e)?.source===`binary`?{tool:n}:{extension:n}}async function te(){let e=++u;f++;let[t]=await Promise.all([d(`/api/config${z()}`,`failed to load config`,{cache:`no-store`}),ee()]);if(e!==u)return;if(!t.ok){J(null),Y(t.error);return}let n=t.value;r===`global`&&n.dir&&(p=n.dir,pe()),m=n,J(n),c?c.type===`sync`&&w():se()}function U(e){return o(`div`,`px-3 pb-0.5 pt-2.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e)}let ne=()=>{let e=o(`span`,`flex-none rounded bg-neutral-100 px-1 text-[10px] font-semibold uppercase tracking-wide text-neutral-500`,`link`);return e.title=`Reached through a symlink`,e},W=()=>o(`span`,`flex-none rounded bg-emerald-50 px-1 text-[10px] font-semibold uppercase tracking-wide text-emerald-700`,`on`);function G(e,t,n,r,i=0,a){let s=o(`button`,`flex w-full cursor-pointer items-center gap-1.5 py-1 pr-3 text-left hover:bg-neutral-100 ${t?`bg-indigo-50 hover:bg-indigo-50`:``} ${n?`text-neutral-400`:``}`);return s.append(o(`span`,`truncate`,e)),a&&s.append(a),s.style.paddingLeft=`${20+i*14}px`,s.title=e,s.onclick=r,s}function oe(e){let t={files:[],dirs:new Map,link:!0};for(let n of e){let e=n.name.split(`/`),r=t;for(let t of e.slice(0,-1)){let e=r.dirs.get(t);e||r.dirs.set(t,e={files:[],dirs:new Map,link:!0}),e.link&&=n.link,r=e}r.files.push({name:e[e.length-1],link:n.link})}return t}let K=new Set;function q(e,t,n,r,i,a){let s=[];for(let[c,l]of t.dirs){let t=n?`${n}/${c}`:c,u=`${e}:${t}`,d=document.createElement(`details`);d.open=K.has(u),d.ontoggle=()=>d.open?K.add(u):K.delete(u);let f=o(`summary`,`flex cursor-pointer select-none items-center gap-1 truncate py-1 pr-3 hover:bg-neutral-100`);f.style.paddingLeft=`${20+r*14}px`,f.title=t,f.append(o(`span`,`chev`,`▶`),o(`span`,`truncate text-neutral-600`,c)),l.link&&f.append(ne()),d.append(f,...q(e,l,t,r+1,i,a)),s.push(d)}for(let o of t.files){let t={type:`resource`,kind:e,name:n?`${n}/${o.name}`:o.name};s.push(G(o.name,i(t),!1,()=>a(t),r,o.link?ne():void 0))}return s}function J(e){if(!e){F.replaceChildren();return}let t=e=>JSON.stringify(e)===JSON.stringify(c),n=t=>{C(),c=t,J(e),t.type===`file`?ce(t.name):t.type===`bundled`?ue(t.name):t.type===`tools`?$():t.type===`sync`?w():fe(t.kind,t.name)},i=[];if(r===`global`){let e={type:`sync`};i.push(U(`Instance`),G(`Configuration sync`,t(e),!1,()=>n(e)))}i.push(U(`Files`));for(let r of e.files){let e={type:`file`,name:r.name};i.push(G(r.name,t(e),!r.exists,()=>n(e)))}if(r===`global`){i.push(U(`bundled with Pier`)),_?i.push(o(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-red-600`,_)):E().length||i.push(o(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-neutral-400`,`none`));for(let e of E()){let r={type:`bundled`,name:e.name};i.push(G(e.name,t(r),!1,()=>n(r),0,e.enabled?W():void 0))}if(!_){let e={type:`tools`},r=k().filter(e=>e.enabled).length;i.push(G(`command-line tools`,t(e),!1,()=>n(e),0,r?W():void 0))}}for(let r of[`extensions`,`skills`]){i.push(U(`${r} (read-only)`));let a=e.resources[r];a.length||i.push(o(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-neutral-400`,`none`)),i.push(...q(r,oe(a),``,0,t,n))}F.replaceChildren(...i)}function se(){L.replaceChildren(o(`p`,`px-4 py-3 text-[13px] text-neutral-400`,`Select a file to edit, or browse extensions and skills.`))}function Y(e){L.replaceChildren(o(`p`,`px-4 py-3 text-[13px] text-red-600`,e))}let X=(e,...t)=>o(`div`,`flex flex-none items-center gap-3 border-b border-neutral-200 px-4 py-2`,o(`span`,`font-mono text-[12.5px] text-neutral-500`,e),...t);async function ce(e){let n=++f,r=await d(`/api/config/files/${encodeURIComponent(e)}${z()}`,`failed to load ${e}`,{cache:`no-store`});if(!r.ok){n===f&&Y(r.error);return}if(n!==f)return;let{content:i}=r.value,s=i,c=o(`span`,`text-[11.5px] text-neutral-400`,``),l=o(`button`,`btn btn-primary ml-auto text-[12.5px]`,`Save`),u=document.createElement(`textarea`);u.className=`block min-h-0 flex-1 resize-none bg-white p-4 font-mono text-[13px] leading-relaxed focus:outline-none`,u.spellcheck=!1,u.value=i;let p=async()=>{if(l.disabled)return;let n=u.value;l.disabled=!0,O(c,`saving`,`saving…`);try{let r=await a(`/api/config/files/${encodeURIComponent(e)}${z()}`,{content:n,expected:s},`PUT`);if(!r.ok)return O(c,`failed`,await t(r,`save failed`));let i=await r.json();s=i.content,u.value===n?(u.value=i.content,O(c,`saved`,`saved — applies to new sessions`)):O(c,`idle`,`saved; newer changes are unsaved`)}catch(e){O(c,`failed`,`save failed: ${String(e)}`)}finally{l.disabled=!1}};l.onclick=()=>void p(),u.onkeydown=e=>{(e.metaKey||e.ctrlKey)&&e.key===`s`&&(e.preventDefault(),p())},u.oninput=()=>{O(c,`idle`,`unsaved changes`)},L.replaceChildren(X(e,c,l),u),u.focus()}function le(e){if(!y)return null;let t=o(`a`,`text-indigo-600 hover:underline`,e);return t.href=`#/tasks/${encodeURIComponent(y)}`,t}let Z=()=>{let e=o(`a`,`text-indigo-600 hover:underline`,`ubix`);return e.href=`https://github.com/timqi/ubix`,e.target=`_blank`,e.rel=`noreferrer`,e};function Q(e){if(e.source!==`binary`)return``;let{spec:t,error:n,installed:r,version:i,path:a}=e.binary;return n?`${t} — ${n}`:r?`${t} — ${i??`unknown version`} at ${a??`an unknown path`}`:`${t} — not installed`}function ue(e,t){f++;let n=g.find(t=>t.name===e&&t.kind===`extension`);if(!n)return Y(`unknown extension: ${e}`);let r=o(`span`,`text-[11.5px] text-neutral-400`,``);t&&O(r,t.state,t.text);let i=le(`every run of the update task`);L.replaceChildren(X(n.name,o(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,n.source===`binary`?`installed by Pier`:`ships with Pier`)),o(`div`,`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4`,o(`p`,`max-w-2xl text-[13px] leading-relaxed text-neutral-600`,n.summary),o(`dl`,`flex max-w-2xl flex-col gap-1.5`,...(n.source===`bundled`?n.adds:[]).flatMap(e=>[o(`dt`,`font-mono text-[12px] text-neutral-700`,e.name),o(`dd`,`text-[12px] leading-snug text-neutral-500`,`needs ${e.needs}`)]),...n.source===`binary`?[o(`dt`,`font-mono text-[12px] text-neutral-700`,`binary`),o(`dd`,`font-mono text-[12px] leading-snug ${n.binary.error?`text-red-600`:`text-neutral-500`}`,Q(n))]:[]),l(`Enabled`,n.source===`binary`?`Installed into Pier's own bin directory, first on the PATH every session, task and terminal inherits; it registers its own Pi extension. Switching it off uninstalls both.`:`Loaded from inside Pier — nothing is installed and no update touches your own extensions. A session mid-turn keeps the tools it started with; the next message picks this up.`,n.enabled,t=>void de(n.name,t,t=>ue(e,t))),o(`p`,`max-w-2xl text-[12px] leading-snug text-neutral-400`,...n.source===`binary`?i?[`A daily task installs and updates it — its history is `,i,`.`]:[`Its installs run as the daily update task.`]:[`An extension of your own that registers the same tool wins: this copy stands down and says so in the log.`]),r))}function $(e,t={name:``,toml:``}){f++;let n=o(`span`,`text-[11.5px] text-neutral-400`,``);e&&O(n,e.state,e.text);let r=k(),a=le(`the update task`),s=e=>{let t=o(`div`,`flex min-w-0 flex-1 flex-col gap-0.5`,o(`span`,`flex items-center gap-2 text-[13px] text-neutral-700`,o(`span`,`font-mono`,e.name),...D(e)?[x(`yours`,`bg-neutral-50 text-neutral-500 ring-neutral-200`)]:[]),o(`span`,`text-[11.5px] leading-snug text-neutral-400`,e.summary||Q(e)),...e.summary?[o(`span`,`font-mono text-[11px] leading-snug ${e.source===`binary`&&e.binary.error?`text-red-600`:`text-neutral-400`}`,Q(e))]:[]),n=l(``,``,e.enabled,t=>void de(e.name,t,e=>$(e))),r=o(`button`,`btn text-[12px] text-neutral-500 hover:text-red-600`,`Remove`);return r.onclick=()=>{r.disabled=!0;let t=ae(e,T);V(t.body,t.saved).then(e=>$(e))},o(`div`,`flex max-w-2xl items-start gap-3 border-b border-neutral-100 py-2.5 last:border-0`,t,...D(e)?[r]:[],n)},c={...t},u=o(`span`,`font-mono text-[12px] text-neutral-500`,`[tools.<name>]`),d=i(c.name,`claude`,e=>{c.name=e,u.textContent=`[tools.${e.trim()||`<name>`}]`},!0),p=document.createElement(`textarea`);p.className=`${h} h-24 resize-y font-mono leading-snug`,p.spellcheck=!1,p.value=c.toml,p.placeholder=`spec = "github:owner/repo"
1
+ import{A as e,B as t,C as n,D as r,E as i,G as a,I as o,M as s,N as c,O as l,S as u,V as d,_ as f,b as p,c as m,f as h,g,h as _,j as v,k as y,l as b,m as x,o as S,p as C,q as w,r as T,t as E,v as D,w as O,x as k,y as A}from"./index-DHxoYoeq.js";import{n as j,t as M}from"./code-C86xKk2k.js";var N={display_information:{name:`Pier`,description:`Coding agent sessions in Slack threads`,background_color:`#262626`},features:{bot_user:{display_name:`Pier`,always_online:!1},app_home:{messages_tab_enabled:!0,messages_tab_read_only_enabled:!1}},oauth_config:{scopes:{bot:[`chat:write`,`reactions:write`,`channels:history`,`channels:read`,`groups:history`,`groups:read`,`im:history`,`im:write`,`mpim:history`,`mpim:read`,`mpim:write`,`users:read`,`files:read`,`files:write`]}},settings:{event_subscriptions:{bot_events:[`message.channels`,`message.groups`,`message.im`,`message.mpim`]},interactivity:{is_enabled:!0},socket_mode_enabled:!0,token_rotation_enabled:!1}},P=()=>`https://api.slack.com/apps?new_app=1&manifest_json=${encodeURIComponent(JSON.stringify(N))}`,F=()=>p(`Getting a bot token`,[`Open [@BotFather](https://t.me/BotFather) in Telegram.`,"Send `/newbot`, pick a display name, then a username ending in `bot`.","Copy the token it prints (`123456789:AA…`) and paste it here.","Send `/setprivacy` → `Disable` if the bot should see plain group messages. Left enabled it only ever receives mentions, replies and commands — the usual reason a bot looks dead in a group.","Send `/setjoingroups` → `Enable`, then add the bot to your group or forum."]),I=(e=`left`)=>p(`Enabling topics on a group`,["In Telegram open the group → `Edit` → turn on `Topics`. Owner only; group size no longer matters.","The group becomes a forum supergroup and the existing chat becomes its `General` topic.","Make the bot an admin with `Manage Topics`. That is the one right topic creation needs — without it Pier logs the failure and answers in General instead.","Send one message in the group so Pier discovers it, then enable it under `Chats` below.","After that, a message in General opens its own topic with its own session. A reply, or anything starting with `/`, stays where it was sent."],e);function L(){let e=g(`Create Slack app ↗`,!0);e.classList.add(`mt-1`,`w-fit`),e.onclick=()=>window.open(P(),`_blank`,`noreferrer`);let t=c(`btn w-fit text-[12.5px]`,()=>JSON.stringify(N,null,2));return p(`Creating a Slack app`,[y(`Opens Slack with every scope, event and Socket Mode already filled in. Pick your workspace → Create.`,e),"`Install to Workspace` → allow. Then `OAuth & Permissions` → copy the bot token (`xoxb-…`) into the field above.","`Basic Information` → `App-Level Tokens` → `Generate` with scope `connections:write`. Paste that `xapp-…` token below. The manifest cannot mint this one for you.","In Slack, invite the bot where you want it: `/invite @Pier`. It answers in threads only, so it never adds noise to the channel.",y(`Prefer to paste it yourself? Create the app from a manifest and use this:`,t)])}var R=()=>p(`What agent access allows`,["Gives agent sessions a `slack` tool: read a channel's history for a time range, read one thread, and post, edit or delete a message.",`Editing and deleting reach only what Pier's own bot posted — Slack refuses either on anyone else's message.`,`Pier performs every call itself — the bot token is never given to the agent, and Slack's own membership rules still apply, so the bot reaches only channels it was invited to.`,`Every read fetches live from Slack — Pier keeps no message archive.`,`This includes sessions started by tasks and subagents. Switch it off if an agent should never post to your workspace on its own.`,`The tool is only given to sessions opened while Slack is connected and this is on, so an unused tool costs no context. A session opened earlier keeps it, and a call made after you switch it off is refused with the reason.`]),z=(e=`left`)=>p(`How Slack threads work here`,[`Pier never posts in a channel's main flow. A message in the channel is answered in *its own thread*; a message in a thread is answered in that thread.`,`Each thread is its own Pi session, so one channel hosts many parallel sessions.`,`The same applies in a DM: every new message you send there starts its own thread and its own session. Reply *inside* a thread to continue that conversation.`,"Inside a thread Pier already owns, no `@mention` is needed — continuing that thread is addressing it.","Commands are bare words after a mention: `@bot settings`, `@bot stop`, `@bot bind <code>`. Slack's client swallows an unregistered `/command` before it ever reaches an app."],e),ee=()=>p(`Creating a Feishu app`,["On [open.feishu.cn](https://open.feishu.cn/app) create a 企业自建应用 (custom app). `Credentials & Basic Info` shows the App ID (`cli_…`) and App Secret — paste both here.","`Add Features` → enable **Bot** (机器人).","`Permissions` (权限管理), add: `im:message` (read messages), `im:message:send_as_bot` (send), `im:resource` (attachments, both directions), `im:message.reactions:create` + `:read` + `:delete` (the 👀 receipt), `im:chat:readonly` (chat names for this page), `contact:user.base:readonly` (speaker names).","`Events & Callbacks` → set the mode to **长连接 (long connection)** — no public URL needed. Under Events subscribe `im.message.receive_v1` (接收消息); Callbacks gain `card.action.trigger` automatically once cards are sent, add it if listed.",`**Publish a version** (版本管理与发布 → 创建版本 → 申请发布). Nothing above takes effect until this is approved — the usual reason a configured bot stays silent.`,`Add the bot to a group (群设置 → 群机器人), or DM it directly.`]),B=(e=`left`)=>p(`How Lark topics work here`,[`Pier never posts in a chat's main flow. A message in the chat is answered in *its own topic* (话题); a message inside a topic is answered there.`,`Each topic is its own Pi session, so one group hosts many parallel sessions.`,`The same applies in a DM: every new message starts its own topic and its own session. Reply *inside* a topic to continue that conversation.`,`Inside a topic Pier already owns, no @mention is needed — continuing that topic is addressing it.`,"Commands are slash words: `/stop`, `/settings`, `/bind <code>`. A bare @mention with nothing else also opens the settings panel."],e),V=[[`telegram`,`Telegram`],[`slack`,`Slack`],[`lark`,`Lark`]],H=(e,t)=>o(`span`,`flex items-center gap-1.5 text-[13px] text-neutral-400`,o(`span`,``,e),t),te={dm:`bg-sky-50 text-sky-700 ring-sky-200`,group:`bg-neutral-100 text-neutral-600 ring-neutral-200`,forum:`bg-violet-50 text-violet-700 ring-violet-200`},U=`pier.channelsPlatform`;function ne(e){let t=localStorage.getItem(U),n=V.some(([e])=>e===t)?t:`telegram`,r=null,c=[],p=o(`div`,`ml-auto flex items-center gap-1.5 text-[11.5px]`),m=o(`div`,`sticky top-0 z-30 flex items-center gap-1 border-b border-neutral-200 bg-white px-4 py-2`,p),h=o(`div`,`px-4 py-5`);e.append(o(`div`,`min-h-0 flex-1 overflow-y-auto bg-neutral-50/60`,m,h));function v(){m.replaceChildren(...V.map(([e,t])=>u(t,e===n,()=>{y&&M(),n=e,localStorage.setItem(U,e),N()})),p)}let y,b=!1,S=null;function w(e){if(p.replaceChildren(),e!==`clean`){if(p.className=`ml-auto flex items-center gap-1.5 text-[11.5px] ${C[e]}`,e===`saving`)p.append(o(`span`,`spinner`),o(`span`,``,`Saving…`));else if(e===`saved`)p.append(o(`span`,``,`✓`),o(`span`,``,`Saved`)),setTimeout(()=>{p.textContent?.includes(`Saved`)&&w(`clean`)},2e3);else{let e=_(`Retry`,`cursor-pointer underline`);e.onclick=M,p.append(o(`span`,``,`⚠`),o(`span`,``,`Save failed`),e)}}}function O(){w(`saving`),clearTimeout(y),y=setTimeout(M,500)}let k=e=>t=>{e(t),O()};async function j(e){b=!0,w(`saving`);try{w((await a(`/api/channels/${e.platform}`,e.config,`PUT`)).ok?`saved`:`failed`)}catch{w(`failed`)}finally{b=!1;let e=S;S=null,e&&j(e)}}function M(){if(clearTimeout(y),y=void 0,!r)return;let e={platform:n,config:r};b?S=e:j(e)}async function N(){if(!c.length){let e=await d(`/api/models`,`Could not load the model catalog`);e.ok&&(c=e.value)}let e=await d(`/api/channels/${n}`,`Failed to load`);if(!e.ok){r=null,v(),h.replaceChildren(D(e.error));return}r=e.value,w(`clean`),W()}function P(e){let t=n===`slack`,r=n===`lark`,a=i(e.token,t?`xoxb-…`:r?`cli_…`:`123456789:AA…`,k(t=>e.token=t),!0),o=i(e.appToken,r?``:`xapp-…`,k(t=>e.appToken=t),!0),s=E(e.cwd,`(pier process cwd)`,k(t=>e.cwd=t));return f(`Connection`,t?`Pier connects over Socket Mode; no public URL or webhook needed.`:r?`Pier connects over Feishu's WebSocket long connection; no public URL or webhook needed.`:`Pier polls Telegram for updates; no public URL or webhook needed.`,l(`Enabled`,`Start the adapter when Pier boots.`,e.enabled,k(t=>{e.enabled=t,v()})),A(r?`App ID`:`Bot token`,a,{hint:`Stored locally, shown masked once saved.`,help:n===`telegram`?F():t?L():ee()}),...t?[A(`App-level token`,o,{hint:`Opens the Socket Mode connection. Needs connections:write.`}),l(`Agent access`,`Let agent sessions read channel history and post through the slack tool. Off makes the tool refuse; inbound messages are unaffected.`,e.agentTool,k(t=>e.agentTool=t),R())]:[],...r?[A(`App Secret`,o,{hint:`From Credentials & Basic Info, beside the App ID.`})]:[],A(`Default working directory`,s.el,{hint:`Where sessions this channel opens start.`}))}function ne(e){return f(`Defaults for new chats`,`Copied into a group the first time the bot sees it; changing them here never touches a group that already exists. DMs are always bound-users-only.`,l(`Require mention in groups`,`Ignore group messages that do not @mention or reply to the bot.`,e.requireMention,k(t=>e.requireMention=t)),l(`Require bound user`,`Only users bound with a code below can drive the agent.`,e.requireBind,k(t=>e.requireBind=t)),...n===`slack`?[H(`Thread mode: always on`,z())]:n===`lark`?[H(`Thread mode: always on`,B())]:[l(`Topic mode`,`In a forum group, each new request opens its own topic and its own session.`,e.topicMode,k(t=>e.topicMode=t),I())],T(`Model & reasoning`,e,c,k(t=>{e.model=t.model,e.thinking=t.thinking,W()})))}function re(e){let t=o(`span`,`font-mono text-[15px] font-semibold tracking-widest`),r=o(`div`,`hidden items-center gap-2 rounded-lg bg-indigo-50 px-3 py-2 text-[12.5px] text-indigo-800`,t,o(`span`,`text-[11.5px] text-indigo-500`,`DM the bot /bind <code> · expires in 10 min`)),i=g(`Generate bind code`);i.onclick=async()=>{let e=await fetch(`/api/channels/${n}/bind-code`,{method:`POST`});if(!e.ok)return;let{code:i}=await e.json();t.textContent=i,r.classList.replace(`hidden`,`flex`)};let a=o(`div`,`flex flex-col`);e.users.length||a.append(D(`No bound users yet.`));for(let t of e.users){let e=_(`Remove`,`cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-red-600 group-hover:opacity-100`);e.onclick=async()=>{await fetch(`/api/channels/${n}/users/${encodeURIComponent(t.id)}`,{method:`DELETE`}),await N()},a.append(o(`div`,`group flex items-center gap-2.5 border-b border-neutral-100 py-2 last:border-0`,o(`span`,`flex h-6 w-6 flex-none items-center justify-center rounded-full bg-neutral-100 text-[11px] font-semibold text-neutral-500`,(t.name[0]??`?`).toUpperCase()),o(`span`,`min-w-0 flex-1 truncate text-[13px] text-neutral-700`,t.name),o(`span`,`flex-none font-mono text-[11.5px] text-neutral-400`,t.id),e))}return f(`Bound users`,`A code is single-use and expires; redeeming it in a DM binds that account.`,a,o(`div`,`flex flex-col gap-2`,i,r))}function ie(e,t){let r=o(`div`,`rounded-xl border px-3.5 py-3 transition-colors ${t.enabled?`border-neutral-200 bg-white`:`border-neutral-200 bg-neutral-50/60`}`),i=o(`div`,`flex items-center gap-2`,o(`span`,`min-w-0 flex-1 truncate text-[13px] font-medium ${t.enabled?`text-neutral-800`:`text-neutral-400`}`,t.name||t.id),x(t.kind,te[t.kind]),o(`span`,`flex-none font-mono text-[11px] text-neutral-400`,t.id)),a=l(``,``,t.enabled,k(e=>{t.enabled=e,W()}));a.classList.add(`flex-none`,`items-center`),i.append(a);let s=o(`div`,`mt-3 flex flex-wrap items-center gap-x-6 gap-y-2`);t.kind===`dm`?s.append(o(`span`,`text-[13px] text-neutral-400`,n===`telegram`?`Direct message · bound users only, mention and topics not applicable`:`Direct message · bound users only, mention not applicable`)):s.append(l(`Require mention`,``,t.requireMention,k(e=>t.requireMention=e)),l(`Require bind`,``,t.requireBind,k(e=>t.requireBind=e)),n===`slack`?H(`Thread mode: always on`,z(`right`)):n===`lark`?H(`Thread mode: always on`,B(`right`)):t.kind===`forum`?l(`Topic mode`,``,t.topicMode,k(e=>t.topicMode=e),I(`right`)):H(`Topic mode: forum groups only`,I(`right`)));let u=E(t.cwd,``,k(e=>t.cwd=e)),d=o(`div`,`mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2`,A(`Working directory`,u.el),T(`Model & reasoning`,t,c,k(e=>{t.model=e.model,t.thinking=e.thinking,W()})));return r.append(i,s,d),r}function ae(e){let t=o(`div`,`flex flex-col gap-2.5`);return e.chats.length?t.append(...e.chats.map(t=>ie(e,t))):t.append(D(`None yet. Chats appear here after the bot sees a message in them.`)),f(n===`slack`?`Channels`:`Chats`,`Discovered from inbound traffic — no platform reliably lists every chat a bot is in.`,t)}function W(){if(!r)return;v();let e=o(`div`,`mx-auto flex max-w-3xl flex-col gap-4`);e.append(P(r),ne(r),re(r),ae(r)),h.replaceChildren(e)}return s(e,()=>void N(),()=>{y&&M()})}function re(){let e=o(`div`,`min-h-0 min-w-0 flex-1 overflow-y-auto p-4`),n=o(`div`,`mx-auto flex max-w-3xl min-w-0 flex-col gap-4`),r=o(`p`,`text-[12px] break-words`),s=o(`section`,`flex min-w-0 flex-col gap-3 border-b border-neutral-200 pb-4`),u=o(`section`,`flex min-w-0 flex-col gap-3`);n.append(o(`h2`,`text-[14px] font-semibold text-neutral-700`,`Configuration sync`),r,s,u),e.append(n);let f=null,p=!1,m=!1,h=0,_=``,v=!1,y=e=>e?new Date(e).toLocaleString():`Never`;async function b(){let e=h,t=await d(`/api/config-sync`,`Could not load configuration sync`,{cache:`no-store`});if(!(m||e!==h)){if(!t.ok){O(r,`failed`,t.error);return}f=t.value,v||(_=f.sourceUrl),C()}}async function x(e){if(!p){++h,p=!0,C(),O(r,`saving`,`Working...`);try{let n=await a(`/api/config-sync`,{action:e,...e===`subscribe`?{url:_}:{}});if(!n.ok)throw Error(await t(n,`Configuration sync failed`));let i=await n.json();f=i,v=!1,_=i.sourceUrl,O(r,`saved`,i.result??`Saved`)}catch(e){O(r,`failed`,e instanceof Error?e.message:`Configuration sync failed`),await b()}finally{p=!1,m||C()}}}function S(e,t){let n=g(e);return n.disabled=p,n.onclick=()=>{x(t)},n}function C(){if(!f||m)return;if(s.replaceChildren(o(`h3`,`text-[13px] font-medium text-neutral-700`,`Publish`)),f.publishedPath){let e=`${f.publicUrl||window.location.origin}${f.publishedPath}`,t=i(e,``,()=>{},!0);t.readOnly=!0,t.setAttribute(`aria-label`,`Sharing URL`),s.append(t,o(`div`,`flex flex-wrap items-center gap-2`,c(`btn text-[12px]`,()=>e),S(`Revoke link`,`revoke`)))}else s.append(o(`div`,``,S(`Generate link`,`publish`)));s.append(o(`p`,`text-[12px] text-neutral-500`,`Anyone with the link can read shared prompts. Provider connections and credentials stay private.`));let e=i(_,`https://example.com/config-sync/...`,e=>{_=e,v=!0},!0);e.type=`url`,e.setAttribute(`aria-label`,`Configuration source URL`),e.disabled=p||f.enabled;let t=l(`Automatic sync`,``,f.enabled,e=>{x(e?`subscribe`:`pause`)});t.querySelector(`input`).disabled=p;let n=o(`div`,`flex flex-wrap items-center gap-3`,t);f.enabled&&n.append(S(`Sync now`,`sync`)),u.replaceChildren(o(`h3`,`text-[13px] font-medium text-neutral-700`,`Source`),A(`Source URL`,e),n);let r=o(`dl`,`grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1 text-[12px]`);for(let[e,t]of[[`Last checked`,y(f.lastChecked)],[`Last applied`,y(f.lastApplied)],[`Next check`,f.enabled?y(f.nextRunAt):`Paused`]])r.append(o(`dt`,`text-neutral-500`,e),o(`dd`,`min-w-0 break-words text-neutral-700`,t));if(u.append(r),f.error&&u.append(o(`p`,`text-[12px] break-words text-red-600`,f.error)),f.needsReload&&u.append(o(`p`,`text-[12px] text-amber-700`,`Reload pending; retry synchronization.`)),f.taskId){let e=o(`a`,`text-[12px] text-indigo-600 hover:underline`,`Sync task history`);e.href=`#/tasks/${encodeURIComponent(f.taskId)}`,u.append(e)}}b();let w=setInterval(()=>{!p&&!v&&b()},15e3);return{el:e,dispose:()=>{m=!0,clearInterval(w)}}}async function ie(e,n){let r;try{r=await a(`/api/settings`,e,`PUT`)}catch(e){return{outcome:{state:`failed`,text:`Could not save: ${String(e)}`}}}if(!r.ok)return{outcome:{state:`failed`,text:await t(r,`could not save`)}};let i;try{i=await r.json()}catch(e){return{outcome:{state:`failed`,text:`Saved, but the answer could not be read: ${String(e)}`}}}return i.toolsSync?.state===`refused`?{outcome:{state:`failed`,text:`Saved, but nothing will install it: ${i.toolsSync.reason}`},answer:i}:i.toolsSync?.state===`waiting`?{outcome:{state:`saved`,text:`Saved — a sync is already running; this change goes in the run right after it.`},answer:i}:{outcome:{state:`saved`,text:n},answer:i}}function ae(e,t){return e.enabled?{body:{tool:{name:e.name,on:!1}},saved:`Switched ${e.name} off — the next run uninstalls it. Remove it again once its binary is gone.`}:{body:{customTools:t.filter(t=>t.name!==e.name)},saved:`Removed ${e.name}.`}}function W(e,n){let r=`global`,c=null,u=0,f=0,p=``,m=null,g=[],_=``,y=null,S=null,C=()=>{S?.dispose(),S=null},w=()=>{C(),++f,S=re(),L.replaceChildren(S.el)},T=[],E=()=>g.filter(e=>e.kind===`extension`),D=e=>e.source===`binary`&&e.custom===!0,k=()=>g.filter(e=>e.kind===`tool`),N=document.createElement(`select`);N.className=`select w-full rounded-md border border-neutral-300 px-2 py-1 text-[12.5px] focus:border-indigo-400 focus:outline-none`,N.onchange=()=>{C(),r=N.value,c=null,K.clear(),te()};let P=o(`div`,`flex flex-none flex-col gap-1 border-b border-neutral-200 px-3 pb-2.5 pt-2`);P.append(o(`span`,`text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,`Scope`),N);let F=o(`div`,`min-h-0 flex-1 overflow-y-auto py-1`),I=o(`nav`,`flex w-64 flex-none flex-col border-r border-neutral-200 text-[13px] max-md:max-h-48 max-md:w-full max-md:border-r-0 max-md:border-b`);I.append(P,F);let L=o(`div`,`flex min-w-0 flex-1 flex-col`),R=o(`div`,`flex min-h-0 flex-1 max-md:flex-col`);R.append(I,L),e.append(R);let z=(e=``)=>`?scope=${encodeURIComponent(r)}${e}`;async function ee(){if(r!==`global`){g=[],_=``;return}let e=await d(`/api/settings`,`could not be loaded`,{cache:`no-store`});if(!e.ok){g=[],_=e.error;return}B(e.value),_=``}function B(e){g=e.catalog,T=e.customTools,y=e.toolsTaskId}async function V(e,t){let{outcome:n,answer:r}=await ie(e,t);return r&&(B(r),J(m)),n}function H(e,t){let n={name:e,on:t};return g.find(t=>t.name===e)?.source===`binary`?{tool:n}:{extension:n}}async function te(){let e=++u;f++;let[t]=await Promise.all([d(`/api/config${z()}`,`failed to load config`,{cache:`no-store`}),ee()]);if(e!==u)return;if(!t.ok){J(null),Y(t.error);return}let n=t.value;r===`global`&&n.dir&&(p=n.dir,pe()),m=n,J(n),c?c.type===`sync`&&w():se()}function U(e){return o(`div`,`px-3 pb-0.5 pt-2.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e)}let ne=()=>{let e=o(`span`,`flex-none rounded bg-neutral-100 px-1 text-[10px] font-semibold uppercase tracking-wide text-neutral-500`,`link`);return e.title=`Reached through a symlink`,e},W=()=>o(`span`,`flex-none rounded bg-emerald-50 px-1 text-[10px] font-semibold uppercase tracking-wide text-emerald-700`,`on`);function G(e,t,n,r,i=0,a){let s=o(`button`,`flex w-full cursor-pointer items-center gap-1.5 py-1 pr-3 text-left hover:bg-neutral-100 ${t?`bg-indigo-50 hover:bg-indigo-50`:``} ${n?`text-neutral-400`:``}`);return s.append(o(`span`,`truncate`,e)),a&&s.append(a),s.style.paddingLeft=`${20+i*14}px`,s.title=e,s.onclick=r,s}function oe(e){let t={files:[],dirs:new Map,link:!0};for(let n of e){let e=n.name.split(`/`),r=t;for(let t of e.slice(0,-1)){let e=r.dirs.get(t);e||r.dirs.set(t,e={files:[],dirs:new Map,link:!0}),e.link&&=n.link,r=e}r.files.push({name:e[e.length-1],link:n.link})}return t}let K=new Set;function q(e,t,n,r,i,a){let s=[];for(let[c,l]of t.dirs){let t=n?`${n}/${c}`:c,u=`${e}:${t}`,d=document.createElement(`details`);d.open=K.has(u),d.ontoggle=()=>d.open?K.add(u):K.delete(u);let f=o(`summary`,`flex cursor-pointer select-none items-center gap-1 truncate py-1 pr-3 hover:bg-neutral-100`);f.style.paddingLeft=`${20+r*14}px`,f.title=t,f.append(o(`span`,`chev`,`▶`),o(`span`,`truncate text-neutral-600`,c)),l.link&&f.append(ne()),d.append(f,...q(e,l,t,r+1,i,a)),s.push(d)}for(let o of t.files){let t={type:`resource`,kind:e,name:n?`${n}/${o.name}`:o.name};s.push(G(o.name,i(t),!1,()=>a(t),r,o.link?ne():void 0))}return s}function J(e){if(!e){F.replaceChildren();return}let t=e=>JSON.stringify(e)===JSON.stringify(c),n=t=>{C(),c=t,J(e),t.type===`file`?ce(t.name):t.type===`bundled`?ue(t.name):t.type===`tools`?$():t.type===`sync`?w():fe(t.kind,t.name)},i=[];if(r===`global`){let e={type:`sync`};i.push(U(`Instance`),G(`Configuration sync`,t(e),!1,()=>n(e)))}i.push(U(`Files`));for(let r of e.files){let e={type:`file`,name:r.name};i.push(G(r.name,t(e),!r.exists,()=>n(e)))}if(r===`global`){i.push(U(`bundled with Pier`)),_?i.push(o(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-red-600`,_)):E().length||i.push(o(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-neutral-400`,`none`));for(let e of E()){let r={type:`bundled`,name:e.name};i.push(G(e.name,t(r),!1,()=>n(r),0,e.enabled?W():void 0))}if(!_){let e={type:`tools`},r=k().filter(e=>e.enabled).length;i.push(G(`command-line tools`,t(e),!1,()=>n(e),0,r?W():void 0))}}for(let r of[`extensions`,`skills`]){i.push(U(`${r} (read-only)`));let a=e.resources[r];a.length||i.push(o(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-neutral-400`,`none`)),i.push(...q(r,oe(a),``,0,t,n))}F.replaceChildren(...i)}function se(){L.replaceChildren(o(`p`,`px-4 py-3 text-[13px] text-neutral-400`,`Select a file to edit, or browse extensions and skills.`))}function Y(e){L.replaceChildren(o(`p`,`px-4 py-3 text-[13px] text-red-600`,e))}let X=(e,...t)=>o(`div`,`flex flex-none items-center gap-3 border-b border-neutral-200 px-4 py-2`,o(`span`,`font-mono text-[12.5px] text-neutral-500`,e),...t);async function ce(e){let n=++f,r=await d(`/api/config/files/${encodeURIComponent(e)}${z()}`,`failed to load ${e}`,{cache:`no-store`});if(!r.ok){n===f&&Y(r.error);return}if(n!==f)return;let{content:i}=r.value,s=i,c=o(`span`,`text-[11.5px] text-neutral-400`,``),l=o(`button`,`btn btn-primary ml-auto text-[12.5px]`,`Save`),u=document.createElement(`textarea`);u.className=`block min-h-0 flex-1 resize-none bg-white p-4 font-mono text-[13px] leading-relaxed focus:outline-none`,u.spellcheck=!1,u.value=i;let p=async()=>{if(l.disabled)return;let n=u.value;l.disabled=!0,O(c,`saving`,`saving…`);try{let r=await a(`/api/config/files/${encodeURIComponent(e)}${z()}`,{content:n,expected:s},`PUT`);if(!r.ok)return O(c,`failed`,await t(r,`save failed`));let i=await r.json();s=i.content,u.value===n?(u.value=i.content,O(c,`saved`,`saved — applies to new sessions`)):O(c,`idle`,`saved; newer changes are unsaved`)}catch(e){O(c,`failed`,`save failed: ${String(e)}`)}finally{l.disabled=!1}};l.onclick=()=>void p(),u.onkeydown=e=>{(e.metaKey||e.ctrlKey)&&e.key===`s`&&(e.preventDefault(),p())},u.oninput=()=>{O(c,`idle`,`unsaved changes`)},L.replaceChildren(X(e,c,l),u),u.focus()}function le(e){if(!y)return null;let t=o(`a`,`text-indigo-600 hover:underline`,e);return t.href=`#/tasks/${encodeURIComponent(y)}`,t}let Z=()=>{let e=o(`a`,`text-indigo-600 hover:underline`,`ubix`);return e.href=`https://github.com/timqi/ubix`,e.target=`_blank`,e.rel=`noreferrer`,e};function Q(e){if(e.source!==`binary`)return``;let{spec:t,error:n,installed:r,version:i,path:a}=e.binary;return n?`${t} — ${n}`:r?`${t} — ${i??`unknown version`} at ${a??`an unknown path`}`:`${t} — not installed`}function ue(e,t){f++;let n=g.find(t=>t.name===e&&t.kind===`extension`);if(!n)return Y(`unknown extension: ${e}`);let r=o(`span`,`text-[11.5px] text-neutral-400`,``);t&&O(r,t.state,t.text);let i=le(`every run of the update task`);L.replaceChildren(X(n.name,o(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,n.source===`binary`?`installed by Pier`:`ships with Pier`)),o(`div`,`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4`,o(`p`,`max-w-2xl text-[13px] leading-relaxed text-neutral-600`,n.summary),o(`dl`,`flex max-w-2xl flex-col gap-1.5`,...(n.source===`bundled`?n.adds:[]).flatMap(e=>[o(`dt`,`font-mono text-[12px] text-neutral-700`,e.name),o(`dd`,`text-[12px] leading-snug text-neutral-500`,`needs ${e.needs}`)]),...n.source===`binary`?[o(`dt`,`font-mono text-[12px] text-neutral-700`,`binary`),o(`dd`,`font-mono text-[12px] leading-snug ${n.binary.error?`text-red-600`:`text-neutral-500`}`,Q(n))]:[]),l(`Enabled`,n.source===`binary`?`Installed into Pier's own bin directory, first on the PATH every session, task and terminal inherits; it registers its own Pi extension. Switching it off uninstalls both.`:`Loaded from inside Pier — nothing is installed and no update touches your own extensions. A session mid-turn keeps the tools it started with; the next message picks this up.`,n.enabled,t=>void de(n.name,t,t=>ue(e,t))),o(`p`,`max-w-2xl text-[12px] leading-snug text-neutral-400`,...n.source===`binary`?i?[`A daily task installs and updates it — its history is `,i,`.`]:[`Its installs run as the daily update task.`]:[`An extension of your own that registers the same tool wins: this copy stands down and says so in the log.`]),r))}function $(e,t={name:``,toml:``}){f++;let n=o(`span`,`text-[11.5px] text-neutral-400`,``);e&&O(n,e.state,e.text);let r=k(),a=le(`the update task`),s=e=>{let t=o(`div`,`flex min-w-0 flex-1 flex-col gap-0.5`,o(`span`,`flex items-center gap-2 text-[13px] text-neutral-700`,o(`span`,`font-mono`,e.name),...D(e)?[x(`yours`,`bg-neutral-50 text-neutral-500 ring-neutral-200`)]:[]),o(`span`,`text-[11.5px] leading-snug text-neutral-400`,e.summary||Q(e)),...e.summary?[o(`span`,`font-mono text-[11px] leading-snug ${e.source===`binary`&&e.binary.error?`text-red-600`:`text-neutral-400`}`,Q(e))]:[]),n=l(``,``,e.enabled,t=>void de(e.name,t,e=>$(e))),r=o(`button`,`btn text-[12px] text-neutral-500 hover:text-red-600`,`Remove`);return r.onclick=()=>{r.disabled=!0;let t=ae(e,T);V(t.body,t.saved).then(e=>$(e))},o(`div`,`flex max-w-2xl items-start gap-3 border-b border-neutral-100 py-2.5 last:border-0`,t,...D(e)?[r]:[],n)},c={...t},u=o(`span`,`font-mono text-[12px] text-neutral-500`,`[tools.<name>]`),d=i(c.name,`claude`,e=>{c.name=e,u.textContent=`[tools.${e.trim()||`<name>`}]`},!0),p=document.createElement(`textarea`);p.className=`${h} h-24 resize-y font-mono leading-snug`,p.spellcheck=!1,p.value=c.toml,p.placeholder=`spec = "github:owner/repo"
2
2
  exe = "tool"`,p.oninput=()=>c.toml=p.value;let m=o(`button`,`btn btn-primary text-[12.5px]`,`Add`);m.onclick=()=>{let e={name:c.name.trim(),toml:c.toml.trim()};if(!e.name||!e.toml)return O(n,`failed`,`A custom tool needs a name and a block with a spec line.`);m.disabled=!0,V({customTools:[...T,e],tool:{name:e.name,on:!0}},`Added ${e.name} — installing now.`).then(e=>$(e,e.state===`failed`?c:void 0))},L.replaceChildren(X(`command-line tools`,o(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,`installed by Pier`)),o(`div`,`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4`,o(`p`,`max-w-2xl text-[12.5px] leading-relaxed text-neutral-500`,`Pier writes no downloader: `,Z(),` does the work — a declarative installer that resolves a spec like `,o(`span`,`font-mono text-[11.5px]`,`github:owner/repo`),` to the right release asset for this machine, verifies it, and upgrades in place. Pier bootstraps it, generates its config from the switches below, and keeps its files under Pier's own directory — your own ubix setup is untouched.`),_?o(`p`,`max-w-2xl text-[12.5px] text-red-600`,_):o(`div`,`flex max-w-2xl flex-col`,...r.map(s)),o(`div`,`flex max-w-2xl flex-col gap-2 border-t border-neutral-200 pt-4`,o(`span`,`text-[12.5px] font-medium text-neutral-600`,`Add one of your own`),A(`Name`,d),A(`The block Pier writes under the header`,p,{hint:`A line that opens a section of its own is refused, because it could rewrite the rest of the file.`}),o(`div`,`flex items-center gap-3`,u,m)),o(`p`,`max-w-2xl text-[12px] leading-snug text-neutral-400`,...a?[`Installs and daily updates run as `,a,` — output, failures and all.`]:[`Switching one on creates the daily task that installs it and keeps it current.`]),n))}async function de(e,t,n){let r=g.find(t=>t.name===e);n(await V(H(e,t),r?.source===`binary`?t?`Saved — installing now; watch the run.`:`Saved — uninstalling in the next run.`:`Saved — sessions take it on their next message.`))}async function fe(e,t){let n=++f,r=await d(`/api/config/resource${z(`&kind=${e}&name=${encodeURIComponent(t)}`)}`,`failed to load ${t}`,{cache:`no-store`});if(!r.ok){n===f&&Y(r.error);return}if(n!==f)return;let{content:i}=r.value,a=i.split(`
3
3
  `);a.at(-1)===``&&a.pop();let s=await b(t);n===f&&L.replaceChildren(X(t,o(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,`read-only`)),o(`div`,`min-h-0 flex-1 overflow-auto`,M(j(a),s)))}function pe(){N.replaceChildren(new Option(p?`Global (${p})`:`Global`,`global`),...n().map(e=>new Option(`${v(e)} — ${e}`,e))),[...N.options].some(e=>e.value===r)||(r=`global`),N.value=r}return s(e,()=>{pe(),te()},C)}var G=e=>`${e.provider}/${e.id}`,oe=[`hardest reasoning — architecture, gnarly debugging`,`long autonomous implementation runs`,`balanced default — implementation, review`,`cheap & fast — listings, extraction, simple checks`,`cross-vendor second opinion`];function K(){let e=[],r=[],i=!1,s=o(`span`,`text-[11.5px]`,``),c=g(`Save menu`,!0),l=o(`div`,`flex min-w-0 flex-col gap-2`),u=o(`div`,`flex items-center gap-2`),p=o(`div`,`mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-6`);function h(){i=!0,O(s,`idle`,`unsaved changes`)}function _(t){let r=k(t.note??``);r.classList.remove(`w-full`),r.classList.add(`min-w-0`,`flex-1`),r.placeholder=`why this one — pick a preset or write your own`,r.setAttribute(`list`,`model-menu-notes`),r.oninput=()=>{t.note=r.value,h()};let i=n([[`thinking: model default`,``],...m.map(e=>[`thinking: ${w(e)}`,e])],t.thinking??``);i.classList.replace(`w-full`,`w-44`),i.classList.add(`flex-none`),i.onchange=()=>{i.value?t.thinking=i.value:delete t.thinking,h()};let a=g(`Remove`);a.classList.add(`flex-none`),a.onclick=()=>{e=e.filter(e=>e!==t),h(),y()};let s=o(`span`,`w-52 flex-none truncate font-mono text-[12px] text-neutral-700`,G(t));return s.title=G(t),o(`div`,`flex min-w-0 items-center gap-2 rounded-lg border border-neutral-200 bg-white px-3 py-2 shadow-2xs max-md:flex-wrap`,s,i,r,a)}function v(){let t=r.filter(t=>!e.some(e=>G(e)===G(t))),i=n(t.map(e=>[G(e),G(e)]),t[0]?G(t[0]):``);i.classList.replace(`w-full`,`flex-1`),i.classList.add(`min-w-0`);let a=g(`+ Pin model`);a.classList.add(`flex-none`,`whitespace-nowrap`),a.disabled=t.length===0,a.onclick=()=>{let n=t.find(e=>G(e)===i.value);n&&(e.push({...n}),h(),y())},u.replaceChildren(i,a)}function y(){l.replaceChildren(...e.length?e.map(_):[D(`Nothing pinned — every picker shows the curated catalog as is.`)]),v()}async function b(){O(s,`saving`,`saving…`);let n=e.map(({provider:e,id:t,thinking:n,note:r})=>({provider:e,id:t,...n?{thinking:n}:{},...r?.trim()?{note:r.trim()}:{}})),r=await a(`/api/settings`,{modelMenu:n},`PUT`);if(!r.ok)return O(s,`failed`,await t(r,`Could not save`));e=(await r.json()).modelMenu,i=!1,O(s,`saved`,`Saved — agents see it on their next models call.`),y()}c.onclick=()=>void b();function x(){i||(async()=>{let[t,n]=await Promise.all([d(`/api/settings`,`Could not load the menu`),d(`/api/models`,`Could not load the model catalog`)]);if(!t.ok)return O(s,`failed`,t.error);e=t.value.modelMenu,r=n.ok?n.value:[],s.textContent=``,y()})()}let S=o(`datalist`,``);return S.id=`model-menu-notes`,S.append(...oe.map(e=>new Option(e))),p.append(f(`Model menu`,`Which few models this deployment favors, each with a usual reasoning level and one line of intent. Pinned entries lead every model picker, and agents delegating work match your notes against the task instead of guessing ids.`,A(`Pinned models`,l,{hint:`The note is what an agent matches a task against — say when to reach for it, not what it is.`}),A(`Add`,u,{hint:`The list is the live catalog — only models that exist right now can be pinned.`}),o(`div`,`flex items-center gap-3`,c,s),S)),{el:p,load:x}}var q=(e,t)=>{let n;try{n=new URL(e)}catch{return null}if(n.protocol!==`http:`&&n.protocol!==`https:`)return null;let r=o(`a`,`text-indigo-600 hover:underline`,t);return r.href=n.href,r.target=`_blank`,r.rel=`noreferrer`,r};function J(e,n,r,i){let s=document.createElement(`dialog`);s.className=`m-auto w-[min(32rem,92vw)] rounded-lg border border-neutral-200 bg-white p-0 shadow-xl backdrop:bg-black/30`;let l=o(`div`,`flex flex-col gap-2`),u=o(`div`,`flex flex-col gap-2`),d=o(`p`,`text-[12.5px] text-neutral-400`,`Starting…`),f=g(`Cancel`),p=(e,t)=>{d.className=`text-[12.5px] ${C[e]}`,d.textContent=t};s.append(o(`div`,`border-b border-neutral-200 px-4 py-2.5 text-[14px] font-semibold`,n),o(`div`,`flex max-h-[65vh] flex-col gap-3 overflow-y-auto px-4 py-3`,l,u,d),o(`div`,`flex justify-end border-t border-neutral-200 px-4 py-2.5`,f)),document.body.append(s),s.showModal();let m=e.id,h=e.state,_,v,y=new Set,b=!1,x=!1,S=async e=>{if(!x){if(e&&h===`running`){x=!0,f.disabled=!0;try{let e=await a(`/api/providers/flows/${m}/cancel`,{});if(!e.ok&&e.status!==404){p(`failed`,await t(e,`Could not cancel authentication flow`));return}}catch(e){p(`failed`,`Could not cancel authentication flow: ${String(e)}`);return}finally{x=!1,f.disabled=!1}}clearTimeout(_),s.close()}};f.onclick=()=>void S(!0),s.oncancel=e=>{e.preventDefault(),S(!0)},s.onclose=()=>{b=!0,clearTimeout(_),s.remove()};let w=e=>{if(e.type===`auth_url`){let t=o(`div`,`flex flex-col gap-1 text-[12.5px] text-neutral-600`);return e.instructions&&t.append(o(`p`,``,e.instructions)),t.append(q(e.url,`Open authorization page`)??o(`span`,`text-red-600`,`Invalid authorization URL`)),t}if(e.type===`device_code`){let t=o(`div`,`flex flex-col gap-2 text-[12.5px] text-neutral-600`);return t.append(o(`div`,`flex items-center gap-2`,o(`code`,`font-mono text-[17px] font-semibold text-neutral-800`,e.userCode),c(`btn text-[11px]`,()=>e.userCode))),t.append(q(e.verificationUri,`Open verification page`)??o(`span`,`text-red-600`,`Invalid verification URL`)),t}let t=o(`div`,`text-[12.5px] text-neutral-600`,e.message);if(e.type===`info`)for(let n of e.links??[]){let e=q(n.url,n.label??n.url);e&&t.append(` `,e)}return t},T=(e,n)=>{v=n.id;let r;if(n.type===`select`){let e=document.createElement(`select`);e.append(...n.options.map(e=>new Option(e.description?`${e.label} — ${e.description}`:e.label,e.id))),r=e}else{let e=k(``,n.type===`secret`?`password`:`text`);e.placeholder=n.placeholder??``,e.autocomplete=`off`,r=e}r.className=`${r.tagName===`SELECT`?`select `:``}w-full rounded-lg border border-neutral-300 bg-white px-2.5 py-1.5 text-[12.5px] focus:border-indigo-400 focus:outline-none`;let i=g(`Continue`,!0);i.type=`submit`;let s=o(`form`,`flex flex-col gap-2`,o(`label`,`text-[12.5px] font-medium text-neutral-700`,n.message),r,o(`div`,`flex justify-end`,i));s.onsubmit=o=>{o.preventDefault(),i.disabled=!0,(async()=>{try{let i=await a(`/api/providers/flows/${e.id}/respond`,{promptId:n.id,value:r.value});if(b)return;if(!i.ok){p(`failed`,await t(i,`Could not submit response`));return}y.add(n.id),v=void 0,u.replaceChildren(),p(`saving`,`Waiting for provider…`)}catch(e){b||p(`failed`,`Could not submit response: ${String(e)}`)}finally{i.disabled=!1}})()},u.replaceChildren(s),r.focus()},E=e=>{h=e.state,l.replaceChildren(...e.events.map(w));let t=e.prompt&&!y.has(e.prompt.id)?e.prompt:void 0;if(t?.id!==v&&(t?T(e,t):(v=void 0,u.replaceChildren())),e.state===`running`){p(`saving`,t?`Waiting for your response.`:`Waiting for provider…`);return}clearTimeout(_),u.replaceChildren(),e.state===`succeeded`?p(`saved`,`${r} configured.`):p(`failed`,e.state===`cancelled`?`Cancelled.`:e.error??`Authentication failed.`),f.textContent=`Close`,f.onclick=()=>void S(!1),e.state===`succeeded`&&i()},D=async()=>{if(!(b||h!==`running`))try{let e=await fetch(`/api/providers/flows/${m}`,{cache:`no-store`});if(b)return;if(!e.ok){p(`failed`,await t(e,`Authentication status unavailable`)),e.status===404?h=`failed`:_=setTimeout(()=>void D(),1e3);return}E(await e.json()),h===`running`&&(_=setTimeout(()=>void D(),500))}catch(e){if(b)return;p(`failed`,`Authentication status unavailable: ${String(e)}`),_=setTimeout(()=>void D(),1e3)}};E(e),h===`running`&&(_=setTimeout(()=>void D(),500))}var se=[`anthropic`,`openai`,`openai-codex`,`google`,`openrouter`,`deepseek`],Y=[[`OpenAI Chat Completions`,`openai-completions`],[`OpenAI Responses`,`openai-responses`],[`Anthropic Messages`,`anthropic-messages`],[`Google Generative AI`,`google-generative-ai`]],X=`__custom__`;async function ce(e){let r=g(`Add provider`,!0);r.classList.add(`ml-auto`);let i=o(`div`,`flex flex-none items-center gap-3 rounded-t-xl border-b border-neutral-200/70 bg-neutral-50/70 px-4 py-2`,o(`h2`,`text-[13px] font-semibold text-neutral-700`,`Providers`),r),s=o(`div`,`min-h-0 flex-1 overflow-y-auto`);e.replaceChildren(i,s);let c=[],l=``,u=async()=>{s.replaceChildren(o(`p`,`px-4 py-3 text-[13px] text-neutral-400`,`Loading…`));try{let[e,t]=await Promise.all([d(`/api/providers`,`Could not load providers`,{cache:`no-store`}),d(`/api/models`,`the model catalog could not be read`,{cache:`no-store`})]);if(c=t.ok?t.value:[],l=t.ok?``:t.error,!e.ok){s.replaceChildren(D(e.error));return}let n=e.value;r.onclick=()=>Z(n,void 0,u),_(n)}catch(e){s.replaceChildren(D(`Could not load providers: ${String(e)}`))}},f=async e=>{if(window.confirm(`Remove the stored credential for ${e.name}?`))try{let n=await a(`/api/providers/${encodeURIComponent(e.id)}/logout`,{});if(!n.ok){window.alert(await t(n,`Could not remove credential`));return}await u()}catch(e){window.alert(`Could not remove credential: ${String(e)}`)}},p=e=>[...new Set([...(e.models??[]).map(e=>e.id),...c.filter(t=>t.provider===e.id).map(e=>e.id)])],m=(e,t)=>o(`div`,`flex flex-col gap-1`,o(`span`,`text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),o(`pre`,`max-h-56 overflow-auto whitespace-pre-wrap break-all rounded-md bg-neutral-50 p-2 font-mono text-[11.5px] leading-relaxed text-neutral-600`,t)),h=async(e,n)=>{try{let r=await a(`/api/providers/${encodeURIComponent(e)}/check`,{model:n});return r.ok?await r.json():await t(r,`Could not test`)}catch(e){return`Could not test: ${String(e)}`}},_=e=>{let t=e.filter(e=>e.configured);if(!t.length){s.replaceChildren(D(`No providers configured.`));return}s.replaceChildren(...t.map(t=>{let r=o(`div`,`min-w-0 flex-1`,o(`div`,`truncate text-[13px] font-medium text-neutral-700`,t.name),o(`div`,`truncate font-mono text-[11px] text-neutral-400`,t.id)),i=t.stored===`api_key`?`API key`:t.stored===`oauth`?`OAuth`:t.source??`configured`,a=t.endpoint??`Default endpoint`,s=o(`div`,`flex min-w-32 flex-col items-start gap-1`,x(`configured`,`bg-emerald-50 text-emerald-700 ring-emerald-200`),o(`span`,`max-w-48 truncate text-[11px] text-neutral-500`,i),o(`span`,`max-w-48 truncate text-[11px] text-neutral-400`,a));s.title=a;let c=o(`span`,`text-[11.5px]`,``),d=o(`div`,`hidden flex-col gap-2 px-4 pb-3`,c),_=o(`div`,`flex flex-wrap justify-end gap-1.5`),v=p(t);if(!v.length)O(c,`idle`,l||`No models to test: none are configured here.`),d.classList.replace(`hidden`,`flex`);else{let e=n([[`Model to test…`,``],...v.map(e=>[e,e])],``);e.classList.add(`max-w-52`,`text-[12px]`);let r=g(`Test`);r.disabled=!0,e.onchange=()=>r.disabled=!e.value,r.onclick=()=>{let n=e.value;r.disabled=!0,d.replaceChildren(c),d.classList.replace(`hidden`,`flex`),O(c,`saving`,`asking ${n}…`),h(t.id,n).then(e=>{if(r.disabled=!1,typeof e==`string`)return O(c,`failed`,e);O(c,e.ok?`saved`:`failed`,`${e.model} ${e.ok?`answered`:`did not answer`} in ${e.ms} ms`),d.append(m(`sent`,e.request||`(the request was never made)`),m(e.ok?`answered`:`replied`,e.response))})},_.append(e,r)}if(t.builtin||t.api&&t.models){let n=g(`Edit`);n.onclick=()=>Z(e,t,u),_.append(n)}if(t.stored){let e=g(`Remove credential`);e.onclick=()=>void f(t),_.append(e)}return o(`div`,`border-b border-neutral-100`,o(`div`,`grid grid-cols-[minmax(8rem,1fr)_minmax(8rem,auto)_minmax(9rem,auto)] items-center gap-3 px-4 py-2.5 max-sm:grid-cols-[1fr_auto]`,r,s,_),d)}))};await u()}function le(e,t){let n=t.filter(e=>!e.configured&&e.methods.length&&(e.builtin||e.api!==void 0&&e.models!==void 0)),r=(t,n)=>{if(!n.length)return;let r=document.createElement(`optgroup`);r.label=t,r.append(...n.map(e=>new Option(e.name,e.id))),e.append(r)};r(`Common`,se.flatMap(e=>n.filter(t=>t.id===e))),r(`More providers`,n.filter(e=>e.builtin&&!se.includes(e.id)).sort((e,t)=>e.name.localeCompare(t.name))),r(`Custom providers`,n.filter(e=>!e.builtin).sort((e,t)=>e.name.localeCompare(t.name))),e.append(new Option(`Custom provider…`,X))}function Z(e,n,i){let s=document.createElement(`dialog`);s.className=`m-auto w-[min(32rem,92vw)] rounded-lg border border-neutral-200 bg-white p-0 shadow-xl backdrop:bg-black/30`;let c=document.createElement(`select`);c.className=`${h} select`,n||le(c,e);let l=k(),u=k(),d=k(),f=document.createElement(`select`);f.className=`${h} select`,f.append(...Y.map(([e,t])=>new Option(e,t)));let p=r(``,4);p.placeholder=`model-id
4
4
  another-model-id`;let m=document.createElement(`input`);m.type=`checkbox`;let _=document.createElement(`select`);_.className=`${h} select`;let v=o(`div`,`flex flex-col gap-4`),y=o(`span`,`text-[11.5px] text-red-600`,``),b=g(`Cancel`),x=g(n?`Save`:`Add`,!0);x.type=`submit`;let S=()=>n??e.find(e=>e.id===c.value),C=()=>{let e=S(),t=e?!e.builtin:c.value===X;l.value=e?.id??``,l.disabled=n!==void 0,u.value=e?.name??``,d.value=e?.endpoint??``,f.value=e?.api??`openai-completions`,p.value=e?.models?.map(e=>e.id).join(`
@@ -1,3 +1,3 @@
1
- import{F as e,I as t,U as n,V as r,g as i}from"./index-WrsNstrb.js";var a=e=>e===null?`-`:new Date(e).toLocaleString(),o=t=>t.startedAt===null?`-`:e((t.finishedAt??Date.now())-t.startedAt),s=e=>e.state===`succeeded`&&e.matched===!1?`No match`:e.state,c=e=>e.trigger.type===`manual`?`Manual`:e.trigger.type===`cron`?`${e.trigger.expression} (${e.trigger.timezone})`:`Every ${e.trigger.intervalSeconds}s · ${e.trigger.mode}`,l=e=>e.action.type===`agent`?`Agent · ${e.action.session.mode}`:e.action.type===`bash`?`Bash`:e.action.type===`system`?`System`:`Task`;function u(e,n){let r=t(`div`,`grid max-w-4xl grid-cols-[6rem_minmax(0,1fr)] gap-x-5 gap-y-3 p-4 text-[13px] md:grid-cols-[9.375rem_minmax(0,1fr)]`),o=[[`Status`,e.archived?`Archived`:e.trigger.type===`manual`?`Manual`:e.enabled?`Enabled`:`Paused`],[`Trigger`,c(e)],[`Action`,l(e)],[`Timeout`,`${e.timeoutSeconds}s`],[`Next run`,a(e.nextRunAt)],[`Revision`,String(e.revision)],[`Created by`,e.createdBySessionId??e.creator],[`Callback`,e.callback.type===`session`?e.callback.sessionId:e.callback.type],[`Description`,e.description||`-`]];e.action.type===`agent`&&(o.push([`Session policy`,e.action.session.mode]),e.action.session.mode===`reuse`&&o.push([`Session`,e.action.session.sessionId]),`cwd`in e.action.session&&o.push([`Directory`,e.action.session.cwd]),e.action.launch?.model&&o.push([`Model`,`${e.action.launch.model.provider}/${e.action.launch.model.id}`]),e.action.launch?.thinking&&o.push([`Thinking`,e.action.launch.thinking]),o.push([`Prompt`,e.action.prompt])),e.action.type===`bash`&&o.push([`Directory`,e.action.cwd],[`Script`,e.action.script]),e.action.type===`task`&&o.push([`Target task`,e.action.taskId]),e.action.type===`system`&&o.push([`System action`,e.action.name]),e.trigger.type===`watch`&&o.push([`Probe`,e.trigger.script]);for(let[e,n]of o)r.append(t(`span`,`text-[11px] font-semibold uppercase text-neutral-400`,e),t(`pre`,`whitespace-pre-wrap break-words font-mono text-[12.5px]`,n));if(e.action.type===`agent`&&e.action.session.mode===`reuse`){let{sessionId:a}=e.action.session,o=i(`Open session`);o.onclick=()=>n(a),r.append(t(`span`,``,``),o)}return r}function d(e){return[e.pendingDecisionId?`Awaiting decision`:``,e.callbackState&&e.callbackState!==`delivered`?`Callback not delivered (${e.callbackState})`:``,e.groupCallbackState&&e.groupCallbackState!==`delivered`?`Group callback not delivered (${e.groupCallbackState})`:``].filter(Boolean).join(` · `)}function f(e,n,r,i){let c=t(`div`,`divide-y divide-neutral-100`);for(let e of n){let n=t(`button`,`grid w-full cursor-pointer grid-cols-[minmax(0,1fr)_auto] gap-x-3 gap-y-1 px-4 py-2.5 text-left text-[12.5px] hover:bg-neutral-50 md:grid-cols-[7.5rem_minmax(0,1fr)_7.5rem_6.25rem]`);n.setAttribute(`type`,`button`),n.append(t(`span`,`font-medium`,s(e)),t(`span`,`truncate text-neutral-500`,a(e.queuedAt)),t(`span`,`text-neutral-500`,e.triggerSource),t(`span`,`text-right text-neutral-500`,o(e))),n.onclick=()=>r(e.id),c.append(n)}n.length||c.append(t(`p`,`p-4 text-[13px] text-neutral-400`,`No runs yet.`)),e.replaceChildren(c),e.scrollTop=i.top,e.onscroll=()=>{i.top=e.scrollTop}}var p=e=>`Exit code: ${e.exitCode??`-`}\nstdout:\n${e.stdout}${e.stdoutTruncated?`
1
+ import{F as e,I as t,U as n,V as r,g as i}from"./index-DHxoYoeq.js";var a=e=>e===null?`-`:new Date(e).toLocaleString(),o=t=>t.startedAt===null?`-`:e((t.finishedAt??Date.now())-t.startedAt),s=e=>e.state===`succeeded`&&e.matched===!1?`No match`:e.state,c=e=>e.trigger.type===`manual`?`Manual`:e.trigger.type===`cron`?`${e.trigger.expression} (${e.trigger.timezone})`:`Every ${e.trigger.intervalSeconds}s · ${e.trigger.mode}`,l=e=>e.action.type===`agent`?`Agent · ${e.action.session.mode}`:e.action.type===`bash`?`Bash`:e.action.type===`system`?`System`:`Task`;function u(e,n){let r=t(`div`,`grid max-w-4xl grid-cols-[6rem_minmax(0,1fr)] gap-x-5 gap-y-3 p-4 text-[13px] md:grid-cols-[9.375rem_minmax(0,1fr)]`),o=[[`Status`,e.archived?`Archived`:e.trigger.type===`manual`?`Manual`:e.enabled?`Enabled`:`Paused`],[`Trigger`,c(e)],[`Action`,l(e)],[`Timeout`,`${e.timeoutSeconds}s`],[`Next run`,a(e.nextRunAt)],[`Revision`,String(e.revision)],[`Created by`,e.createdBySessionId??e.creator],[`Callback`,e.callback.type===`session`?e.callback.sessionId:e.callback.type],[`Description`,e.description||`-`]];e.action.type===`agent`&&(o.push([`Session policy`,e.action.session.mode]),e.action.session.mode===`reuse`&&o.push([`Session`,e.action.session.sessionId]),`cwd`in e.action.session&&o.push([`Directory`,e.action.session.cwd]),e.action.launch?.model&&o.push([`Model`,`${e.action.launch.model.provider}/${e.action.launch.model.id}`]),e.action.launch?.thinking&&o.push([`Thinking`,e.action.launch.thinking]),o.push([`Prompt`,e.action.prompt])),e.action.type===`bash`&&o.push([`Directory`,e.action.cwd],[`Script`,e.action.script]),e.action.type===`task`&&o.push([`Target task`,e.action.taskId]),e.action.type===`system`&&o.push([`System action`,e.action.name]),e.trigger.type===`watch`&&o.push([`Probe`,e.trigger.script]);for(let[e,n]of o)r.append(t(`span`,`text-[11px] font-semibold uppercase text-neutral-400`,e),t(`pre`,`whitespace-pre-wrap break-words font-mono text-[12.5px]`,n));if(e.action.type===`agent`&&e.action.session.mode===`reuse`){let{sessionId:a}=e.action.session,o=i(`Open session`);o.onclick=()=>n(a),r.append(t(`span`,``,``),o)}return r}function d(e){return[e.pendingDecisionId?`Awaiting decision`:``,e.callbackState&&e.callbackState!==`delivered`?`Callback not delivered (${e.callbackState})`:``,e.groupCallbackState&&e.groupCallbackState!==`delivered`?`Group callback not delivered (${e.groupCallbackState})`:``].filter(Boolean).join(` · `)}function f(e,n,r,i){let c=t(`div`,`divide-y divide-neutral-100`);for(let e of n){let n=t(`button`,`grid w-full cursor-pointer grid-cols-[minmax(0,1fr)_auto] gap-x-3 gap-y-1 px-4 py-2.5 text-left text-[12.5px] hover:bg-neutral-50 md:grid-cols-[7.5rem_minmax(0,1fr)_7.5rem_6.25rem]`);n.setAttribute(`type`,`button`),n.append(t(`span`,`font-medium`,s(e)),t(`span`,`truncate text-neutral-500`,a(e.queuedAt)),t(`span`,`text-neutral-500`,e.triggerSource),t(`span`,`text-right text-neutral-500`,o(e))),n.onclick=()=>r(e.id),c.append(n)}n.length||c.append(t(`p`,`p-4 text-[13px] text-neutral-400`,`No runs yet.`)),e.replaceChildren(c),e.scrollTop=i.top,e.onscroll=()=>{i.top=e.scrollTop}}var p=e=>`Exit code: ${e.exitCode??`-`}\nstdout:\n${e.stdout}${e.stdoutTruncated?`
2
2
  [stdout truncated]`:``}\nstderr:\n${e.stderr}${e.stderrTruncated?`
3
3
  [stderr truncated]`:``}`;async function m(e,c,l,f,m){let g=String(Number(e.dataset.runRequest??0)+1);e.dataset.runRequest=g,e.onscroll=()=>{m.scrollTop=e.scrollTop};let _=i(`Runs`);_.className=`cursor-pointer text-neutral-500 hover:underline`,_.onclick=()=>{m.selectedId=null,m.scrollTop=0,l()};let v=t(`div`,`flex flex-wrap items-center gap-2 border-b border-neutral-200 px-4 py-2`);v.append(_,t(`span`,`min-w-0 truncate font-mono text-[12px] text-neutral-400`,c));let y=e.dataset.runId!==c;y&&(e.dataset.runId=c,e.replaceChildren(v,t(`p`,`p-4 text-[13px] text-neutral-500`,`Loading run...`)));let[b,x]=await Promise.all([r(`/api/task-runs/${c}`,`Could not load the run`),r(`/api/task-runs/${c}/messages`,`Could not load the run's messages`)]);if(!e.isConnected||e.dataset.runRequest!==g||m.selectedId!==c)return;if(!b.ok){m.drawn=``,e.replaceChildren(v,t(`p`,`p-4 text-[13px] text-red-600`,b.error));return}let S=b.value,C=x.ok?x.value:[],w=JSON.stringify([S,x]);if(!y&&m.drawn===w)return;if(m.drawn=w,S.targetSessionId){let e=i(`Open session`);e.classList.add(`ml-auto`),e.onclick=()=>f.openSession(S.targetSessionId),v.append(e)}if(S.state===`queued`||S.state===`running`){if(S.context.definition.action.type===`agent`){let e=i(`Steer`);e.onclick=()=>void h(n(`Steer run`,`/api/task-runs/${S.id}/steer`,{mode:`steer`,sourceSessionId:f.currentSessionId()},`Run control failed`),f),v.append(e)}let e=i(`Stop run`);e.onclick=()=>void f.mutate(`/api/task-runs/${S.id}/cancel`),v.append(e)}else if(S.context.definition.action.type===`agent`&&S.targetSessionId){let e=i(`Continue`);e.onclick=()=>void h(n(`Continue run`,`/api/task-runs/${S.id}/resume`,{sourceSessionId:f.currentSessionId()},`Run control failed`),f,!0),v.append(e)}let T=C.find(e=>e.id===S.pendingDecisionId);if(T&&T.toSessionId===f.currentSessionId()){let e=i(`Reply to decision`);e.onclick=()=>void h(n(`Reply to decision`,`/api/task-messages/${T.id}/reply`,{sourceSessionId:f.currentSessionId()},`Reply failed`),f),v.append(e)}let E=t(`div`,`min-w-0`);E.append(t(`div`,`flex flex-wrap items-center gap-x-5 gap-y-2 border-b border-neutral-100 px-4 py-3 text-[12.5px]`,t(`span`,`font-medium`,s(S)),t(`span`,`text-amber-700`,d(S)),t(`span`,`text-neutral-500`,a(S.queuedAt)),t(`span`,`text-neutral-500`,S.triggerSource),t(`span`,`text-neutral-500`,o(S))));let D=t(`div`,`flex flex-wrap items-center gap-3 border-b border-neutral-100 px-4 py-3 text-[12px]`),O=(e,t)=>{let n=i(e);n.classList.add(`max-w-full`,`break-all`,`!whitespace-normal`),n.onclick=t,D.append(n)};if(S.context.definition.kind===`task`&&O(`Task: ${S.context.definition.name}`,()=>f.openTask(S.taskId)),S.parentRunId&&O(`Parent: ${S.parentRunId}`,()=>f.openRun(S.parentRunId)),S.resumedFromRunId&&O(`Resumed from: ${S.resumedFromRunId}`,()=>f.openRun(S.resumedFromRunId)),S.result?.type===`task`){let e=S.result.runId;O(`Child result: ${e}`,()=>f.openRun(e))}S.groupId&&D.append(t(`span`,`break-all text-neutral-500`,`Group: ${S.groupId}`)),E.append(D);for(let e of[S.error,S.skipReason,S.callbackError])e&&E.append(t(`p`,`whitespace-pre-wrap break-words p-4 text-[13px] text-red-600`,e));if(S.result){let e=S.result,n=e.type===`agent`||e.type===`system`?e.text:e.type===`bash`?p(e):e.type===`task`?`Child run: ${e.runId}`:`Watch did not match.`;E.append(t(`h3`,`px-4 pt-3 text-[12px] font-medium`,`Result`),t(`pre`,`whitespace-pre-wrap break-words p-4 font-mono text-[12px]`,n||`No output.`))}S.probe&&E.append(t(`h3`,`px-4 pt-3 text-[12px] font-medium`,`Watch probe: ${S.matched===null?`not evaluated`:S.matched?`matched`:`not matched`}`),t(`pre`,`whitespace-pre-wrap break-words p-4 font-mono text-[12px]`,p(S.probe)));let k=t(`details`,`border-t border-neutral-200`);if(k.append(t(`summary`,`cursor-pointer px-4 py-3 text-[12px] text-neutral-500`,`Configuration snapshot (revision ${S.taskRevision})`),u(S.context.definition,f.openSession)),E.append(k),x.ok||E.append(t(`p`,`p-4 text-[13px] text-red-600`,x.error)),C.length){let e=t(`div`,`border-t border-neutral-200`);e.append(t(`div`,`px-4 py-2 text-[11px] font-semibold uppercase text-neutral-400`,`Messages`));for(let n of C){let r=t(`div`,`grid grid-cols-[auto_1fr] gap-3 border-t border-neutral-100 px-4 py-2 text-[12px] md:grid-cols-[6.25rem_6.25rem_minmax(0,1fr)]`);r.append(t(`span`,`font-medium`,n.kind),t(`span`,`text-neutral-500`,n.state),t(`span`,`col-span-2 whitespace-pre-wrap break-words md:col-span-1`,n.content)),n.error&&r.append(t(`span`,`col-span-2 break-words text-red-600 md:col-span-3`,n.error)),e.append(r)}E.append(e)}let A=t(`details`,`border-t border-neutral-200`);A.open=m.rawOpen,A.ontoggle=()=>{A.isConnected&&(m.rawOpen=A.open)},A.append(t(`summary`,`cursor-pointer px-4 py-3 text-[12px] text-neutral-500`,`Raw record`),t(`pre`,`whitespace-pre-wrap break-words px-4 pb-4 font-mono text-[12px]`,JSON.stringify(S,null,2))),E.append(A),e.replaceChildren(v,E),e.scrollTop=m.scrollTop,e.onscroll=()=>{m.scrollTop=e.scrollTop}}async function h(e,t,n=!1){let r=await e;if(r.sent){if(r.error)t.onError(r.error);else if(n&&r.response)try{let e=await r.response.json();t.openRun(e.id)}catch(e){t.onError(`Could not open continuation: ${String(e)}`)}else await t.reload()}}export{f as a,s as c,m as i,c as l,a as n,d as o,u as r,o as s,l as t};
@@ -1,4 +1,4 @@
1
- import{B as e,C as t,D as n,G as r,I as i,M as a,T as o,V as s,W as c,g as l,x as u,y as d,z as f}from"./index-WrsNstrb.js";import{a as p,c as m,l as h,n as g,r as _,s as v,t as y}from"./task-runs-CpgHxFLf.js";function b(e,t){let n=e.map(e=>[`${e.title??`Untitled`} · ${e.cwd}`,e.id]);return t&&!n.some(([,e])=>e===t)&&n.push([`Current session · ${t}`,t]),n}function x(e,r){let a=document.createElement(`dialog`);a.className=`m-auto w-[38.75rem] max-w-[94vw] rounded-lg border border-neutral-200 p-0 shadow-xl backdrop:bg-black/20`;let o=document.createElement(`form`);o.className=`flex max-h-[88vh] flex-col`;let s=i(`span`,`mr-auto text-[12px] text-red-600`),c=i(`header`,`flex h-11 flex-none items-center border-b border-neutral-200 px-4 font-medium`,r?`Edit task`:`New task`),f=i(`div`,`grid min-h-0 flex-1 grid-cols-2 gap-3 overflow-y-auto p-4`),p=u(r?.name??``);p.required=!0;let m=u(r?.description??``),h=u(String(r?.timeoutSeconds??900),`number`);h.min=`1`,h.max=`86400`;let g=t([[`Manual`,`manual`],[`Scheduled`,`cron`],[`Watch`,`watch`]],r?.trigger.type??`manual`),_=t([[`Bash`,`bash`],[`Agent`,`agent`],[`Task`,`task`]],r?.action.type??`bash`),v=t([[`No callback`,`none`],[`Invoking session`,`origin`],[`Specific session`,`session`]],r?.callback.type??`none`),y=r?.callback.type===`session`?r.callback.sessionId:null,x=t(b(e.sessions(),y),y??``),C=d(`Callback session`,x);C.classList.toggle(`hidden`,v.value!==`session`),v.onchange=()=>C.classList.toggle(`hidden`,v.value!==`session`),f.append(d(`Name`,p),d(`Description`,m),d(`Trigger`,g),d(`Action`,_),d(`Callback`,v),C,d(`Timeout (seconds)`,h));let w=i(`div`,`col-span-2 grid grid-cols-2 gap-3 border-t border-neutral-200 pt-3`);f.append(w);let T=()=>{w.replaceChildren();let c,l,f,y,C,T;if(g.value===`cron`)c=u(r?.trigger.type===`cron`?r.trigger.expression:`0 9 * * *`),l=u(r?.trigger.type===`cron`?r.trigger.timezone:Intl.DateTimeFormat().resolvedOptions().timeZone),w.append(d(`Cron`,c),d(`Timezone`,l));else if(g.value===`watch`){f=n(r?.trigger.type===`watch`?r.trigger.script:``,4),T=u(r?.trigger.type===`watch`?r.trigger.cwd:e.sessions()[0]?.cwd??``),y=u(String(r?.trigger.type===`watch`?r.trigger.intervalSeconds:60),`number`),C=t([[`Continue after matches`,`repeat`],[`Stop after first match`,`once`]],r?.trigger.type===`watch`?r.trigger.mode:`repeat`);let i=d(`Probe script (0=match, 1=no match)`,f);i.classList.add(`col-span-2`),w.append(i,d(`Probe directory`,T),d(`Interval (seconds)`,y),d(`Mode`,C))}let E,D,O,k,A,j,M,N,P,F;if(_.value===`bash`){D=u(r?.action.type===`bash`?r.action.cwd:e.sessions()[0]?.cwd??``),E=n(r?.action.type===`bash`?r.action.script:``,6);let t=d(`Bash script`,E);t.classList.add(`col-span-2`),w.append(d(`Working directory`,D),i(`span`,``),t)}else if(_.value===`agent`){let i=e.sessions(),a=r?.action.type===`agent`?r.action:null,o=a?.session.mode===`reuse`?a.session.sessionId:``,s=b(i,o||null);O=t([[`Reuse session`,`reuse`],[`Fresh child per run`,`fresh`]],a?.session.mode===`reuse`?`reuse`:`fresh`),k=t(s,o||s[0]?.[1]||``);let c=a&&`cwd`in a.session?a.session.cwd??``:``;A=u(c||i[0]?.cwd||``),j=n(a?.prompt??``,6),M=t([[`Project default`,``],[`Off`,`off`],[`Low`,`low`],[`Medium`,`medium`],[`High`,`high`],[`Extra high`,`xhigh`]],a?.launch?.thinking??``),N=u(a?.launch?.model?.provider??``),P=u(a?.launch?.model?.id??``);let l=d(`Session`,k),f=d(`Child directory`,A),p=[d(`Thinking`,M),d(`Model provider (optional)`,N),d(`Model id (optional)`,P)],m=()=>{let e=O?.value===`reuse`;l.classList.toggle(`hidden`,!e),f.classList.toggle(`hidden`,e);for(let t of p)t.classList.toggle(`hidden`,e)};O.onchange=m,m();let h=d(`Prompt`,j);h.classList.add(`col-span-2`),w.append(d(`Session policy`,O),l,f,...p,h)}else F=t(e.tasks().filter(e=>e.id!==r?.id&&!e.archived).map(e=>[e.name,e.id]),r?.action.type===`task`?r.action.taskId:``),w.append(d(`Target task`,F));o.onsubmit=t=>{t.preventDefault();let n=g.value===`manual`?{type:`manual`}:g.value===`cron`?{type:`cron`,expression:c.value,timezone:l.value}:{type:`watch`,script:f.value,cwd:T.value,intervalSeconds:Number(y.value),mode:C.value},i=_.value===`agent`&&O.value!==`reuse`?{...M.value?{thinking:M.value}:{},...N.value.trim()&&P.value.trim()?{model:{provider:N.value.trim(),id:P.value.trim()}}:{}}:void 0,o=_.value===`bash`?{type:`bash`,cwd:D.value,script:E.value}:_.value===`agent`?{type:`agent`,prompt:j.value,session:O.value===`reuse`?{mode:`reuse`,sessionId:k.value}:{mode:`fresh`,cwd:A.value},...i?{launch:i}:{}}:{type:`task`,taskId:F.value},u=v.value===`origin`?{type:`origin`}:v.value===`session`?{type:`session`,sessionId:x.value}:{type:`none`},d={name:p.value,description:m.value,trigger:n,action:o,callback:u,timeoutSeconds:Number(h.value)};s.textContent=``,S(r?.id,d,a,s,e.onSaved)}};g.onchange=T,_.onchange=T,T();let E=l(`Cancel`);E.onclick=()=>a.close();let D=l(`Save`,!0);D.type=`submit`;let O=i(`footer`,`flex flex-none justify-end gap-2 border-t border-neutral-200 px-4 py-3`);O.append(s,E,D),o.append(c,f,O),a.append(o),a.addEventListener(`close`,()=>a.remove()),document.body.append(a),a.showModal(),p.focus()}async function S(e,t,n,i,a){let o=await r(e?`/api/tasks/${e}`:`/api/tasks`,t,e?`PATCH`:`POST`);if(!o.ok){i.textContent=(await o.json()).error??`Task save failed`;return}let s=await o.json(),c=`task`in s?s.task:s;n.close(),a(c.id)}function C(n,u,d,b,S,C,w){let T=[],E=[],D=null,O=`active`,k=`all`,A=``,j=`runs`,M={top:0},N=0,P=0,F=``,I=f(async()=>{let e=`${O}:${k}`,t=await s(`/api/tasks?state=${O}&kind=task`,`Failed to load tasks`);if(!t.ok)return F=``,L(t.error);if(e!==`${O}:${k}`)return;let n=JSON.stringify(t.value);e+n===F&&!D||(F=e+n,T=t.value,E=O===`archived`?await R():T,e===`${O}:${k}`&&(k!==`all`&&(T=T.filter(e=>e.trigger.type===k)),D?await G(D):U()))});function L(e){n.querySelector(`[role=alert]`)?.remove();let t=i(`p`,`flex-none p-4 text-[13px] text-red-600`,e);t.setAttribute(`role`,`alert`),n.append(t)}async function R(){let e=await s(`/api/tasks?state=active`,`Failed to load tasks`);return e.ok?e.value:E}let z={sessions:u,tasks:()=>E,onSaved:e=>{V(e),j=`definition`,w(e)}};function B(e,t){let n=i(`header`,`flex min-h-10 flex-none flex-wrap items-center gap-2 border-b border-neutral-200 px-4 py-2`);if(n.append(typeof e==`string`?i(`span`,`truncate font-medium max-md:hidden`,e):e),t.length){let e=i(`div`,`ml-auto flex flex-wrap items-center gap-2 max-md:w-full`);e.append(...t),n.append(e)}return n}function V(e){D=e,j=`runs`,M.top=0}function H(){D=null,N++,U()}function U(){let e=l(`New task`,!0);e.onclick=()=>void d().then(()=>x(z));let r=i(`div`,`flex flex-none flex-wrap items-center gap-3 border-b border-neutral-200 px-4 py-2`),a=(e,n,a,o)=>{let s=t(n,a);s.setAttribute(`aria-label`,e),s.classList.add(`!w-auto`,`pr-8`),s.onchange=()=>{o(s.value),P=0,I()},r.append(i(`label`,`flex items-center gap-2 text-[12px] text-neutral-500`,e,s))};a(`Status`,[[`Current`,`active`],[`Archived`,`archived`]],O,e=>{O=e});let o=i(`input`,`min-w-0 rounded border border-neutral-200 px-2 py-1 text-[13px]`);o.type=`search`,o.placeholder=`Search tasks`,o.setAttribute(`aria-label`,`Search tasks`),o.value=A,o.oninput=()=>{A=o.value,u()},r.append(o),a(`Trigger`,[[`All triggers`,`all`],[`Manual`,`manual`],[`Scheduled`,`cron`],[`Watching`,`watch`]],k,e=>{k=e});let s=document.createElement(`table`);s.className=`w-full table-fixed text-left text-[12.5px]`,s.innerHTML=`<thead class="sticky top-0 bg-neutral-50 text-[10.5px] uppercase text-neutral-400"><tr>
1
+ import{B as e,C as t,D as n,G as r,I as i,M as a,T as o,V as s,W as c,g as l,x as u,y as d,z as f}from"./index-DHxoYoeq.js";import{a as p,c as m,l as h,n as g,r as _,s as v,t as y}from"./task-runs-DKvtBVxS.js";function b(e,t){let n=e.map(e=>[`${e.title??`Untitled`} · ${e.cwd}`,e.id]);return t&&!n.some(([,e])=>e===t)&&n.push([`Current session · ${t}`,t]),n}function x(e,r){let a=document.createElement(`dialog`);a.className=`m-auto w-[38.75rem] max-w-[94vw] rounded-lg border border-neutral-200 p-0 shadow-xl backdrop:bg-black/20`;let o=document.createElement(`form`);o.className=`flex max-h-[88vh] flex-col`;let s=i(`span`,`mr-auto text-[12px] text-red-600`),c=i(`header`,`flex h-11 flex-none items-center border-b border-neutral-200 px-4 font-medium`,r?`Edit task`:`New task`),f=i(`div`,`grid min-h-0 flex-1 grid-cols-2 gap-3 overflow-y-auto p-4`),p=u(r?.name??``);p.required=!0;let m=u(r?.description??``),h=u(String(r?.timeoutSeconds??900),`number`);h.min=`1`,h.max=`86400`;let g=t([[`Manual`,`manual`],[`Scheduled`,`cron`],[`Watch`,`watch`]],r?.trigger.type??`manual`),_=t([[`Bash`,`bash`],[`Agent`,`agent`],[`Task`,`task`]],r?.action.type??`bash`),v=t([[`No callback`,`none`],[`Invoking session`,`origin`],[`Specific session`,`session`]],r?.callback.type??`none`),y=r?.callback.type===`session`?r.callback.sessionId:null,x=t(b(e.sessions(),y),y??``),C=d(`Callback session`,x);C.classList.toggle(`hidden`,v.value!==`session`),v.onchange=()=>C.classList.toggle(`hidden`,v.value!==`session`),f.append(d(`Name`,p),d(`Description`,m),d(`Trigger`,g),d(`Action`,_),d(`Callback`,v),C,d(`Timeout (seconds)`,h));let w=i(`div`,`col-span-2 grid grid-cols-2 gap-3 border-t border-neutral-200 pt-3`);f.append(w);let T=()=>{w.replaceChildren();let c,l,f,y,C,T;if(g.value===`cron`)c=u(r?.trigger.type===`cron`?r.trigger.expression:`0 9 * * *`),l=u(r?.trigger.type===`cron`?r.trigger.timezone:Intl.DateTimeFormat().resolvedOptions().timeZone),w.append(d(`Cron`,c),d(`Timezone`,l));else if(g.value===`watch`){f=n(r?.trigger.type===`watch`?r.trigger.script:``,4),T=u(r?.trigger.type===`watch`?r.trigger.cwd:e.sessions()[0]?.cwd??``),y=u(String(r?.trigger.type===`watch`?r.trigger.intervalSeconds:60),`number`),C=t([[`Continue after matches`,`repeat`],[`Stop after first match`,`once`]],r?.trigger.type===`watch`?r.trigger.mode:`repeat`);let i=d(`Probe script (0=match, 1=no match)`,f);i.classList.add(`col-span-2`),w.append(i,d(`Probe directory`,T),d(`Interval (seconds)`,y),d(`Mode`,C))}let E,D,O,k,A,j,M,N,P,F;if(_.value===`bash`){D=u(r?.action.type===`bash`?r.action.cwd:e.sessions()[0]?.cwd??``),E=n(r?.action.type===`bash`?r.action.script:``,6);let t=d(`Bash script`,E);t.classList.add(`col-span-2`),w.append(d(`Working directory`,D),i(`span`,``),t)}else if(_.value===`agent`){let i=e.sessions(),a=r?.action.type===`agent`?r.action:null,o=a?.session.mode===`reuse`?a.session.sessionId:``,s=b(i,o||null);O=t([[`Reuse session`,`reuse`],[`Fresh child per run`,`fresh`]],a?.session.mode===`reuse`?`reuse`:`fresh`),k=t(s,o||s[0]?.[1]||``);let c=a&&`cwd`in a.session?a.session.cwd??``:``;A=u(c||i[0]?.cwd||``),j=n(a?.prompt??``,6),M=t([[`Project default`,``],[`Off`,`off`],[`Low`,`low`],[`Medium`,`medium`],[`High`,`high`],[`Extra high`,`xhigh`]],a?.launch?.thinking??``),N=u(a?.launch?.model?.provider??``),P=u(a?.launch?.model?.id??``);let l=d(`Session`,k),f=d(`Child directory`,A),p=[d(`Thinking`,M),d(`Model provider (optional)`,N),d(`Model id (optional)`,P)],m=()=>{let e=O?.value===`reuse`;l.classList.toggle(`hidden`,!e),f.classList.toggle(`hidden`,e);for(let t of p)t.classList.toggle(`hidden`,e)};O.onchange=m,m();let h=d(`Prompt`,j);h.classList.add(`col-span-2`),w.append(d(`Session policy`,O),l,f,...p,h)}else F=t(e.tasks().filter(e=>e.id!==r?.id&&!e.archived).map(e=>[e.name,e.id]),r?.action.type===`task`?r.action.taskId:``),w.append(d(`Target task`,F));o.onsubmit=t=>{t.preventDefault();let n=g.value===`manual`?{type:`manual`}:g.value===`cron`?{type:`cron`,expression:c.value,timezone:l.value}:{type:`watch`,script:f.value,cwd:T.value,intervalSeconds:Number(y.value),mode:C.value},i=_.value===`agent`&&O.value!==`reuse`?{...M.value?{thinking:M.value}:{},...N.value.trim()&&P.value.trim()?{model:{provider:N.value.trim(),id:P.value.trim()}}:{}}:void 0,o=_.value===`bash`?{type:`bash`,cwd:D.value,script:E.value}:_.value===`agent`?{type:`agent`,prompt:j.value,session:O.value===`reuse`?{mode:`reuse`,sessionId:k.value}:{mode:`fresh`,cwd:A.value},...i?{launch:i}:{}}:{type:`task`,taskId:F.value},u=v.value===`origin`?{type:`origin`}:v.value===`session`?{type:`session`,sessionId:x.value}:{type:`none`},d={name:p.value,description:m.value,trigger:n,action:o,callback:u,timeoutSeconds:Number(h.value)};s.textContent=``,S(r?.id,d,a,s,e.onSaved)}};g.onchange=T,_.onchange=T,T();let E=l(`Cancel`);E.onclick=()=>a.close();let D=l(`Save`,!0);D.type=`submit`;let O=i(`footer`,`flex flex-none justify-end gap-2 border-t border-neutral-200 px-4 py-3`);O.append(s,E,D),o.append(c,f,O),a.append(o),a.addEventListener(`close`,()=>a.remove()),document.body.append(a),a.showModal(),p.focus()}async function S(e,t,n,i,a){let o=await r(e?`/api/tasks/${e}`:`/api/tasks`,t,e?`PATCH`:`POST`);if(!o.ok){i.textContent=(await o.json()).error??`Task save failed`;return}let s=await o.json(),c=`task`in s?s.task:s;n.close(),a(c.id)}function C(n,u,d,b,S,C,w){let T=[],E=[],D=null,O=`active`,k=`all`,A=``,j=`runs`,M={top:0},N=0,P=0,F=``,I=f(async()=>{let e=`${O}:${k}`,t=await s(`/api/tasks?state=${O}&kind=task`,`Failed to load tasks`);if(!t.ok)return F=``,L(t.error);if(e!==`${O}:${k}`)return;let n=JSON.stringify(t.value);e+n===F&&!D||(F=e+n,T=t.value,E=O===`archived`?await R():T,e===`${O}:${k}`&&(k!==`all`&&(T=T.filter(e=>e.trigger.type===k)),D?await G(D):U()))});function L(e){n.querySelector(`[role=alert]`)?.remove();let t=i(`p`,`flex-none p-4 text-[13px] text-red-600`,e);t.setAttribute(`role`,`alert`),n.append(t)}async function R(){let e=await s(`/api/tasks?state=active`,`Failed to load tasks`);return e.ok?e.value:E}let z={sessions:u,tasks:()=>E,onSaved:e=>{V(e),j=`definition`,w(e)}};function B(e,t){let n=i(`header`,`flex min-h-10 flex-none flex-wrap items-center gap-2 border-b border-neutral-200 px-4 py-2`);if(n.append(typeof e==`string`?i(`span`,`truncate font-medium max-md:hidden`,e):e),t.length){let e=i(`div`,`ml-auto flex flex-wrap items-center gap-2 max-md:w-full`);e.append(...t),n.append(e)}return n}function V(e){D=e,j=`runs`,M.top=0}function H(){D=null,N++,U()}function U(){let e=l(`New task`,!0);e.onclick=()=>void d().then(()=>x(z));let r=i(`div`,`flex flex-none flex-wrap items-center gap-3 border-b border-neutral-200 px-4 py-2`),a=(e,n,a,o)=>{let s=t(n,a);s.setAttribute(`aria-label`,e),s.classList.add(`!w-auto`,`pr-8`),s.onchange=()=>{o(s.value),P=0,I()},r.append(i(`label`,`flex items-center gap-2 text-[12px] text-neutral-500`,e,s))};a(`Status`,[[`Current`,`active`],[`Archived`,`archived`]],O,e=>{O=e});let o=i(`input`,`min-w-0 rounded border border-neutral-200 px-2 py-1 text-[13px]`);o.type=`search`,o.placeholder=`Search tasks`,o.setAttribute(`aria-label`,`Search tasks`),o.value=A,o.oninput=()=>{A=o.value,u()},r.append(o),a(`Trigger`,[[`All triggers`,`all`],[`Manual`,`manual`],[`Scheduled`,`cron`],[`Watching`,`watch`]],k,e=>{k=e});let s=document.createElement(`table`);s.className=`w-full table-fixed text-left text-[12.5px]`,s.innerHTML=`<thead class="sticky top-0 bg-neutral-50 text-[10.5px] uppercase text-neutral-400"><tr>
2
2
  <th class="w-[42%] px-4 py-2 font-semibold md:w-[24%]">Name</th><th class="hidden w-[10%] px-2 py-2 font-semibold md:table-cell">Action</th>
3
3
  <th class="hidden w-[23%] px-2 py-2 font-semibold md:table-cell">Trigger</th><th class="hidden w-[17%] px-2 py-2 font-semibold md:table-cell">Next</th>
4
4
  <th class="px-2 py-2 font-semibold md:w-[14%]">Last result</th><th class="w-[6rem] px-2 py-2 font-semibold"></th></tr></thead>`;let c=document.createElement(`tbody`),u=()=>{let e=T.filter(e=>`${e.name} ${e.description??``}`.toLowerCase().includes(A.toLowerCase()));c.replaceChildren(...e.map(W)),f.classList.toggle(`hidden`,e.length>0)};s.append(c);let f=i(`p`,`p-4 text-[13px] text-neutral-500`,`No matching tasks.`),p=i(`div`,`min-h-0 flex-1 overflow-auto`,s,f);u(),p.onscroll=()=>{P=p.scrollTop},n.replaceChildren(B(`Tasks`,[e]),r,p),p.scrollTop=P}function W(e){let t=document.createElement(`tr`);t.className=`cursor-pointer border-b border-neutral-100 hover:bg-neutral-50`,t.onclick=()=>w(e.id);let n=e.archived?`Archived`:e.trigger.type===`manual`?`Manual`:e.enabled?`Enabled`:`Paused`,r=l(e.name);r.className=`block w-full cursor-pointer truncate text-left font-medium`,r.title=e.name,t.append(i(`td`,`truncate py-2.5 pl-4 pr-2`,r,i(`div`,`truncate text-[11px] text-neutral-400`,n),i(`div`,`truncate text-[11px] text-neutral-400 md:hidden`,h(e))));for(let n of[y(e),h(e),g(e.nextRunAt)]){let e=i(`td`,`hidden truncate px-2 py-2.5 md:table-cell`,n);e.title=n,t.append(e)}t.append(i(`td`,`px-2 py-2.5`,i(`div`,`break-words`,e.lastRun?m(e.lastRun):`-`),i(`div`,`text-[11px] text-neutral-400`,e.lastRun?v(e.lastRun):``)));let a=l(`Run now`);return a.disabled=e.archived,a.onclick=t=>{t.stopPropagation(),K(e.id)},t.append(i(`td`,`px-2 py-1 text-right`,a)),t}async function G(e){let t=++N,r=n.querySelector(`[data-task-detail]`),[a,c]=await Promise.all([s(`/api/tasks/${e}`,`Failed to load task`),s(`/api/tasks/${e}/runs`,`Failed to load the task's runs`)]);if(t!==N||D!==e)return;if(!a.ok)return L(a.error);if(!c.ok)return L(c.error);let u=a.value,f=c.value,m=l(`Tasks`);m.className=`cursor-pointer text-neutral-500 hover:underline`,m.onclick=()=>w();let h=i(`span`,`flex min-w-0 items-center gap-1.5`,m,i(`span`,`text-neutral-400`,`›`),i(`span`,`truncate font-medium`,u.name)),g=l(`Run now`,!0);g.disabled=u.archived,g.onclick=()=>void K(u.id);let v=l(u.enabled?`Pause schedule`:`Resume schedule`);v.disabled=u.archived||u.action.type===`system`||u.trigger.type===`manual`,v.onclick=()=>void q(`/api/tasks/${u.id}/${u.enabled?`pause`:`resume`}`);let y=l(`Edit`);y.disabled=u.archived||u.action.type===`system`,y.onclick=()=>void d().then(()=>x(z,u));let S=l(`Archive`);S.disabled=u.archived||u.action.type===`system`,S.onclick=()=>void q(`/api/tasks/${u.id}/archive`);let T=i(`div`,`flex flex-none gap-1 border-b border-neutral-200 px-4 py-2`),E=i(`div`,`min-h-0 flex-1 overflow-auto`);E.dataset.taskDetail=e;let O=()=>{T.replaceChildren(o(`Recent runs (${f.length})`,j===`runs`,()=>{j=`runs`,O()}),o(`Definition`,j===`definition`,()=>{j=`definition`,O()})),j===`runs`?p(E,f,e=>C({},e),M):(E.onscroll=null,E.replaceChildren(_(u,b)))},k=r?.scrollTop??0,A=l(`All runs`);A.onclick=()=>C({taskId:u.id}),n.replaceChildren(B(h,[g,...u.trigger.type===`manual`?[]:[v],y,S,A]),T,E),O(),E.scrollTop=k}async function K(t){try{let n=await r(`/api/tasks/${t}/run`,{sourceSessionId:S()});if(!n.ok)return L(await e(n,`Failed to run task`));C({},(await n.json()).runId)}catch(e){L(`Failed to run task: ${String(e)}`)}}async function q(e){let t=await c(e,`POST`,`Task update failed`);if(t)return L(t);await I()}let J=a(n,e=>{e&&e!==D&&V(e),e||H(),n.childElementCount||U(),I()});return Object.assign(J,{refresh(e){J.visible&&(!D||!e||D===e)&&I()}})}export{C as createTasksView};
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ghostty-web-Bvhh3ZFk.js","assets/index-WrsNstrb.js","assets/index-DuZ2vERd.css"])))=>i.map(i=>d[i]);
2
- import{B as e,G as t,H as n,I as r,M as i,a,d as o,i as s,n as c,w as l}from"./index-WrsNstrb.js";var u=`pier.terminalPrefs`,d={fontFamily:`monospace`,fontSize:14,cursorBlink:!0},f=()=>{try{let e=JSON.parse(localStorage.getItem(u)??`null`),t=typeof e?.fontSize==`number`?e.fontSize:d.fontSize;return{fontFamily:typeof e?.fontFamily==`string`&&e.fontFamily.trim()?e.fontFamily.slice(0,200):d.fontFamily,fontSize:Math.round(Math.max(10,Math.min(24,t))),cursorBlink:typeof e?.cursorBlink==`boolean`?e.cursorBlink:d.cursorBlink}}catch{return{...d}}},p=e=>localStorage.setItem(u,JSON.stringify(e)),m=null,h=()=>(m||=o(()=>import(`./ghostty-web-Bvhh3ZFk.js`).then(async e=>(await e.init(),e)),__vite__mapDeps([0,1,2])).catch(e=>{throw m=null,e}),m),g=()=>{let e=()=>void h().catch(e=>{console.warn(`terminal: emulator warm-up failed`,e)});`requestIdleCallback`in window?requestIdleCallback(e,{timeout:1e4}):setTimeout(e,3e3)},_={background:`#1a1b26`,foreground:`#a9b1d6`,cursor:`#c0caf5`};function v(e){let t=e.renderer,n=document.createElement(`canvas`).getContext(`2d`);if(!n||typeof t?.remeasureFont!=`function`){console.warn(`terminal: could not correct cell metrics — rows will render tight`);return}t.measureFont=()=>{let{fontSize:t,fontFamily:r}=e.options;n.font=`${t}px ${r}`;let i=n.measureText(`M`),a=i.fontBoundingBoxAscent||i.actualBoundingBoxAscent||t*.8,o=i.fontBoundingBoxDescent||i.actualBoundingBoxDescent||t*.25;return{width:Math.ceil(i.width),height:Math.ceil(a+o),baseline:Math.ceil(a)}},t.remeasureFont()}var y=`w-full rounded border border-neutral-300 px-2 py-1.5 font-mono text-[12px] outline-none focus:border-indigo-400`;function b(o,u,m,b,x,S){g();let C=``,w=null,T=null,E=null,D=!1,O=0,k=!1,A=f(),j=r(`div`,`ml-auto flex min-w-0 flex-none items-center gap-2`),M=r(`header`,`flex h-10 flex-none items-center gap-2 border-b border-neutral-200 bg-white px-3`),N=r(`div`,`min-h-0 flex-1 overflow-hidden p-1`);N.style.background=_.background,N.setAttribute(`data-owns-keyboard`,``),N.addEventListener(`keydown`,e=>{e.metaKey&&!e.defaultPrevented&&e.stopImmediatePropagation()},!0),N.addEventListener(`scroll`,()=>{N.scrollTop=0,N.scrollLeft=0}),N.addEventListener(`compositionend`,()=>{for(let e=N.childNodes.length-1;e>=0;e--){let t=N.childNodes[e];t&&t.nodeName!==`CANVAS`&&t.nodeName!==`TEXTAREA`&&t.remove()}}),o.append(M,N);let P=e=>{let t=r(`button`,`min-w-0 max-w-72 cursor-pointer truncate rounded-md bg-neutral-100 px-2 py-0.5 text-left font-mono text-[11.5px] text-neutral-600 hover:bg-neutral-200`,e);return t.type=`button`,t};function F(e,t){if(j.replaceChildren(),e&&j.append(r(`span`,`min-w-0 truncate text-[11.5px] text-neutral-400`,e)),t){let e=P(t.label);e.className=e.className.replace(`bg-neutral-100`,`bg-indigo-50 font-medium text-indigo-700 hover:bg-indigo-100`),e.onclick=t.run,j.append(e)}}function I(){w&&(w.options.fontFamily=A.fontFamily,w.options.fontSize=A.fontSize,w.options.cursorBlink=A.cursorBlink,requestAnimationFrame(H))}function L(){let i=document.createElement(`input`);i.type=`text`,i.placeholder=`tmux new -As "$(basename $PWD)"`,i.spellcheck=!1,i.autocomplete=`off`,i.autocapitalize=`off`,i.disabled=!0,i.className=`${y} disabled:bg-neutral-50`;let a=r(`span`,`block text-[11.5px] text-neutral-400`,`loading…`),o=(e,t)=>{a.isConnected?l(a,e,t):e===`failed`&&F(t)},s=``;(async()=>{try{s=(await n(`/api/settings`,`Could not load the startup command`)).terminalInitCommand??``,i.value=s,i.disabled=!1,o(`idle`,`Runs when a shell starts — Restart applies it here.`)}catch(e){o(`failed`,String(e))}})();let c=async()=>{let n=i.value.trim();if(!(i.disabled||n===s)){o(`saving`,`saving…`);try{let r=await t(`/api/settings`,{terminalInitCommand:n},`PUT`);if(!r.ok)return o(`failed`,await e(r,`Could not save the startup command`));s=(await r.json()).terminalInitCommand,i.value=s,o(`saved`,s?`Saved — the next shell runs it.`:`Cleared.`)}catch(e){o(`failed`,`Could not save the startup command: ${String(e)}`)}}};return i.onblur=()=>void c(),i.onkeydown=e=>{e.key===`Enter`&&c()},r(`div`,`space-y-1.5 border-t border-neutral-200 pt-2.5`,r(`div`,``,r(`span`,`text-[12px] font-semibold text-neutral-700`,`Startup command`),r(`span`,`block text-[11px] text-neutral-400`,`This Pier, every shell — not only this browser.`)),i,a)}function R(e){let t=document.createElement(`input`);t.type=`text`,t.value=A.fontFamily,t.setAttribute(`list`,`terminal-font-presets`),t.className=y;let n=document.createElement(`datalist`);n.id=`terminal-font-presets`;for(let e of[`monospace`,`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`,`JetBrains Mono, monospace`,`Cascadia Mono, monospace`,`Fira Code, monospace`]){let t=document.createElement(`option`);t.value=e,n.append(t)}let i=document.createElement(`input`);i.type=`number`,i.min=`10`,i.max=`24`,i.step=`1`,i.value=String(A.fontSize),i.className=`w-20 rounded border border-neutral-300 px-2 py-1.5 text-[12px] outline-none focus:border-indigo-400`;let o=document.createElement(`input`);o.type=`checkbox`,o.checked=A.cursorBlink,o.className=`h-4 w-4 accent-indigo-600`;let s=()=>{let e=t.value.trim(),n=Number(i.value);!e||!Number.isFinite(n)||(A={fontFamily:e.slice(0,200),fontSize:Math.round(Math.max(10,Math.min(24,n))),cursorBlink:o.checked},i.value=String(A.fontSize),p(A),I())};t.oninput=s,i.oninput=s,o.onchange=s;let c=r(`button`,`cursor-pointer text-[12px] text-neutral-500 hover:text-indigo-700`,`Reset`);c.type=`button`,c.onclick=()=>{A={...d},t.value=A.fontFamily,i.value=String(A.fontSize),o.checked=A.cursorBlink,p(A),I()},a(e,r(`div`,`w-72 space-y-3 px-3 py-2.5`,r(`div`,`flex items-center`,r(`span`,`text-[12px] font-semibold text-neutral-700`,`Terminal`),r(`span`,`ml-auto`,c)),r(`label`,`block space-y-1 text-[11.5px] text-neutral-500`,r(`span`,``,`Font family`),t,n),r(`label`,`flex items-center justify-between text-[11.5px] text-neutral-500`,r(`span`,``,`Font size`),i),r(`label`,`flex cursor-pointer items-center justify-between text-[11.5px] text-neutral-500`,r(`span`,``,`Blinking cursor`),o),L()))}function z(){let e=P(C||`Choose a folder…`);e.title=`Switch folder`,e.onclick=()=>c(e,u().map(e=>({path:e})),C||void 0,e=>e===C?void 0:b(e));let t=P(`Files`);t.title=`Browse this folder`,t.onclick=()=>x(C);let n=P(`Fit`);n.title=`Resize the shell to this window`,n.onclick=()=>{H(),w?.focus()};let i=P(`Restart`);i.title=`End this shell and start a new one`,i.onclick=()=>void V();let a=r(`button`,`icon-btn text-[15px]`,`⚙`);a.type=`button`,a.title=`Terminal settings`,a.setAttribute(`aria-label`,`Terminal settings`),a.onclick=()=>R(a);let o=r(`button`,`icon-btn`,`✕`);o.type=`button`,o.title=`Close Terminal`,o.setAttribute(`aria-label`,`Close Terminal`),o.onclick=S,M.replaceChildren(e,j,...C?[t]:[],n,i,a,o)}let B=()=>{w&&E?.readyState===WebSocket.OPEN&&E.send(JSON.stringify({t:`resize`,cols:w.cols,rows:w.rows}))};async function V(){if(E?.readyState!==WebSocket.OPEN){await W();return}window.confirm(`Restart the shell in ${C}? Anything running in it stops.`)&&(k=!0,F(`restarting…`),E.send(JSON.stringify({t:`restart`})))}function H(){!w||N.clientHeight===0||(T?.fit(),B())}window.addEventListener(`focus`,H),document.addEventListener(`visibilitychange`,()=>{document.hidden||H()});function U(){E?.close(),E=null,T=null,w?.dispose(),w=null,N.replaceChildren()}async function W(){let e=++O;U(),D=!1,k=!1,F(`connecting…`);let t;try{t=await h()}catch(e){F(`could not load the terminal: ${String(e)}`,{label:`Retry`,run:()=>void W()});return}if(e!==O)return;w=new t.Terminal({fontFamily:A.fontFamily,fontSize:A.fontSize,cursorBlink:A.cursorBlink,scrollback:2e3,theme:_}),w.open(N),v(w),T=new t.FitAddon,w.loadAddon(T),T.observeResize(),T.fit();let n=new WebSocket(`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/api/terminal?cwd=${encodeURIComponent(C)}`);n.binaryType=`arraybuffer`,E=n,n.onopen=()=>{e===O&&(F(``),B(),w?.focus())},n.onmessage=t=>{if(e!==O)return;if(typeof t.data!=`string`){w?.write(new Uint8Array(t.data));return}let r;try{r=JSON.parse(t.data)}catch{D=!0,F(`invalid terminal response`,{label:`Reconnect`,run:()=>void W()}),n.close();return}if(r.t===`exit`){if(k){k=!1,W();return}D=!0,F(`shell exited (${r.code??`?`})`,{label:`Restart`,run:()=>void W()})}else r.t===`error`&&(D=!0,F(r.message??`terminal error`,{label:`Retry`,run:()=>void W()}))},n.onclose=()=>{e!==O||D||F(`disconnected`,{label:`Reconnect`,run:()=>void W()})},w.onData(e=>{n.readyState===WebSocket.OPEN&&n.send(JSON.stringify({t:`in`,d:e}))}),w.onResize(({cols:e,rows:t})=>{n.readyState===WebSocket.OPEN&&n.send(JSON.stringify({t:`resize`,cols:e,rows:t}))})}return i(o,e=>{let t=e?.startsWith(`/`)?e:C||m()||u()[0]||``;if(t===C&&w){z(),!D&&E&&E.readyState>WebSocket.OPEN?W():(H(),w.focus());return}if(C=t,z(),!C){F(`No project yet — pick a folder from the chip.`);return}W()},s)}export{b as createTerminalView};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ghostty-web-CvSZragH.js","assets/index-DHxoYoeq.js","assets/index-DuZ2vERd.css"])))=>i.map(i=>d[i]);
2
+ import{B as e,G as t,H as n,I as r,M as i,a,d as o,i as s,n as c,w as l}from"./index-DHxoYoeq.js";var u=`pier.terminalPrefs`,d={fontFamily:`monospace`,fontSize:14,cursorBlink:!0},f=()=>{try{let e=JSON.parse(localStorage.getItem(u)??`null`),t=typeof e?.fontSize==`number`?e.fontSize:d.fontSize;return{fontFamily:typeof e?.fontFamily==`string`&&e.fontFamily.trim()?e.fontFamily.slice(0,200):d.fontFamily,fontSize:Math.round(Math.max(10,Math.min(24,t))),cursorBlink:typeof e?.cursorBlink==`boolean`?e.cursorBlink:d.cursorBlink}}catch{return{...d}}},p=e=>localStorage.setItem(u,JSON.stringify(e)),m=null,h=()=>(m||=o(()=>import(`./ghostty-web-CvSZragH.js`).then(async e=>(await e.init(),e)),__vite__mapDeps([0,1,2])).catch(e=>{throw m=null,e}),m),g=()=>{let e=()=>void h().catch(e=>{console.warn(`terminal: emulator warm-up failed`,e)});`requestIdleCallback`in window?requestIdleCallback(e,{timeout:1e4}):setTimeout(e,3e3)},_={background:`#1a1b26`,foreground:`#a9b1d6`,cursor:`#c0caf5`};function v(e){let t=e.renderer,n=document.createElement(`canvas`).getContext(`2d`);if(!n||typeof t?.remeasureFont!=`function`){console.warn(`terminal: could not correct cell metrics — rows will render tight`);return}t.measureFont=()=>{let{fontSize:t,fontFamily:r}=e.options;n.font=`${t}px ${r}`;let i=n.measureText(`M`),a=i.fontBoundingBoxAscent||i.actualBoundingBoxAscent||t*.8,o=i.fontBoundingBoxDescent||i.actualBoundingBoxDescent||t*.25;return{width:Math.ceil(i.width),height:Math.ceil(a+o),baseline:Math.ceil(a)}},t.remeasureFont()}var y=`w-full rounded border border-neutral-300 px-2 py-1.5 font-mono text-[12px] outline-none focus:border-indigo-400`;function b(o,u,m,b,x,S){g();let C=``,w=null,T=null,E=null,D=!1,O=0,k=!1,A=f(),j=r(`div`,`ml-auto flex min-w-0 flex-none items-center gap-2`),M=r(`header`,`flex h-10 flex-none items-center gap-2 border-b border-neutral-200 bg-white px-3`),N=r(`div`,`min-h-0 flex-1 overflow-hidden p-1`);N.style.background=_.background,N.setAttribute(`data-owns-keyboard`,``),N.addEventListener(`keydown`,e=>{e.metaKey&&!e.defaultPrevented&&e.stopImmediatePropagation()},!0),N.addEventListener(`scroll`,()=>{N.scrollTop=0,N.scrollLeft=0}),N.addEventListener(`compositionend`,()=>{for(let e=N.childNodes.length-1;e>=0;e--){let t=N.childNodes[e];t&&t.nodeName!==`CANVAS`&&t.nodeName!==`TEXTAREA`&&t.remove()}}),o.append(M,N);let P=e=>{let t=r(`button`,`min-w-0 max-w-72 cursor-pointer truncate rounded-md bg-neutral-100 px-2 py-0.5 text-left font-mono text-[11.5px] text-neutral-600 hover:bg-neutral-200`,e);return t.type=`button`,t};function F(e,t){if(j.replaceChildren(),e&&j.append(r(`span`,`min-w-0 truncate text-[11.5px] text-neutral-400`,e)),t){let e=P(t.label);e.className=e.className.replace(`bg-neutral-100`,`bg-indigo-50 font-medium text-indigo-700 hover:bg-indigo-100`),e.onclick=t.run,j.append(e)}}function I(){w&&(w.options.fontFamily=A.fontFamily,w.options.fontSize=A.fontSize,w.options.cursorBlink=A.cursorBlink,requestAnimationFrame(H))}function L(){let i=document.createElement(`input`);i.type=`text`,i.placeholder=`tmux new -As "$(basename $PWD)"`,i.spellcheck=!1,i.autocomplete=`off`,i.autocapitalize=`off`,i.disabled=!0,i.className=`${y} disabled:bg-neutral-50`;let a=r(`span`,`block text-[11.5px] text-neutral-400`,`loading…`),o=(e,t)=>{a.isConnected?l(a,e,t):e===`failed`&&F(t)},s=``;(async()=>{try{s=(await n(`/api/settings`,`Could not load the startup command`)).terminalInitCommand??``,i.value=s,i.disabled=!1,o(`idle`,`Runs when a shell starts — Restart applies it here.`)}catch(e){o(`failed`,String(e))}})();let c=async()=>{let n=i.value.trim();if(!(i.disabled||n===s)){o(`saving`,`saving…`);try{let r=await t(`/api/settings`,{terminalInitCommand:n},`PUT`);if(!r.ok)return o(`failed`,await e(r,`Could not save the startup command`));s=(await r.json()).terminalInitCommand,i.value=s,o(`saved`,s?`Saved — the next shell runs it.`:`Cleared.`)}catch(e){o(`failed`,`Could not save the startup command: ${String(e)}`)}}};return i.onblur=()=>void c(),i.onkeydown=e=>{e.key===`Enter`&&c()},r(`div`,`space-y-1.5 border-t border-neutral-200 pt-2.5`,r(`div`,``,r(`span`,`text-[12px] font-semibold text-neutral-700`,`Startup command`),r(`span`,`block text-[11px] text-neutral-400`,`This Pier, every shell — not only this browser.`)),i,a)}function R(e){let t=document.createElement(`input`);t.type=`text`,t.value=A.fontFamily,t.setAttribute(`list`,`terminal-font-presets`),t.className=y;let n=document.createElement(`datalist`);n.id=`terminal-font-presets`;for(let e of[`monospace`,`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`,`JetBrains Mono, monospace`,`Cascadia Mono, monospace`,`Fira Code, monospace`]){let t=document.createElement(`option`);t.value=e,n.append(t)}let i=document.createElement(`input`);i.type=`number`,i.min=`10`,i.max=`24`,i.step=`1`,i.value=String(A.fontSize),i.className=`w-20 rounded border border-neutral-300 px-2 py-1.5 text-[12px] outline-none focus:border-indigo-400`;let o=document.createElement(`input`);o.type=`checkbox`,o.checked=A.cursorBlink,o.className=`h-4 w-4 accent-indigo-600`;let s=()=>{let e=t.value.trim(),n=Number(i.value);!e||!Number.isFinite(n)||(A={fontFamily:e.slice(0,200),fontSize:Math.round(Math.max(10,Math.min(24,n))),cursorBlink:o.checked},i.value=String(A.fontSize),p(A),I())};t.oninput=s,i.oninput=s,o.onchange=s;let c=r(`button`,`cursor-pointer text-[12px] text-neutral-500 hover:text-indigo-700`,`Reset`);c.type=`button`,c.onclick=()=>{A={...d},t.value=A.fontFamily,i.value=String(A.fontSize),o.checked=A.cursorBlink,p(A),I()},a(e,r(`div`,`w-72 space-y-3 px-3 py-2.5`,r(`div`,`flex items-center`,r(`span`,`text-[12px] font-semibold text-neutral-700`,`Terminal`),r(`span`,`ml-auto`,c)),r(`label`,`block space-y-1 text-[11.5px] text-neutral-500`,r(`span`,``,`Font family`),t,n),r(`label`,`flex items-center justify-between text-[11.5px] text-neutral-500`,r(`span`,``,`Font size`),i),r(`label`,`flex cursor-pointer items-center justify-between text-[11.5px] text-neutral-500`,r(`span`,``,`Blinking cursor`),o),L()))}function z(){let e=P(C||`Choose a folder…`);e.title=`Switch folder`,e.onclick=()=>c(e,u().map(e=>({path:e})),C||void 0,e=>e===C?void 0:b(e));let t=P(`Files`);t.title=`Browse this folder`,t.onclick=()=>x(C);let n=P(`Fit`);n.title=`Resize the shell to this window`,n.onclick=()=>{H(),w?.focus()};let i=P(`Restart`);i.title=`End this shell and start a new one`,i.onclick=()=>void V();let a=r(`button`,`icon-btn text-[15px]`,`⚙`);a.type=`button`,a.title=`Terminal settings`,a.setAttribute(`aria-label`,`Terminal settings`),a.onclick=()=>R(a);let o=r(`button`,`icon-btn`,`✕`);o.type=`button`,o.title=`Close Terminal`,o.setAttribute(`aria-label`,`Close Terminal`),o.onclick=S,M.replaceChildren(e,j,...C?[t]:[],n,i,a,o)}let B=()=>{w&&E?.readyState===WebSocket.OPEN&&E.send(JSON.stringify({t:`resize`,cols:w.cols,rows:w.rows}))};async function V(){if(E?.readyState!==WebSocket.OPEN){await W();return}window.confirm(`Restart the shell in ${C}? Anything running in it stops.`)&&(k=!0,F(`restarting…`),E.send(JSON.stringify({t:`restart`})))}function H(){!w||N.clientHeight===0||(T?.fit(),B())}window.addEventListener(`focus`,H),document.addEventListener(`visibilitychange`,()=>{document.hidden||H()});function U(){E?.close(),E=null,T=null,w?.dispose(),w=null,N.replaceChildren()}async function W(){let e=++O;U(),D=!1,k=!1,F(`connecting…`);let t;try{t=await h()}catch(e){F(`could not load the terminal: ${String(e)}`,{label:`Retry`,run:()=>void W()});return}if(e!==O)return;w=new t.Terminal({fontFamily:A.fontFamily,fontSize:A.fontSize,cursorBlink:A.cursorBlink,scrollback:2e3,theme:_}),w.open(N),v(w),T=new t.FitAddon,w.loadAddon(T),T.observeResize(),T.fit();let n=new WebSocket(`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/api/terminal?cwd=${encodeURIComponent(C)}`);n.binaryType=`arraybuffer`,E=n,n.onopen=()=>{e===O&&(F(``),B(),w?.focus())},n.onmessage=t=>{if(e!==O)return;if(typeof t.data!=`string`){w?.write(new Uint8Array(t.data));return}let r;try{r=JSON.parse(t.data)}catch{D=!0,F(`invalid terminal response`,{label:`Reconnect`,run:()=>void W()}),n.close();return}if(r.t===`exit`){if(k){k=!1,W();return}D=!0,F(`shell exited (${r.code??`?`})`,{label:`Restart`,run:()=>void W()})}else r.t===`error`&&(D=!0,F(r.message??`terminal error`,{label:`Retry`,run:()=>void W()}))},n.onclose=()=>{e!==O||D||F(`disconnected`,{label:`Reconnect`,run:()=>void W()})},w.onData(e=>{n.readyState===WebSocket.OPEN&&n.send(JSON.stringify({t:`in`,d:e}))}),w.onResize(({cols:e,rows:t})=>{n.readyState===WebSocket.OPEN&&n.send(JSON.stringify({t:`resize`,cols:e,rows:t}))})}return i(o,e=>{let t=e?.startsWith(`/`)?e:C||m()||u()[0]||``;if(t===C&&w){z(),!D&&E&&E.readyState>WebSocket.OPEN?W():(H(),w.focus());return}if(C=t,z(),!C){F(`No project yet — pick a folder from the chip.`);return}W()},s)}export{b as createTerminalView};
@@ -33,7 +33,7 @@
33
33
  which style.css pays for with the safe-area inset. -->
34
34
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
35
35
  <title>Pier</title>
36
- <script type="module" crossorigin src="/assets/index-WrsNstrb.js"></script>
36
+ <script type="module" crossorigin src="/assets/index-DHxoYoeq.js"></script>
37
37
  <link rel="stylesheet" crossorigin href="/assets/index-DuZ2vERd.css">
38
38
  </head>
39
39
  <!-- The document never scrolls: this is a fixed-viewport workbench, and every
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timqi/pier",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "A self-hosted workspace for coding agents: web workbench and IM channels in front of Pi sessions",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": "github:timqi/pier",