@timqi/pier 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channels/config.js +16 -0
- package/dist/channels/control.js +10 -3
- package/dist/channels/conversations.js +9 -0
- package/dist/channels/lark.js +3 -0
- package/dist/channels/panel.js +3 -6
- package/dist/channels/routes.js +3 -0
- package/dist/channels/slack.js +3 -0
- package/dist/channels/types.js +1 -0
- package/dist/web/public/assets/{activity-C9PhqKVX.js → activity-dxSOEHmf.js} +1 -1
- package/dist/web/public/assets/activity-dxSOEHmf.js.br +0 -0
- package/dist/web/public/assets/activity-dxSOEHmf.js.gz +0 -0
- package/dist/web/public/assets/{boards-YW0uAwJI.js → boards-BRwn5UZi.js} +1 -1
- package/dist/web/public/assets/boards-BRwn5UZi.js.br +0 -0
- package/dist/web/public/assets/boards-BRwn5UZi.js.gz +0 -0
- package/dist/web/public/assets/{explorer-BNm0Cr51.js → explorer-CCJQ22Dp.js} +1 -1
- package/dist/web/public/assets/explorer-CCJQ22Dp.js.br +0 -0
- package/dist/web/public/assets/explorer-CCJQ22Dp.js.gz +0 -0
- package/dist/web/public/assets/{index-Bfy7U1wv.js → index-CzV2cZEH.js} +3 -3
- package/dist/web/public/assets/index-CzV2cZEH.js.br +0 -0
- package/dist/web/public/assets/index-CzV2cZEH.js.gz +0 -0
- package/dist/web/public/assets/{runs-BNv9MSL2.js → runs-DtvDXSfo.js} +1 -1
- package/dist/web/public/assets/runs-DtvDXSfo.js.br +0 -0
- package/dist/web/public/assets/runs-DtvDXSfo.js.gz +0 -0
- package/dist/web/public/assets/{settings-Dxxux4Un.js → settings-CJbHCEZo.js} +1 -1
- package/dist/web/public/assets/settings-CJbHCEZo.js.br +0 -0
- package/dist/web/public/assets/settings-CJbHCEZo.js.gz +0 -0
- package/dist/web/public/assets/{task-runs-I1jLSvYq.js → task-runs-DcORJXHU.js} +1 -1
- package/dist/web/public/assets/task-runs-DcORJXHU.js.br +0 -0
- package/dist/web/public/assets/task-runs-DcORJXHU.js.gz +0 -0
- package/dist/web/public/assets/{tasks-DqrNu2Tz.js → tasks-8l1M8EJU.js} +1 -1
- package/dist/web/public/assets/tasks-8l1M8EJU.js.br +0 -0
- package/dist/web/public/assets/tasks-8l1M8EJU.js.gz +0 -0
- package/dist/web/public/index.html +1 -1
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/package.json +1 -1
- package/dist/web/public/assets/activity-C9PhqKVX.js.br +0 -0
- package/dist/web/public/assets/activity-C9PhqKVX.js.gz +0 -0
- package/dist/web/public/assets/boards-YW0uAwJI.js.br +0 -0
- package/dist/web/public/assets/boards-YW0uAwJI.js.gz +0 -0
- package/dist/web/public/assets/explorer-BNm0Cr51.js.br +0 -0
- package/dist/web/public/assets/explorer-BNm0Cr51.js.gz +0 -0
- package/dist/web/public/assets/index-Bfy7U1wv.js.br +0 -0
- package/dist/web/public/assets/index-Bfy7U1wv.js.gz +0 -0
- package/dist/web/public/assets/runs-BNv9MSL2.js.br +0 -0
- package/dist/web/public/assets/runs-BNv9MSL2.js.gz +0 -0
- package/dist/web/public/assets/settings-Dxxux4Un.js.br +0 -0
- package/dist/web/public/assets/settings-Dxxux4Un.js.gz +0 -0
- package/dist/web/public/assets/task-runs-I1jLSvYq.js.br +0 -0
- package/dist/web/public/assets/task-runs-I1jLSvYq.js.gz +0 -0
- package/dist/web/public/assets/tasks-DqrNu2Tz.js.br +0 -0
- package/dist/web/public/assets/tasks-DqrNu2Tz.js.gz +0 -0
package/dist/channels/config.js
CHANGED
|
@@ -91,6 +91,22 @@ export class ChannelStore {
|
|
|
91
91
|
}
|
|
92
92
|
this.save(platform, config);
|
|
93
93
|
}
|
|
94
|
+
/** A DM's id belongs to the bot it was opened with, so a new app or a rotated
|
|
95
|
+
* token leaves DMs no one can reach and nothing on screen tells them apart
|
|
96
|
+
* from the live ones — they are dropped. Group ids survive the swap. Returns
|
|
97
|
+
* the chat ids forgotten; the first identity ever seen forgets nothing. */
|
|
98
|
+
claimBot(platform, botId) {
|
|
99
|
+
const known = this.cached(platform).botId;
|
|
100
|
+
if (!botId || known === botId)
|
|
101
|
+
return [];
|
|
102
|
+
const config = this.get(platform);
|
|
103
|
+
const keep = (chat) => !known || chat.kind !== "dm";
|
|
104
|
+
const dropped = config.chats.filter((c) => !keep(c)).map((c) => c.id);
|
|
105
|
+
config.chats = config.chats.filter(keep);
|
|
106
|
+
config.botId = botId;
|
|
107
|
+
this.save(platform, config);
|
|
108
|
+
return dropped;
|
|
109
|
+
}
|
|
94
110
|
// On the per-message path: no clone, nothing here escapes.
|
|
95
111
|
policy(platform, chatId) {
|
|
96
112
|
const config = this.cached(platform);
|
package/dist/channels/control.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// What an adapter may do
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// What an adapter may do beyond handing a prompt over: act on a thread's
|
|
2
|
+
// session, and claim the identity its chats belong to. Not part of the
|
|
3
|
+
// `Channel` seam: the channel layer owns the router and the stores and hands
|
|
4
|
+
// adapters this narrow interface instead. Thin wrappers; no policy.
|
|
4
5
|
import { projectCwds } from "../core/identity.js";
|
|
5
6
|
import { chatOf, isChannelPlatform } from "./types.js";
|
|
6
7
|
export const NO_SESSION = "No session in this thread yet — start one first (Start in the panel).";
|
|
@@ -25,6 +26,12 @@ export function createControl({ router, factory, conversations, store, modelMenu
|
|
|
25
26
|
};
|
|
26
27
|
return {
|
|
27
28
|
launchFor,
|
|
29
|
+
claimBot(platform, botId) {
|
|
30
|
+
const dropped = store.claimBot(platform, botId);
|
|
31
|
+
for (const chatId of dropped)
|
|
32
|
+
conversations.forgetChat(platform, chatId);
|
|
33
|
+
return dropped;
|
|
34
|
+
},
|
|
28
35
|
knows: (key) => conversations.get(key) !== undefined,
|
|
29
36
|
abort: (key) => router.abortConversation(key),
|
|
30
37
|
working: (key) => router.sessionOf(key)?.state === "streaming",
|
|
@@ -52,6 +52,15 @@ export class ConversationStore {
|
|
|
52
52
|
const rows = this.db.prepare(`SELECT session_id FROM conversations`).all();
|
|
53
53
|
return new Set(rows.map((r) => r.session_id));
|
|
54
54
|
}
|
|
55
|
+
/** Every thread of one chat: a chat that is gone would otherwise keep its
|
|
56
|
+
* sessions bound to a conversation nothing can reach. */
|
|
57
|
+
forgetChat(channelId, chatId) {
|
|
58
|
+
const prefix = `${chatId}/`;
|
|
59
|
+
this.db.prepare(`
|
|
60
|
+
DELETE FROM conversations
|
|
61
|
+
WHERE channel_id = ? AND (conversation_id = ? OR substr(conversation_id, 1, ?) = ?)
|
|
62
|
+
`).run(channelId, chatId, prefix.length, prefix);
|
|
63
|
+
}
|
|
55
64
|
forget(key) {
|
|
56
65
|
this.db.prepare(`
|
|
57
66
|
DELETE FROM conversations WHERE channel_id = ? AND conversation_id = ?
|
package/dist/channels/lark.js
CHANGED
|
@@ -90,6 +90,9 @@ export class LarkChannel {
|
|
|
90
90
|
// Every chat with require-mention on goes silent; loud, not a debug line.
|
|
91
91
|
this.log("bot info returned no open_id: mention detection is disabled");
|
|
92
92
|
}
|
|
93
|
+
const dropped = this.deps.control?.claimBot("lark", this.me) ?? [];
|
|
94
|
+
if (dropped.length)
|
|
95
|
+
this.log(`bot is now ${this.me}: forgot ${dropped.length} DM(s) the previous bot opened`);
|
|
93
96
|
this.running = true;
|
|
94
97
|
void this.receipts.sweep(true);
|
|
95
98
|
this.socket = await this.api.connect({
|
package/dist/channels/panel.js
CHANGED
|
@@ -31,11 +31,8 @@ export const CWD_DRAFT_TAIL = "Start creates the session there.";
|
|
|
31
31
|
export const CWD_PLACEHOLDER = "/path/to/project";
|
|
32
32
|
export const QUESTION_TOO_LONG = "Your question is too long to hold — send it again after Start.";
|
|
33
33
|
const btn = (label, action) => ({ label, action });
|
|
34
|
-
/** A button label is the last
|
|
35
|
-
const shortDir = (path) =>
|
|
36
|
-
const parts = path.split("/").filter(Boolean);
|
|
37
|
-
return parts.length > 2 ? `…/${parts.slice(-2).join("/")}` : path;
|
|
38
|
-
};
|
|
34
|
+
/** A button label is the last segment; the numbered line above has the whole path. */
|
|
35
|
+
const shortDir = (path) => path.split("/").filter(Boolean).at(-1) ?? path;
|
|
39
36
|
/** One transcript line as a reader sees it: what was said, minus what was
|
|
40
37
|
* written for the model (the speaker header, attachment markers, the
|
|
41
38
|
* next-step block, a silent turn's reason). */
|
|
@@ -324,7 +321,7 @@ export class ChatPanel {
|
|
|
324
321
|
title: "Continue web session",
|
|
325
322
|
suffix: ` · page ${at + 1}/${pages}`,
|
|
326
323
|
lines: slice.length
|
|
327
|
-
? slice.map((s, i) => `${String(from + i + 1)}. ${this.esc(shortTitle(s))} · ${this.code(s.cwd
|
|
324
|
+
? slice.map((s, i) => `${String(from + i + 1)}. ${this.esc(shortTitle(s))} · ${this.code(shortDir(s.cwd))} · ${age(s.modified ?? s.createdAt, now)}`)
|
|
328
325
|
: [unavailable ?? "No unbound sessions."],
|
|
329
326
|
}],
|
|
330
327
|
picks: slice.map((s, i) => btn(`${String(from + i + 1)} ${shortTitle(s)}`, `session:${String(from + i)}`)),
|
package/dist/channels/routes.js
CHANGED
|
@@ -79,6 +79,9 @@ export function registerChannelRoutes(app, store, runtime, handoff) {
|
|
|
79
79
|
users: current.users,
|
|
80
80
|
chats: parseChats(body.chats, current.chats),
|
|
81
81
|
bindCode: current.bindCode,
|
|
82
|
+
// Learned at start, never edited here: a save that reset it would make the
|
|
83
|
+
// next start read as the first one and skip the swapped bot's cleanup.
|
|
84
|
+
botId: current.botId,
|
|
82
85
|
};
|
|
83
86
|
store.save(platform, next);
|
|
84
87
|
await runtime.reload();
|
package/dist/channels/slack.js
CHANGED
|
@@ -126,6 +126,9 @@ export class SlackChannel {
|
|
|
126
126
|
// Every channel with require-mention on goes silent; loud, not a debug line.
|
|
127
127
|
this.log("auth.test returned no user id: mention detection is disabled");
|
|
128
128
|
}
|
|
129
|
+
const dropped = this.deps.control?.claimBot("slack", this.me) ?? [];
|
|
130
|
+
if (dropped.length)
|
|
131
|
+
this.log(`bot is now ${this.me}: forgot ${dropped.length} DM(s) the previous bot opened`);
|
|
129
132
|
this.running = true;
|
|
130
133
|
void this.receipts.sweep(true);
|
|
131
134
|
this.socket = await this.api.connect((env) => this.onEnvelope(env, onMessage));
|
package/dist/channels/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{C as e,G as t,J as n,O as r,P as i,Q as a,V as o,Y as s,Z as c,at as l,et as u,t as d,u as f}from"./index-
|
|
1
|
+
import{C as e,G as t,J as n,O as r,P as i,Q as a,V as o,Y as s,Z as c,at as l,et as u,t as d,u as f}from"./index-CzV2cZEH.js";var p=[[`path`,{d:`M3 5h.01`}],[`path`,{d:`M3 12h.01`}],[`path`,{d:`M3 19h.01`}],[`path`,{d:`M8 5h13`}],[`path`,{d:`M8 12h13`}],[`path`,{d:`M8 19h13`}]],m=[[`path`,{d:`m10.586 5.414-5.172 5.172`}],[`path`,{d:`m18.586 13.414-5.172 5.172`}],[`path`,{d:`M6 12h12`}],[`circle`,{cx:`12`,cy:`20`,r:`2`}],[`circle`,{cx:`12`,cy:`4`,r:`2`}],[`circle`,{cx:`20`,cy:`12`,r:`2`}],[`circle`,{cx:`4`,cy:`12`,r:`2`}]],h=(e,t={})=>{let n=document.createElementNS(`http://www.w3.org/2000/svg`,e);for(let[e,r]of Object.entries(t))n.setAttribute(e,r);return n},g=e=>e===null?`-`:n(Date.now()-e),_={invocation:{stroke:`stroke-neutral-400`,fill:`fill-neutral-400`},callback:{stroke:`stroke-cyan-500`,fill:`fill-cyan-500`,dash:`6 5`},message:{stroke:`stroke-amber-500`,fill:`fill-amber-500`,dash:`2 5`}},v={scheduler:`border-violet-200 bg-violet-50 text-violet-700`,console:`border-indigo-200 bg-indigo-50 text-indigo-700`,task:`border-amber-200 bg-amber-50 text-amber-700`,process:`border-dashed border-neutral-300 bg-neutral-50 text-neutral-500`,streaming:`border-emerald-200 bg-white font-medium text-neutral-800`,idle:`border-neutral-200 bg-white font-medium text-neutral-600`},y=300,b=4;function x(e,t){let n,r=null,i=!1,a=!1,o=()=>{clearTimeout(n),n=setTimeout(()=>{i||a||!r||r.dataset.closing!==void 0||(f(),r=null)},120)};e.onpointerenter=s=>{s.pointerType!==`touch`&&(i=!0,clearTimeout(n),!(r?.isConnected&&r.dataset.closing===void 0)&&(n=setTimeout(()=>{!e.isConnected||!i||(r=d(e,t),r.onpointerenter=()=>{a=!0,clearTimeout(n)},r.onpointerleave=()=>{a=!1,o()})},y)))},e.onpointerleave=()=>{i=!1,o()},e.onpointerdown=()=>clearTimeout(n)}function S(e){let t,n=!1;e.classList.add(`cursor-grab`),e.onpointerdown=r=>{n=!1,!(r.button!==0||r.pointerType===`touch`||r.target.closest(`[data-node], path`))&&(t={x:r.clientX,y:r.clientY,left:e.scrollLeft,top:e.scrollTop},e.setPointerCapture(r.pointerId),e.classList.add(`cursor-grabbing`,`select-none`))},e.onpointermove=r=>{if(!t)return;let i=r.clientX-t.x,a=r.clientY-t.y;(Math.abs(i)>b||Math.abs(a)>b)&&(n=!0),e.scrollLeft=t.left-i,e.scrollTop=t.top-a};let r=()=>{t=void 0,e.classList.remove(`cursor-grabbing`,`select-none`)};e.onpointerup=r,e.onpointercancel=r,e.addEventListener(`click`,e=>{n&&(e.stopPropagation(),e.preventDefault())},!0)}function C(n,d,f){let y=`sessions`,b=`active`,C={sessions:[],runs:[],messages:[]},w=``,T=a(async()=>{let e=b,t=await u(`/api/activity?scope=${e}`,`Failed to load activity`);if(!t.ok){w=``,n.replaceChildren(s(`p`,`p-4 text-[13px] text-red-600`,t.error));return}if(e!==b)return;let r=JSON.stringify(t.value);if(`${e}:${r}`===w)return;w=`${e}:${r}`;let i=t.value;C={...i,sessions:i.sessions.map(e=>({...e,title:l(e.title)}))},E()});function E(){let e=o(i([[`Sessions`,`sessions`,p],[`Relationships`,`dependencies`,m]],y,e=>{y=e,E()}),s(`span`,`ml-auto text-[11.5px] text-neutral-400`,`${C.sessions.length} sessions · ${C.runs.length} runs`),i([[`Current`,`active`],[`Last 24h`,`recent`]],b,e=>{b=e,E(),T()})),t=s(`div`,`automation-list min-h-0 flex-1 overflow-auto`);y===`sessions`?D(t):k(t),n.replaceChildren(e,t)}function D(e){let t=document.createElement(`table`);t.className=`w-full table-fixed text-left text-[12.5px]`,t.innerHTML=`<thead class="sticky top-0 bg-neutral-50 text-[10.5px] uppercase tracking-wide text-neutral-400 shadow-[inset_0_-1px_0_var(--color-neutral-200)]"><tr>
|
|
2
2
|
<th class="w-[50%] px-4 py-2 font-semibold md:w-[34%]">Session</th>
|
|
3
3
|
<th class="hidden w-[38%] px-2 py-2 font-semibold md:table-cell">Project</th>
|
|
4
4
|
<th class="px-2 py-2 font-semibold md:w-[14%]">State</th>
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as e,B as t,E as n,G as r,K as i,M as a,O as o,X as s,Y as c,et as l,it as u,rt as d,w as f}from"./index-
|
|
1
|
+
import{$ as e,B as t,E as n,G as r,K as i,M as a,O as o,X as s,Y as c,et as l,it as u,rt as d,w as f}from"./index-CzV2cZEH.js";var p=e=>e.public&&e.token?`/p/${e.slug}-${e.token}/`:`/boards/${e.slug}/`;function m(m,h){let g=[],_=``,v=c(`header`,`pagehead sticky top-[-8px] z-30 max-md:hidden`,a(`Boards`)),y=c(`div`,`px-4 pb-5 pt-1`);m.append(c(`div`,`min-h-0 flex-1 overflow-y-auto`,v,y));async function b(t,n){let r=await u(`/api/boards/${t.slug}`,{public:n},`PATCH`);if(r.ok)return t.token=(await r.json().catch(()=>({}))).token??``,w();_=await e(r,`Could not change ${t.slug}`),await T()}async function x(e){_=await d(`/api/boards/${e}`,`DELETE`,`Could not delete ${e}`)??``,await T()}function S(e){let n=c(`div`,`group flex flex-col gap-1 py-2.5`),r=document.createElement(`a`);r.className=`min-w-0 flex-1 truncate text-[13px] font-medium text-neutral-800 hover:text-indigo-700 max-md:basis-full`,r.href=p(e),r.target=`_blank`,r.rel=`noreferrer`,r.textContent=e.title;let a=c(`div`,`flex flex-wrap items-center gap-x-2 gap-y-1`,r),o=t(``,``,e.public,t=>{e.public=t,b(e,t)});o.className=`flex flex-none cursor-pointer items-center gap-1.5 text-[11.5px] text-neutral-500`,o.append(c(`span`,``,`Public`));let l=f(`Delete`,`flex-none cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-red-600 group-hover:opacity-100 pointer-coarse:opacity-100`);l.title=`Renames the folder on disk; nothing is erased`,l.onclick=()=>void x(e.slug);let u=i(`flex-none cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-indigo-600 group-hover:opacity-100 pointer-coarse:opacity-100`,()=>`${location.origin}${p(e)}`);u.title=`Copy the board's link`,a.append(c(`div`,`ml-auto flex flex-none items-center gap-2`,o,u,l)),n.append(a);let d=c(`div`,`flex flex-wrap items-center gap-x-3 gap-y-1 text-[11.5px] text-neutral-500`);d.append(c(`span`,`min-w-0 break-all font-mono text-neutral-400`,e.slug)),e.description&&d.append(c(`span`,`min-w-0 truncate`,e.description)),d.append(c(`span`,`flex-none text-neutral-400`,s(Date.parse(e.updatedAt))));for(let t of e.sessions){let e=f(t.slice(0,8),`flex-none cursor-pointer font-mono text-indigo-600 hover:underline`);e.title=`Open session ${t}`,e.onclick=()=>h(t),d.append(e)}if(e.public&&e.token){let t=c(`span`,`min-w-0 break-all font-mono text-neutral-400`,p(e));t.title=`Public URL — anyone holding this link can read the board, no password`,d.append(t)}return n.append(d),n}let C=[{title:`Public`,hint:`Readable at /p/<slug>-<token>/ by anyone holding the link.`,wanted:!0},{title:`Private`,hint:`Opened from here; the address that opens is a temporary link, good for 8 hours.`,wanted:!1}];function w(){let e=c(`div`,`mx-auto flex w-full max-w-3xl flex-col gap-4`);g.length===0&&e.append(o(`No boards yet. Ask an agent to build one — it writes a folder under ~/.pier/boards.`));for(let{title:t,hint:r,wanted:i}of C){let a=g.filter(e=>e.public===i);a.length!==0&&e.append(n(t,r,c(`div`,`flex flex-col divide-y divide-neutral-200/70`,...a.map(S))))}y.replaceChildren(..._?[c(`p`,`mb-3 text-[13px] text-red-600`,_)]:[],e)}async function T(){let e=await l(`/api/boards`,`Could not load boards`);if(!e.ok)return _=e.error,w();g=e.value,w(),_=``}let E=r(m,()=>void T());return window.addEventListener(`focus`,()=>{E.visible&&T()}),E}export{m as createBoardsView};
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{G as e,M as t,O as n,W as r,X as i,Y as a,a as o,ct as s,f as c,g as l,h as u,l as d,m as f,mt as p,p as m,pt as ee,q as te,st as h,tt as g,u as _,v as ne,w as re,y as ie}from"./index-
|
|
1
|
+
import{G as e,M as t,O as n,W as r,X as i,Y as a,a as o,ct as s,f as c,g as l,h as u,l as d,m as f,mt as p,p as m,pt as ee,q as te,st as h,tt as g,u as _,v as ne,w as re,y as ie}from"./index-CzV2cZEH.js";var ae=[[`path`,{d:`M12 5v14`}],[`path`,{d:`m19 12-7 7-7-7`}]],oe=[[`path`,{d:`M12 22v-6`}],[`path`,{d:`M12 8V2`}],[`path`,{d:`M4 12H2`}],[`path`,{d:`M10 12H8`}],[`path`,{d:`M16 12h-2`}],[`path`,{d:`M22 12h-2`}],[`path`,{d:`m15 19-3-3-3 3`}],[`path`,{d:`m15 5-3 3-3-3`}]],se=[[`path`,{d:`M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z`}]],ce=[[`path`,{d:`M15 6a9 9 0 0 0-9 9V3`}],[`circle`,{cx:`18`,cy:`6`,r:`3`}],[`circle`,{cx:`6`,cy:`18`,r:`3`}]],v=[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`}],[`path`,{d:`M3 3v5h5`}]],y=e=>{let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`},le=e=>[e.subject,e.body,[[e.author,e.email?`<${e.email}>`:``].filter(Boolean).join(` `),e.at?y(e.at):``].filter(Boolean).join(` · `)].filter(Boolean).join(`
|
|
2
2
|
|
|
3
3
|
`),b=null;function x(){b&&(b.remove(),b=null,document.removeEventListener(`pointerdown`,x,!0),window.removeEventListener(`scroll`,x,!0))}function ue(e,t){e.onmouseenter=()=>{x();let n=t();if(!n)return;b=a(`div`,`pointer-events-none fixed z-50 max-w-96 whitespace-pre-wrap rounded-lg bg-neutral-800/95 px-3 py-2 font-sans text-[11.5px] leading-snug text-neutral-100 shadow-lg`),b.textContent=n,document.body.append(b),document.addEventListener(`pointerdown`,x,!0),window.addEventListener(`scroll`,x,!0);let r=e.getBoundingClientRect();b.style.left=`${Math.max(8,Math.min(r.left,window.innerWidth-b.offsetWidth-8))}px`,b.style.top=r.bottom+6+b.offsetHeight>window.innerHeight?`${r.top-b.offsetHeight-6}px`:`${r.bottom+6}px`},e.onmouseleave=x}function S(e,t,n){let r=a(`button`,`flex w-full cursor-pointer items-center gap-1.5 px-2 py-1 text-left hover:bg-neutral-100`,h(ee,`h-3 w-3 text-indigo-600 ${e.value===t?``:`invisible`}`),a(`span`,`inline-flex flex-none items-center gap-1.5 font-mono text-[11.5px] text-neutral-800`,e.label??e.value));return e.subject&&r.append(a(`span`,`min-w-0 truncate text-[11px] text-neutral-400`,e.subject)),e.author&&r.append(a(`span`,`ml-auto flex-none pl-1.5 text-[10.5px] text-neutral-400`,`${e.author} · ${e.at?i(e.at):``}`)),ue(r,()=>le(e)),r.onclick=()=>n(e.value),r}function de(e,t,n,r,i){let{base:o,head:s}=n,l=()=>s&&o===`${s}~1`?s:``,u=l()?`commit`:`compare`,d=t.commits[0],f=e=>[...e?[{value:``,label:`Working tree`,subject:`the files on disk, uncommitted changes included`}]:[],{...d,value:`HEAD`},...t.refs.map(e=>({value:e.name,subject:e.subject})),...t.commits.map(e=>({...e,value:e.hash}))],p=a(`div`,`flex w-[38rem] max-w-full flex-col`);function m(){let e=(e,t)=>{let n=a(`button`,`cursor-pointer rounded-full px-2.5 py-0.5 text-[11.5px] ${u===t?`bg-indigo-50 font-medium text-indigo-700`:`text-neutral-500 hover:bg-neutral-100`}`,e);return n.onclick=()=>{u=t,m()},n},n=(e,t,n,r)=>a(`div`,`flex min-w-0 flex-1 flex-col`,a(`div`,`flex-none px-2 pb-0.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),a(`div`,`min-h-0 flex-1 overflow-y-auto`,...t.map(e=>S(e,n,r)))),c=u===`compare`?a(`div`,`flex h-72 min-h-0 divide-x divide-neutral-200 pb-1`,n(`base`,f(!1),o,e=>{o=e,m(),r(o,s)}),n(`to`,f(!0),s,e=>{s=e,m(),r(o,s)})):a(`div`,`flex h-72 min-h-0 flex-col overflow-y-auto pb-1`,...t.commits.map(e=>S({value:e.hash,...e},l(),e=>{o=`${e}~1`,s=e,_(),r(o,s)}))),d=a(`div`,`flex-none border-t border-neutral-200`,S({value:i,label:`${i} ↔ Working tree`,subject:`back to the default: the main line's tip vs the files on disk`},o===i&&s===``?i:``,()=>{o=i,s=``,m(),r(o,s)}));d.querySelector(`button > span`).prepend(h(v)),p.replaceChildren(a(`div`,`flex flex-none items-center gap-1 border-b border-neutral-200 px-2 py-1.5`,e(`Compare two points`,`compare`),e(`One commit`,`commit`)),c,...u===`compare`?[d]:[])}m(),c(e,p)}var fe=/\.(png|jpe?g|gif|webp|avif|bmp|svg)$/i,C={A:`text-emerald-600`,M:`text-amber-600`,D:`text-red-600`},pe=30,w=`pier.filesPrefs`,T=50,E=()=>{try{let e=JSON.parse(localStorage.getItem(w)??`{}`);return e&&typeof e==`object`?e:{}}catch{return{}}},me=e=>{let t=e?E()[e]:void 0;return typeof t?.cwd==`string`&&typeof t.base==`string`&&typeof t.head==`string`?{cwd:t.cwd,base:t.base,head:t.head}:null},he=(e,t)=>{let n=E();delete n[e],n[e]=t;let r=Object.keys(n);for(let e of r.slice(0,Math.max(0,r.length-T)))delete n[e];try{localStorage.setItem(w,JSON.stringify(n))}catch(e){console.warn(`Files: could not remember this folder`,e)}},ge=`flex min-w-0 flex-none items-center gap-1.5 rounded-full px-2.5 py-1 font-mono text-[11.5px]`,_e=(e,t=`indigo`)=>re(e,`${ge} cursor-pointer truncate text-left ${t===`indigo`?`bg-indigo-50 font-medium text-indigo-700 hover:bg-indigo-100`:`bg-neutral-100 text-neutral-600 hover:bg-neutral-200`}`);function D(i,c,ee,_){let v=``,y=``,b={branch:null,refs:[],commits:[],worktrees:[]},x=`HEAD`,S=``,w=new Map,T=!0,E=!1,D=[],O=new Set,k=null,A=null,j=null,ve=a(`header`,`pagehead flex-nowrap`),M=a(`div`,`${l} flex-col items-stretch gap-1.5 px-3 py-2.5`),N=a(`div`,`min-h-0 flex-1 overflow-y-auto px-1.5 py-1.5`),ye=a(`aside`,`${ie} w-64 flex-none text-[12.5px] leading-5 max-md:h-1/2 max-md:w-full`,M,N),P=a(`div`,`${l} flex-wrap gap-2 px-4 py-2.5 font-mono text-[11.5px] text-neutral-500`),F=a(`div`,`h-full min-w-0 overflow-auto`),I=a(`div`,`pointer-events-none absolute inset-y-1 right-0.5 z-20 hidden w-2`),be=a(`div`,`relative min-h-0 flex-1`,F,I),xe=a(`section`,`${ie} min-h-0 min-w-0 flex-1`,P,be);i.append(ve,a(`div`,`flex min-h-0 flex-1 gap-3 px-4 pb-4 pt-1 max-md:flex-col`,ye,xe));let L=(e,t)=>`/api/explorer/${e}?${new URLSearchParams({root:v,...t})}`,R=(e,t)=>`/api/fs/${e}?${new URLSearchParams({root:v,...t})}`,z=(e,t=`text-neutral-400`)=>a(`p`,`px-3 py-2 text-[12.5px] ${t}`,e),B=e=>a(`div`,`flex h-full items-center justify-center p-6`,n(e)),Se=()=>T&&b.branch!==null,Ce=e=>{let t=0;for(let n of w.keys())n.startsWith(`${e}/`)&&t++;return t};function we(e,t){let n=new Set(t.map(e=>e.name)),r=e?`${e}/`:``;for(let[e,i]of w){if(i.status!==`D`||!e.startsWith(r))continue;let a=e.slice(r.length).split(`/`)[0];n.has(a)||(n.add(a),t.push({name:a,dir:e.slice(r.length).includes(`/`)}))}let i=t;return Se()&&(i=t.filter(e=>e.dir?Ce(`${r}${e.name}`)>0:w.has(`${r}${e.name}`))),i.sort((e,t)=>Number(t.dir)-Number(e.dir)||e.name.localeCompare(t.name)),i.map(e=>e.dir?Ee(`${r}${e.name}`,e.name):De(`${r}${e.name}`,e.name))}async function Te(e,t){try{let{entries:n}=await g(R(`ls`,{path:t}),`could not list this folder`);e.replaceChildren(...we(t,n)),e.childElementCount||e.append(z(Se()?`No changes.`:`Empty.`))}catch(n){let r=we(t,[]);r.length?e.replaceChildren(...r):e.replaceChildren(z(String(n),`text-red-600`))}}function Ee(e,t){let n=Ce(e),r=[a(`span`,`truncate`,t)];n&&r.push(a(`span`,`ml-auto flex-none rounded-full bg-amber-100/80 px-1.5 font-mono text-[10px] font-semibold text-amber-700`,String(n)));let{el:i,summary:o}=te(``,r);o.className+=` rounded-lg px-2 py-1 transition-colors hover:bg-neutral-100`;let s=a(`div`,`pl-3`);i.append(s);let c=!1,l=()=>{c||(c=!0,s.append(z(`…`)),Te(s,e))};return i.ontoggle=()=>{O[i.open?`add`:`delete`](e),i.open&&l()},((b.branch?T:!e.includes(`/`))&&!E||O.has(e))&&(i.open=!0,l()),i}function V(e){A?.classList.remove(`bg-indigo-50`,`font-medium`,`text-indigo-700`),A=e,e.classList.add(`bg-indigo-50`,`font-medium`,`text-indigo-700`)}function De(e,t){let n=w.get(e)?.status,r=a(`button`,`flex w-full cursor-pointer items-center gap-1.5 rounded-lg py-1 pl-6 pr-2 text-left transition-colors hover:bg-neutral-100`,a(`span`,`truncate`,t));return n&&r.append(a(`span`,`ml-auto flex-none font-mono text-[10.5px] font-semibold ${C[n]??`text-neutral-500`}`,n)),r.title=e,e===k&&V(r),e===j&&(j=null,k=e,V(r),J(e)),r.onclick=()=>{V(r),k=e,J(e)},r}let H=()=>void Te(N,``),U=(e,t)=>[...e?[a(`span`,`flex-none font-mono text-[10.5px] font-semibold text-emerald-600`,`+${e}`)]:[],...t?[a(`span`,`flex-none font-mono text-[10.5px] font-semibold text-red-600`,`−${t}`)]:[]];function W(e,t=!1,n){if(P.classList.toggle(`hidden`,!e),P.classList.toggle(`flex`,!!e),!e)return P.replaceChildren();let i=w.get(e),o=[a(`span`,`min-w-0 truncate`,e)];i&&(o.push(a(`span`,`flex-none font-semibold ${C[i.status]??``}`,i.status)),o.push(...U(i.add,i.del)));let s=a(`div`,`ml-auto flex flex-none items-center gap-2`);if(n&&s.append(n),t){let t=document.createElement(`a`);t.className=`btn flex-none text-[12px]`,t.href=R(`file`,{path:e}),t.download=r(e),t.textContent=`Download`,s.append(t)}P.replaceChildren(...o,s)}function Oe(e){let t=0;for(;t<e.length;){if(e[t].tone!==`del`){t++;continue}let n=t;for(;t<e.length&&e[t].tone===`del`;)t++;let r=t;for(;t<e.length&&e[t].tone===`add`;)t++;let i=Math.min(r-n,t-r);for(let t=0;t<i;t++){let i=e[n+t],a=e[r+t],o=Math.min(i.text.length,a.text.length),s=0;for(;s<o&&i.text[s]===a.text[s];)s++;let c=0;for(;c<o-s&&i.text[i.text.length-1-c]===a.text[a.text.length-1-c];)c++;s+c!==0&&(i.mark=[s,i.text.length-c],a.mark=[s,a.text.length-c])}}}let G=Ie();function K(){I.classList.add(`hidden`),I.replaceChildren(),G.set([],[])}let ke=0,q=e=>e===ke;function J(e){let t=++ke;return w.has(e)?Le(e,t):Ae(e,t)}async function Ae(e,t){if(!q(t))return;K();let n=R(`file`,{path:e}),r=a(`div`,`min-w-0`);if(F.classList.remove(`flex`,`flex-col`),W(e,!0),F.replaceChildren(r),fe.test(e)){let e=a(`img`,`max-w-full p-4`);e.src=n,e.onerror=()=>r.replaceChildren(z(`Could not load image.`,`text-red-600`)),r.append(e);return}if(e.toLowerCase().endsWith(`.pdf`)){let e=document.createElement(`iframe`);e.className=`h-full w-full`,e.src=n,F.replaceChildren(e),F.classList.add(`flex`,`flex-col`);return}r.append(z(`…`));let i=await fetch(n);if(!q(t))return;if(!i.ok){let{error:e}=await i.json().catch(()=>({}));r.replaceChildren(z(e??`HTTP ${i.status}`,`text-red-600`));return}if(!(i.headers.get(`content-type`)??``).startsWith(`text/plain`)){r.replaceChildren(z(`Binary file — use Download.`));return}let o=f(await i.text());if(!q(t))return;let s=await u(e);q(t)&&r.replaceChildren(m(o,s))}function je(e){let t=[],n=0,r=0,i=!1,a=e.split(`
|
|
4
4
|
`);a.at(-1)===``&&a.pop();for(let e of a){let a=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(e);if(a){i&&t.push({nums:[``,``],text:`⋯`,tone:``}),[n,r]=[Number(a[1]),Number(a[2])],i=!0;continue}!i||e.startsWith(`\\`)||(e.startsWith(`+`)?t.push({nums:[``,r++],text:e.slice(1),tone:`add`}):e.startsWith(`-`)?t.push({nums:[n++,``],text:e.slice(1),tone:`del`}):t.push({nums:[n++,r++],text:e.slice(1),tone:``}))}return t}function Me(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n].tone;if(!r)continue;let i=t.at(-1);i&&i.end===n-1?(i.end=n,(r===`add`&&i.tone===`del`||r===`del`&&i.tone===`add`)&&(i.tone=`mixed`)):t.push({start:n,end:n,tone:r})}return t}let Ne={add:`bg-emerald-400`,del:`bg-red-400`,mixed:`bg-amber-400`};function Pe(e,t,n){I.replaceChildren(...e.map(e=>{let r=a(`button`,`map-mark pointer-events-auto absolute left-1/2 w-1 -translate-x-1/2 cursor-pointer rounded-full ${Ne[e.tone]}`);return r.style.top=`${e.start/t*100}%`,r.style.height=`${Math.max(.4,(e.end-e.start+1)/t*100)}%`,r.title=`line ${Fe(n,e.start)}`,r.onclick=()=>n[e.start].scrollIntoView({block:`center`}),r})),I.classList.remove(`hidden`)}let Fe=(e,t)=>e[t]?.querySelector(`span`)?.textContent?.trim()||String(t+1);function Ie(){let e=[],t=[],n=-1,r=a(`span`,`flex-none text-[10.5px] text-neutral-400`),s=i=>{e.length&&(n=(n+i+e.length)%e.length,t[e[n].start].scrollIntoView({block:`center`}),r.textContent=`${n+1}/${e.length}`)},c=()=>e.length>0&&!i.classList.contains(`hidden`),l=(e,t,n,r)=>{let i=a(`button`,`icon-btn flex-none`,h(e));return i.onclick=()=>s(t),o(i,r,n,()=>s(t),c),i};return{el:a(`div`,`flex flex-none items-center gap-1`,r,l(p,-1,`Previous change`,[`p`,`k`]),l(ae,1,`Next change`,[`n`,`j`])),set(i,a){e=i,t=a,n=-1,r.textContent=`${i.length} change${i.length===1?``:`s`}`}}}async function Le(e,t){K(),F.classList.remove(`flex`,`flex-col`);let n=w.get(e)?.status!==`D`;W(e,n),F.replaceChildren(z(`…`));try{let{diff:r}=await g(L(`diff`,{base:x,head:S,file:e,context:`99999`}),`could not read this diff`);if(!q(t))return;if(!r||/^Binary files /m.test(r))return Ae(e,t);let i=je(r);Oe(i);let a=await u(e);if(!q(t))return;let o=m(i,a),s=[...o.children],c=Me(i);G.set(c,s),W(e,n,G.el),F.replaceChildren(o),Pe(c,i.length,s)}catch(n){if(!q(t))return;W(e),F.replaceChildren(z(String(n),`text-red-600`))}}let Y=()=>S&&x===`${S}~1`?S:``,Re=()=>b.commits.find(e=>e.hash===Y())?.subject??``,ze=()=>Y()?`${Y()} — ${Re()||`commit`}`:`${x} ↔ ${S||`working tree`}`,Be=(e,t,n,r)=>{let i=a(`button`,`icon-btn ${n?`bg-indigo-50 text-indigo-700 hover:bg-indigo-100 hover:text-indigo-700`:``}`);return i.append(h(e)),i.title=t,i.setAttribute(`aria-label`,t),i.setAttribute(`aria-pressed`,String(n)),i.onclick=r,i};function X(){let e=Be(se,`Show only files that differ`,T,()=>{T=!T,X(),H()}),t=Be(oe,E?`Restore folders`:`Collapse all folders`,E,()=>{if(E=!E,E)D=[...O],O.clear();else for(let e of D)O.add(e);X(),H()});if(!b.branch){M.replaceChildren(a(`div`,`flex items-center gap-1.5`,a(`span`,`min-w-0 flex-1 text-[11px] leading-snug text-neutral-400`,`Not a git repository — nothing to compare.`),t));return}let n=re(ze(),`${ne} font-mono`);if(Y()){let e=b.commits.find(e=>e.hash===Y());ue(n,()=>e?le(e):``)}else n.title=`Choose what to diff`;n.onclick=async()=>{await We(),de(n,b,{base:x,head:S},(e,t)=>{x=e,S=t,Z()},$())};let[r,i]=[0,0];for(let e of w.values())r+=e.add,i+=e.del;M.replaceChildren(n,a(`div`,`flex items-center gap-1.5 pl-0.5`,a(`span`,`text-[11px] text-neutral-400`,`${w.size} changed file${w.size===1?``:`s`}`),...U(r,i),a(`span`,`ml-auto`),e,t))}let Ve=()=>{y&&v&&he(y,{cwd:v,base:x,head:S})},He=e=>{let t=e.replace(/~\d+$/,``);return!t||t===`HEAD`||b.refs.some(e=>e.name===t)||b.commits.some(e=>e.hash===t)};async function Ue(){if(w=new Map,!b.branch)return;let{files:e}=await g(L(`diff`,{base:x,head:S}),`could not read what changed`);for(let t of e)w.set(t.path,{status:t.status,add:t.add,del:t.del});if(w.size<=pe)for(let e of w.keys()){let t=e.split(`/`);for(let e=1;e<t.length;e++)O.add(t.slice(0,e).join(`/`))}}async function Z(){Ve();try{await Ue()}catch(e){X(),N.replaceChildren(z(String(e),`text-red-600`));return}X(),H(),k&&J(k)}function Q(){let e=_e(``,`neutral`);e.className+=` max-w-72`,e.append(a(`span`,`truncate max-md:hidden`,v||`Choose a folder…`),a(`span`,`truncate md:hidden`,v?r(v):`Choose a folder…`)),e.title=v?`${v} — switch folder`:`Choose a folder`,e.onclick=()=>d(e,b.worktrees.map(e=>({path:e.path,...e.branch?{hint:e.branch}:{}})),v||void 0,ee);let n=a(`button`,`icon-btn ml-auto`,h(s));n.type=`button`,n.title=`Close Files`,n.setAttribute(`aria-label`,`Close Files`),n.onclick=_;let i=b.branch?[a(`span`,`${ge} bg-neutral-100 text-neutral-600`,h(ce),a(`span`,`truncate`,b.branch))]:[];ve.replaceChildren(t(`Files`),e,...i,n)}async function We(){if(v)try{b=await g(L(`git`,{}),`could not read this repository`),Q()}catch(e){F.replaceChildren(B(String(e)))}}let $=()=>b.refs.some(e=>e.name===`main`)?`main`:b.refs.some(e=>e.name===`master`)?`master`:`HEAD`;async function Ge(e){if(Q(),k=null,A=null,O.clear(),j=e||null,e){T=!1;let t=e.split(`/`);for(let e=1;e<t.length;e++)O.add(t.slice(0,e).join(`/`))}if(K(),F.classList.remove(`flex`,`flex-col`),W(),F.replaceChildren(B(`Select a file.`)),!v){M.replaceChildren(),N.replaceChildren(),F.replaceChildren(B(`No folder yet — pick one from the chip above.`));return}try{b=await g(L(`git`,{}),`could not read this repository`)}catch(e){b={branch:null,refs:[],commits:[],worktrees:[]},F.replaceChildren(B(String(e)))}let t=me(y),n=t&&t.cwd===v&&He(t.base)&&He(t.head)?t:null;x=n?.base??$(),S=n?.head??``,Q(),await Z()}return e(i,(e,t)=>{let n=c(),r=n?.id??``,i=new URLSearchParams(t).get(`select`)??void 0,a=e?.startsWith(`/`)?e:(r===y?v:``)||me(r)?.cwd||n?.cwd||``;if(a===v&&r===y&&N.childElementCount&&(!i||i===k)){Q(),We().then(Z);return}y=r,v=a,Ge(i)},()=>{K(),F.classList.remove(`flex`,`flex-col`),W(),F.replaceChildren(B(`Select a file.`))})}export{D as createExplorerView};
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tasks-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tasks-8l1M8EJU.js","assets/task-runs-DcORJXHU.js","assets/runs-DtvDXSfo.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={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`,"stroke-linejoin":`round`},t=([e,n,r])=>{let i=document.createElementNS(`http://www.w3.org/2000/svg`,e);return Object.keys(n).forEach(e=>{i.setAttribute(e,String(n[e]))}),r?.length&&r.forEach(e=>{let n=t(e);i.appendChild(n)}),i},n=(n,r={})=>t([`svg`,{...e,...r},n]),r=[[`path`,{d:`m12 19-7-7 7-7`}],[`path`,{d:`M19 12H5`}]],i=[[`path`,{d:`M7 7h10v10`}],[`path`,{d:`M7 17 17 7`}]],a=[[`path`,{d:`m5 12 7-7 7 7`}],[`path`,{d:`M12 19V5`}]],o=[[`path`,{d:`M20 6 9 17l-5-5`}]],s=[[`path`,{d:`m6 9 6 6 6-6`}]],c=[[`path`,{d:`m15 18-6-6 6-6`}]],l=[[`path`,{d:`m9 18 6-6-6-6`}]],u=[[`circle`,{cx:`12`,cy:`12`,r:`10`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`}],[`path`,{d:`M12 17h.01`}]],d=[[`circle`,{cx:`12`,cy:`12`,r:`10`}],[`path`,{d:`M12 6v6l4 2`}]],f=[[`path`,{d:`M20 4v7a4 4 0 0 1-4 4H4`}],[`path`,{d:`m9 10-5 5 5 5`}]],p=[[`path`,{d:`M12 15V3`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`}],[`path`,{d:`m7 10 5 5 5-5`}]],m=[[`circle`,{cx:`12`,cy:`12`,r:`1`}],[`circle`,{cx:`19`,cy:`12`,r:`1`}],[`circle`,{cx:`5`,cy:`12`,r:`1`}]],ee=[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`}]],te=[[`path`,{d:`M12 10v6`}],[`path`,{d:`M9 13h6`}],[`path`,{d:`M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z`}]],ne=[[`rect`,{width:`7`,height:`9`,x:`3`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`14`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`9`,x:`14`,y:`12`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`3`,y:`16`,rx:`1`}]],re=[[`path`,{d:`M13 5h8`}],[`path`,{d:`M13 12h8`}],[`path`,{d:`M13 19h8`}],[`path`,{d:`m3 17 2 2 4-4`}],[`rect`,{x:`3`,y:`4`,width:`6`,height:`6`,rx:`1`}]],ie=[[`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`}]],ae=[[`path`,{d:`M4 5h16`}],[`path`,{d:`M4 12h16`}],[`path`,{d:`M4 19h16`}]],oe=[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`}]],se=[[`path`,{d:`M5 12h14`}]],ce=[[`rect`,{width:`20`,height:`14`,x:`2`,y:`3`,rx:`2`}],[`line`,{x1:`8`,x2:`16`,y1:`21`,y2:`21`}],[`line`,{x1:`12`,x2:`12`,y1:`17`,y2:`21`}]],h=[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`}]],le=[[`rect`,{x:`14`,y:`3`,width:`5`,height:`18`,rx:`1`}],[`rect`,{x:`5`,y:`3`,width:`5`,height:`18`,rx:`1`}]],ue=[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`}],[`path`,{d:`m15 5 4 4`}]],de=[[`path`,{d:`M5 12h14`}],[`path`,{d:`M12 5v14`}]],fe=[[`path`,{d:`M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8`}],[`path`,{d:`M21 3v5h-5`}]],pe=[[`path`,{d:`m21 21-4.34-4.34`}],[`circle`,{cx:`11`,cy:`11`,r:`8`}]],me=[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`}],[`circle`,{cx:`12`,cy:`12`,r:`3`}]],he=[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`}]],ge=[[`circle`,{cx:`12`,cy:`12`,r:`4`}],[`path`,{d:`M12 2v2`}],[`path`,{d:`M12 20v2`}],[`path`,{d:`m4.93 4.93 1.41 1.41`}],[`path`,{d:`m17.66 17.66 1.41 1.41`}],[`path`,{d:`M2 12h2`}],[`path`,{d:`M20 12h2`}],[`path`,{d:`m6.34 17.66-1.41 1.41`}],[`path`,{d:`m19.07 4.93-1.41 1.41`}]],_e=[[`path`,{d:`M9 14 4 9l5-5`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`}]],ve=[[`path`,{d:`M18 6 6 18`}],[`path`,{d:`m6 6 12 12`}]],g=(e,t=`h-3.5 w-3.5`)=>n(e,{class:`flex-none ${t}`,"aria-hidden":`true`,focusable:`false`});function ye(){let e={ArrowUp:a,ChevronLeft:c,ChevronRight:l,Clock:d,Ellipsis:m,LayoutDashboard:ne,ListTodo:re,Menu:ae,Plus:de,RotateCw:fe,Search:pe,Settings:me,Square:he,Undo2:_e,X:ve};for(let t of document.querySelectorAll(`[data-icon]`)){let n=e[t.dataset.icon];if(!n)throw Error(`Unknown shell icon: ${t.dataset.icon}`);t.replaceChildren(g(n,`h-full w-full`))}let t=g(s);t.setAttribute(`stroke`,`#737373`),document.documentElement.style.setProperty(`--select-chevron`,`url("data:image/svg+xml,${encodeURIComponent(t.outerHTML)}")`)}var be=/[\u201c\u201d"\u2018\u2019'()\uff08\uff09\u300c\u300d\u300e\u300f\u3010\u3011\u300a\u300b\u3008\u3009[\]]/;function xe(e){let t=[],n=e=>`\uE010${t.push(e)-1}\uE011`,r=e.replace(/```[\s\S]*?```/g,e=>n(e)).replace(/`[^`\n]+`/g,e=>n(e));return r=r.replace(/\*\*(\S|\S[\s\S]*?\S)\*\*/g,(e,t)=>{let n=``,r=``,i=t;for(;i.length>1&&be.test(i[0]);)n+=i[0],i=i.slice(1);for(;i.length>1&&be.test(i.at(-1));)r=i.at(-1)+r,i=i.slice(0,-1);return n||r?`${n}**${i}**${r}`:e}),r.replace(/\uE010(\d+)\uE011/g,(e,n)=>t[Number(n)]??``)}var _=e=>!e.text.trim()&&e.suggestions.length===0,Se=e=>e===`xhigh`?`Extra high`:e[0].toUpperCase()+e.slice(1),Ce=e=>{if(e<1e3)return String(e);let t=e/1e3;return t>=9.95?`${Math.round(t)}K`:`${t.toFixed(1)}K`},we=/(?:^|\n)[ \t]*-{3,}[ \t]*\r?\n((?:[ \t]*\[[^\]\r\n]+\][ \t]*(?:[||][ \t]*)?)+)\s*$/,Te=/\[([^\]\r\n]+)\]/g,Ee=5,De=String.raw`[\u200B-\u200D\u2060\uFEFF]*`,Oe=e=>e.split(``).join(De),ke=RegExp(`${Oe(`<silent>`)}([\\s\\S]*?)${Oe(`</silent>`)}`,`gi`),Ae=RegExp(`<(\\/?)${Oe(`silent>`)}`,`gi`);function v(e){let t=[...e.matchAll(ke)].map(e=>(e[1]??``).trim()).filter(Boolean);return t.length?t.join(` · `):void 0}function je(e,t){let n=y(e),r=v(e),i=we.exec(n);if(!i?.[1])return{text:n,suggestions:[],meta:t,silence:r};let a=[...i[1].matchAll(Te)].map(e=>(e[1]??``).trim()).filter(Boolean).slice(0,Ee);return a.length?{text:n.slice(0,i.index).trimEnd(),suggestions:a,meta:t,silence:r}:{text:n,suggestions:[],meta:t,silence:r}}var y=e=>xe(e.replace(ke,``).trim()),Me=/^(?:\s|[-*+>]|\d+[.)])/;function Ne(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&&!(Me.test(s)&&Me.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(Ae))i=!e[1];o=-1,s=n}return a}var Pe=String.raw`(?<when>(?:\d{4}-\d{2}-\d{2} )?\d{1,2}:\d{2})`,Fe=new RegExp(String.raw`^\[(?:(?<name>[^\n[\]<>]*)<(?<id>[^\n[\]<>]+)>)? ?${Pe}? ?(?<where>[a-z]+:[^\s[\]<>]+)?\]\n`),Ie=new RegExp(String.raw`^\[(?<name>[^\n[\]<>]*?) ${Pe}(?: (?<where>[a-z]+))?\]\n`);function Le(e){let t=Fe.exec(e),{id:n,when:r,where:i}=t?.groups??{},a=n||r||i?t:Ie.exec(e);return a?.groups?{...a.groups.name?{name:a.groups.name}:{},...a.groups.id?{id:a.groups.id}:{},...a.groups.when?{when:a.groups.when}:{},...a.groups.where?{where:a.groups.where}:{},text:e.slice(a[0].length)}:{text:e}}var Re=/(?:\n\[[^\]\n]*(?:\]\(\s*<?file:\/\/[^\n]*|$))+$/,ze=/^\s*`[^`\n]{40,}`\s+(\S[\s\S]*)$/;function Be(e){if(!e)return e;let{text:t}=Le(e);return t===e?e:t.replace(Re,``).replace(ze,`$1`).replace(/\s+/g,` `).trim()||e}var Ve=e=>[...new Set([...e].sort((e,t)=>t.createdAt-e.createdAt).map(e=>e.cwd))];function He(e){let t=Ve(e),n=new Set(t);return t.filter(e=>{let t=e.lastIndexOf(`/`),r=e.indexOf(`.`,t+2);return r<0||!n.has(e.slice(0,r))})}function Ue(e){let t,n=!1;return()=>(n=!0,t??=(async()=>{for(;n;)n=!1,await e()})().finally(()=>{t=void 0}))}var We=(e,t)=>({method:t,headers:{"content-type":`application/json`},body:JSON.stringify(e)}),b=(e,t,n=`POST`)=>fetch(e,We(t,n)),Ge=(e,t,n,r=`POST`)=>S(e,n,We(t,r));async function x(e,t){return(await e.json().catch(()=>({}))).error??`${t} (${e.status})`}async function S(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 x(r,t)};try{return{ok:!0,value:await r.json()}}catch(e){return{ok:!1,error:`${t}: ${String(e)}`}}}async function Ke(e,t,n){let r=await S(e,t,n);if(!r.ok)throw Error(r.error);return r.value}async function qe(e,t,n){try{let r=await fetch(e,{method:t});return r.ok?void 0:await x(r,n)}catch(e){return`${n}: ${String(e)}`}}function Je(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 Ye(e){if(Array.isArray(e))return e}function Xe(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 Ze(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
@@ -71,7 +71,7 @@ Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error
|
|
|
71
71
|
`)){let e=Li.exec(i)?.[1];if(n!==void 0)t.push([r,r+i.length]),e&&e[0]===n[0]&&e.length>=n.length&&(n=void 0);else if(e)n=e,t.push([r,r+i.length]);else{let e=[...i.matchAll(/`+/g)];for(let n=0;n<e.length;n++){let i=e[n],a=n+1;for(;a<e.length&&e[a][0].length!==i[0].length;)a++;if(a===e.length)break;t.push([r+i.index,r+e[a].index+e[a][0].length]),n=a}}r+=i.length+1}return t}function zi(e,t,n){let r=Ri(e),i=``,a=0;for(let o of e.matchAll(t)){let t=o.index,s=t+o[0].length;r.some(([e,n])=>t<n&&s>e)||(i+=e.slice(a,t)+n(o),a=s)}return i+e.slice(a)}var Bi=/^\[[^\]\n]*\]\(\s*<?file:\/\/(\/[^)>\s]*)>?\s*\)$/;function Vi(e){let t=e.split(`
|
|
72
72
|
`),n=t.length;for(;n>0&&Bi.test(t[n-1].trim());)n--;let r=t.slice(n).map(e=>{let t=Bi.exec(e.trim())[1];try{return decodeURIComponent(t)}catch{return t}});return{text:t.slice(0,n).join(`
|
|
73
73
|
`).trimEnd(),paths:r}}var Hi=`modulepreload`,Ui=function(e){return`/app/`+e},Wi={},Gi=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Ui(t,n),t=s(t),t in Wi)return;Wi[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:Hi,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Ki,qi;function Ji(){return qi??=Gi(()=>import(`./hljs-tWqyD59G.js`).then(e=>Ki=e.default,e=>{console.warn(`highlighting unavailable — code stays plain text`,e)}),[]),qi}async function Yi(e){let t=await Ji();if(t)for(let n of e.querySelectorAll(`pre code[class]`)){let e=/(?:language|lang)-(\S+)/.exec(n.className)?.[1]?.toLowerCase();!e||!t.getLanguage(e)||(n.innerHTML=t.highlight(n.textContent??``,{language:e}).value)}}var Xi={ts:`typescript`,tsx:`typescript`,mts:`typescript`,cts:`typescript`,js:`javascript`,jsx:`javascript`,mjs:`javascript`,cjs:`javascript`,py:`python`,rs:`rust`,sh:`bash`,zsh:`bash`,md:`markdown`,yml:`yaml`,html:`xml`,htm:`xml`,svg:`xml`,patch:`diff`};async function Zi(e){let t=await Ji(),n=e.split(`.`).pop()?.toLowerCase()??``,r=Xi[n]??n;return t?.getLanguage(r)?r:null}function Qi(e,t){let n=document.createElement(`span`);return Ki&&t&&e.length<=500?n.innerHTML=Ki.highlight(e,{language:t}).value:n.textContent=e,n}var $i=2e4;function ea(e){let t=e.split(`
|
|
74
|
-
`);return t.at(-1)===``&&t.pop(),t.map((e,t)=>({nums:[t+1],text:e,tone:``}))}function ta(e,t){let n=e.length<=$i?t:null,r=Math.max(2,...e.map(e=>e.nums.reduce((e,t)=>Math.max(e,String(t).length),0))),i=I(`div`,`py-2 font-mono text-[12px] leading-[1.5]`);for(let t of e){let e=I(`div`,`flex pl-2 pr-4 ${t.tone===`add`?`bg-emerald-50`:t.tone===`del`?`bg-red-50`:``}`);for(let n of t.nums){let t=I(`span`,`flex-none select-none pr-1.5 text-right text-neutral-300`,n===``?``:String(n));t.style.width=`calc(${r}ch + 0.375rem)`,e.append(t)}t.nums.length===1&&typeof t.nums[0]==`number`&&(e.dataset.line=String(t.nums[0])),e.append(na(t,n)),i.append(e)}return i}function na(e,t){let n=`min-w-0 flex-1 whitespace-pre-wrap [overflow-wrap:anywhere]`;if(!e.mark||e.mark[0]>=e.mark[1]){let r=Qi(e.text,t);return r.className=n,r}let[r,i]=e.mark,a=Qi(e.text.slice(r,i),t);return a.className=`rounded-xs ${e.tone===`add`?`bg-emerald-200/80`:`bg-red-200/70`}`,I(`span`,n,Qi(e.text.slice(0,r),t),a,Qi(e.text.slice(i),t))}var z=null,ra=null,ia=null;function aa(e){z&&!z.contains(e.target)&&e.target!==ia&&B()}var oa={ArrowDown:1,ArrowUp:-1},sa={n:1,j:1,p:-1,k:-1},ca=()=>z!==null;function la(e){if(!(e.altKey||e.metaKey||e.shiftKey||!e.key))return e.ctrlKey?sa[e.key.toLowerCase()]:oa[e.key]}function ua(e,t){let n=[...e.querySelectorAll(`button:not(:disabled)`)];if(!n.length)return!1;let r=n.indexOf(document.activeElement);return n[t===`first`?0:t===`last`?n.length-1:r<0?t>0?0:n.length-1:(r+t+n.length)%n.length]?.focus(),!0}function da(e){if(e.dataset.menu===`true`)return{rows:e,ends:!0};let t=e.querySelector(`[data-list]`);return t?{rows:t,ends:!1}:null}function fa(e){let t=z?da(z):null;if(t){let n=(t.ends?e.key===`Home`?`first`:e.key===`End`?`last`:void 0:void 0)??la(e);if(n!==void 0&&ua(t.rows,n)){e.preventDefault();return}}e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),B())}function pa(e){z&&!z.contains(e.target)&&B()}function B(){if(!z)return;document.removeEventListener(`pointerdown`,aa,!0),document.removeEventListener(`focusin`,aa,!0),document.removeEventListener(`keydown`,fa,!0),window.removeEventListener(`scroll`,pa,!0),window.removeEventListener(`resize`,B);let e=z;z=null,ia?.remove(),ia=null,e.contains(document.activeElement)&&ra?.focus({preventScroll:!0}),ra?.removeAttribute(`aria-expanded`),ra=null,e.inert=!0,e.dataset.closing=``,Promise.allSettled(e.getAnimations().map(e=>e.finished)).then(()=>e.remove())}var ma=null;function ha(e){let t=e.getBoundingClientRect(),n={top:t.bottom+4,left:t.left};return t.width||t.height?n:ma?.anchor===e?{top:ma.top,left:ma.left}:n}var ga=()=>window.innerWidth<640;function _a(e,t){B(),document.querySelectorAll(`.glass-menu[data-closing]`).forEach(e=>e.remove());let n=ga();z=I(`div`,`glass-menu fixed z-50 border border-neutral-200 p-2 font-sans leading-6 ${n?`rounded-3xl inset-x-2 bottom-2 max-h-[70dvh] overflow-y-auto pb-[calc(0.25rem+env(safe-area-inset-bottom))] text-[16px]`:`rounded-2xl min-w-60 max-w-[min(42rem,calc(100vw-1rem))] max-h-[calc(100dvh-1rem)] overflow-y-auto text-[15px]`}`),z.dataset.presentation=n?`sheet`:`popover`,z.append(t);let r=e.closest(`dialog[open]`)??document.body;if(n&&(ia=I(`div`,`fixed inset-0 z-50 bg-black/15`),ia.onclick=e=>{e.stopPropagation(),B()},r.append(ia)),r.append(z),!n){let t=ha(e);ma={anchor:e,...t},z.style.top=`${Math.max(8,Math.min(t.top,window.innerHeight-z.offsetHeight-8))}px`,z.style.left=`${Math.max(8,Math.min(t.left,window.innerWidth-z.offsetWidth-8))}px`}return ra=e,ra.setAttribute(`aria-expanded`,`true`),z.tabIndex=-1,(z.querySelector(`button, input, select, [tabindex='0']`)??z).focus({preventScroll:!0}),document.addEventListener(`pointerdown`,aa,!0),document.addEventListener(`focusin`,aa,!0),document.addEventListener(`keydown`,fa,!0),window.addEventListener(`scroll`,pa,!0),window.addEventListener(`resize`,B),z}function va(e){let t=I(`button`,`flex w-full cursor-pointer items-center gap-2 rounded-xl px-3 text-left transition-colors hover:bg-indigo-50 hover:text-indigo-700 active:bg-indigo-100 ${ga()?`min-h-12 py-3`:`min-h-10 py-2`}`,...e.checked===void 0?[]:[g(o,`h-3 w-3 text-indigo-600 ${e.checked?``:`invisible`}`)],I(`span`,`min-w-0 truncate`,e.label));if(e.hint){let n=I(`span`,`ml-auto max-w-28 shrink-[999] truncate text-[13px] text-neutral-500`,e.hint);n.title=e.hint,t.append(n)}return e.disabled&&(t.disabled=!0,t.classList.add(`cursor-default`,`text-neutral-400`,`hover:bg-transparent`,`hover:text-neutral-400`)),t.onclick=()=>e.onSelect(),t}function ya(e,t,n){let r=I(`div`,``);if(n&&ga()){let e=I(`button`,`icon-btn h-11 w-11`,g(ve));e.setAttribute(`aria-label`,`Close session actions`),e.onclick=B,r.append(I(`div`,`flex items-center gap-3 border-b border-neutral-200 px-3 pb-1 mb-1`,I(`span`,`min-w-0 flex-1 truncate text-sm font-medium text-neutral-500`,n),e))}for(let e of t)e.separatorBefore&&r.append(I(`hr`,`my-2 border-neutral-200`)),r.append(va(e));_a(e,r),z&&(z.dataset.menu=`true`,z.setAttribute(`aria-label`,n?`Actions for ${n}`:`Actions`),z.setAttribute(`role`,`group`))}var ba=async e=>{let t=await S(`/api/fs/ls${e?.startsWith(`/`)?`?path=${encodeURIComponent(e)}`:``}`,`Could not list directories`);return t.ok?t.value:null},xa=e=>e.entries.filter(e=>e.dir&&!e.name.startsWith(`.`)).map(e=>e.name),Sa=`flex w-full min-h-10 cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left transition-colors hover:bg-indigo-50 hover:text-indigo-700 active:bg-indigo-100`,Ca=`font-mono text-[0.875rem]`,wa=(e,t,n)=>{let r=L(e,`${Sa} ${t}`);return r.onclick=n,r};function Ta(e,t){let n=I(`div`,`mt-2 flex-none border-t border-neutral-200 pt-2`),r=wa(`New folder`,`text-neutral-500`,()=>{let r=document.createElement(`input`);r.className=`w-full rounded-xl border-0 bg-neutral-100 px-3 py-2 ${Ca} focus:outline-none`,r.placeholder=`folder-name`;let i=I(`p`,`hidden px-3 pt-1 text-[0.8125rem] text-red-600`);r.onkeydown=async n=>{if(n.key!==`Enter`)return;n.preventDefault();let a=await b(`/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 r.prepend(g(de)),n.append(r),n}function Ea(e,t,n){let r=e=>{n(e),B()};async function i(t){let n=await ba(t);if(!n)return;let a=I(`div`,`flex max-h-[60dvh] w-full flex-col sm:w-88`),o=L(`Use`,`btn btn-primary ml-auto flex-none px-3 py-1 text-[0.8125rem]`);o.onclick=()=>r(n.path);let s=document.createElement(`input`);s.className=`min-w-0 flex-1 border-0 bg-transparent ${Ca} text-neutral-600 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=I(`p`,`hidden flex-none px-3 pb-1 text-[0.8125rem] 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 ba(t);if(!n){c.textContent=`${t} is not a folder this can read`,c.classList.remove(`hidden`);return}r(n.path)};let l=I(`div`,`mb-2 flex flex-none items-center gap-2 border-b border-neutral-200 px-3 pb-2 pt-1`,s,o),u=I(`div`,`min-h-0 flex-1 overflow-y-auto`);u.dataset.list=``,n.parent&&u.append(wa(`../`,`${Ca} text-neutral-500`,()=>void i(n.parent)));let d=xa(n);for(let e of d)u.append(wa(e,`truncate`,()=>void i(`${n.path}/${e}`.replace(`//`,`/`))));d.length||u.append(I(`p`,`px-3 py-2 text-[0.8125rem] text-neutral-400`,`No sub-folders.`)),a.append(l,c,u,Ta(n.path,e=>void i(e))),_a(e,a)}i(t)}function Da(e,t,n,r){ya(e,[...t.map(e=>({label:e.path,...e.hint?{hint:e.hint}:{},checked:e.path===n,onSelect:()=>{B(),r(e.path)}})),{label:`Browse…`,onSelect:()=>Ea(e,n||void 0,r)}])}var Oa=(e,t)=>n=>{e.value=n,e.dispatchEvent(new Event(`input`,{bubbles:!0})),t?.(n)};function ka(e,t){let n=L(`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=()=>Ea(n,e.value.trim()||void 0,Oa(e,t)),n}function Aa(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:I(`div`,`flex items-center gap-1.5`,r,ka(r,n)),input:r}}var ja=F(`#image-dialog`),V=F(`#image-stage`),Ma=F(`#image-full`),Na=F(`#image-prev`),Pa=F(`#image-next`),Fa=F(`#image-close`),Ia=[],La=0;function Ra(e){Ia.length<2||(La=(La+e+Ia.length)%Ia.length,Va(!1),Ma.src=Ia[La])}var za=2.5,Ba=()=>V.dataset.zoom!==void 0;function Va(e,t){if(!e){delete V.dataset.zoom,Ma.style.cssText=``;return}let n=Ma.getBoundingClientRect(),r=V.getBoundingClientRect(),i=t?(t.x-n.left)/n.width:.5,a=t?(t.y-n.top)/n.height:.5,o=n.width*za,s=n.height*za;V.dataset.zoom=``,Ma.style.width=`${String(o)}px`,Ma.style.height=`${String(s)}px`,V.scrollLeft=i*o-r.width/2,V.scrollTop=a*s-r.height/2}function Ha(e){let t=e.closest(`[data-gallery]`);Ia=t?[...t.querySelectorAll(`img.thumb`)].map(e=>e.src):[e.src],La=Math.max(0,Ia.indexOf(e.src)),Ma.src=e.src;let n=Ia.length<2?`none`:`flex`;Na.style.display=n,Pa.style.display=n,ja.showModal()}var Ua=4,Wa,Ga=!1;V.onpointerdown=e=>{Ga=!1,!(!Ba()||e.button!==0)&&(Wa={x:e.clientX,y:e.clientY,left:V.scrollLeft,top:V.scrollTop},V.setPointerCapture(e.pointerId))},V.onpointermove=e=>{if(!Wa)return;let t=e.clientX-Wa.x,n=e.clientY-Wa.y;(Math.abs(t)>Ua||Math.abs(n)>Ua)&&(Ga=!0),V.scrollLeft=Wa.left-t,V.scrollTop=Wa.top-n};var Ka=()=>{Wa=void 0};V.onpointerup=Ka,V.onpointercancel=Ka,V.onclick=e=>{Ga||(e.target===Ma?Va(!Ba(),{x:e.clientX,y:e.clientY}):ja.close())},Fa.onclick=()=>ja.close(),ja.onclose=()=>Va(!1),Na.onclick=()=>Ra(-1),Pa.onclick=()=>Ra(1),ja.onkeydown=e=>{(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),Ra(e.key===`ArrowLeft`?-1:1))};function qa(e){let t=e.querySelector(`:scope > .thumbs`);if(t)return t;let n=I(`div`,`thumbs`);return e.append(n),n}function Ja(e){let t=document.createElement(`img`);return t.src=e,t.loading=`lazy`,t.className=`thumb`,t.onclick=()=>Ha(t),t}var Ya=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`avif`,`bmp`]),Xa=524288,Za=F(`#file-dialog`),Qa=F(`#file-name`),$a=F(`#file-text`),eo=F(`#file-download`);F(`#file-close`).onclick=()=>Za.close();var to=e=>e.split(`.`).pop()?.toLowerCase()??``,no=(e,t,n=!1)=>`/api/sessions/${encodeURIComponent(e)}/files?path=${encodeURIComponent(t)}${n?`&download=1`:``}`,ro=e=>decodeURIComponent(/^\/api\/sessions\/([^/]+)\//.exec(e)?.[1]??``),io=e=>e.slice(0,e.lastIndexOf(`/`))||`/`,ao=(e,t)=>`${e===`/`?``:e}/${t}`;function oo(e,t){return zi(e,/\]\(\s*<?file:\/\/(\/[^)>\s]*)>?\s*\)/g,e=>{let n=e[1];try{n=decodeURIComponent(n)}catch{}return`](${no(t,n)})`})}var so=e=>/^\/api\/sessions\/[^/]+\/files\?/.test(e);function co(e,t){let n=Zr(t)||`file`,r=no(e,t);return Ya.has(to(n))?Co(r,n):wo(r,n)}function lo(e){return new URLSearchParams(e.slice(e.indexOf(`?`)+1)).get(`path`)??``}var uo=(e,t=`text-neutral-500`)=>I(`div`,`px-3 py-2 text-[12.5px] [overflow-wrap:anywhere] ${t}`,e),fo=0;function po(e,t,n){if(eo.hidden=n,n){Qa.replaceChildren(t);return}let r=io(t),i=L(`${r}/`,`min-w-0 cursor-pointer truncate text-neutral-400 hover:text-indigo-600`);i.title=`Browse ${r}`,i.onclick=()=>void ho(e,r),Qa.replaceChildren(i,I(`span`,`flex-none`,Zr(t)))}function mo(e,t){let n=I(`div`,`flex flex-col py-1`),r=(e,t,n)=>{let r=L(e,`flex w-full cursor-pointer items-center px-3 py-1.5 text-left font-mono text-[12.5px] hover:bg-indigo-50 hover:text-indigo-700 ${t}`);return r.onclick=n,r};t.parent&&n.append(r(`../`,`text-neutral-500`,()=>void ho(e,t.parent)));for(let i of t.entries){let a=ao(t.path,i.name);n.append(i.dir?r(`${i.name}/`,`text-neutral-800`,()=>void ho(e,a)):r(i.name,`text-neutral-600`,()=>void go(no(e,a),i.name)))}return t.entries.length||n.append(uo(`Empty folder.`)),n}async function ho(e,t){let n=++fo;po(e,t,!0),$a.replaceChildren(uo(`loading…`)),Za.open||Za.showModal();let r=await ba(t);n===fo&&$a.replaceChildren(r?mo(e,r):uo(`failed to list: ${t}`,`text-red-600`))}async function go(e,t,n){let r=++fo;po(ro(e),lo(e)||t,!1),eo.href=`${e}&download=1`,$a.replaceChildren(uo(`loading…`)),Za.open||Za.showModal();let i=e=>{r===fo&&$a.replaceChildren(e)},a;try{a=await fetch(e)}catch(e){return i(uo(`failed to load: ${String(e)}`,`text-red-600`))}if(!a.ok){let t=lo(e),n=a.status===404?await ba(t):null;return r===fo?n?void ho(ro(e),t):i(uo(`${await x(a,`failed to load`)}: ${t}`,`text-red-600`)):void 0}let o=a.headers.get(`content-type`)??``;if(!o.startsWith(`text/`)&&!o.startsWith(`image/svg+xml`))return i(uo(`Binary file — use Download.`));let s=await a.text(),c=s.length>Xa?`${s.slice(0,Xa)}\n…`:s,l=await Zi(t),u=ta(ea(c),l);if(i(u),n===void 0||r!==fo)return;let d=u.querySelector(`[data-line="${String(n)}"]`);d?.classList.add(`bg-indigo-100`),d?.scrollIntoView({block:`center`})}var _o=new Set(`ts.tsx.mts.cts.js.jsx.mjs.cjs.json.md.css.html.py.rs.go.rb.java.c.h.cpp.hpp.sh.sql.yml.yaml.toml.ini.conf.txt.lock`.split(`.`)),vo=/^(?:~|\/(?:home|Users|root|tmp|var|opt|etc|srv|mnt|media|data|usr))(?:\/|$)/;function yo(e){let t=/^([^\s`"'()[\]{}<>]+?)(?::(\d+))?(?::\d+)?$/.exec(e);if(!t||e.includes(`://`))return null;let n=t[1],r=n.includes(`.`)?to(n):``;return!vo.test(n)&&(!r||!_o.has(r)&&!n.includes(`/`))?null:{path:n,line:t[2]===void 0?void 0:Number(t[2])}}var bo;async function xo(e,t,n){let r=t;r.startsWith(`~`)&&(bo??=ba().then(e=>e?.path??null),r=`${await bo??`~`}${r.slice(1)}`),await go(no(e,r),Zr(r),n)}function So(e,t,n){for(let r of e.querySelectorAll(`:not(pre) > code`)){let e=yo(r.textContent?.trim()??``);if(!e||r.closest(`a`))continue;let i=e.path.startsWith(`/`)||e.path.startsWith(`~`)?e.path:n?`${n}/${e.path}`:null;if(!i)continue;let a=()=>void xo(t,i,e.line);r.classList.add(`fileref`),r.tabIndex=0,r.setAttribute(`role`,`button`),r.title=e.line===void 0?i:`${i}:${String(e.line)}`,r.onclick=a,r.addEventListener(`pointerup`,()=>r.blur()),r.onkeydown=e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),a())}}}function Co(e,t){let n=Ja(e);return n.alt=t,n}function wo(e,t){let n=to(t),r=I(`span`,`inline-flex max-w-full items-center gap-2.5 rounded-lg border border-neutral-200 bg-neutral-50 px-2.5 py-1.5 no-underline`),i=I(`span`,`flex h-7 w-7 flex-none items-center justify-center rounded-md bg-indigo-50 text-[10px] font-semibold uppercase text-indigo-600`,n.slice(0,4)||`file`),a=I(`span`,`min-w-0 truncate text-[13px] font-medium text-neutral-800`,t),o=I(`span`,`ml-1 flex flex-none items-center gap-0.5`),s=I(`button`,`icon-btn h-6 w-6 text-[13px]`,g(ee));s.setAttribute(`aria-label`,`Preview`),s.title=`Preview`,s.onclick=r=>{r.preventDefault(),n===`pdf`?window.open(e,`_blank`,`noopener`):go(e,t)},o.append(s);let c=document.createElement(`a`);return c.className=`icon-btn h-6 w-6 text-[13px] no-underline`,c.href=`${e}&download=1`,c.download=t,c.title=`Download`,c.append(g(p)),c.setAttribute(`aria-label`,`Download`),o.append(c),r.append(i,a,o),r}function To(e){let t=new Set;for(let n of e)n.parentElement&&t.add(n.parentElement);for(let n of t){let t=[...n.children].filter(t=>e.includes(t));if([...n.childNodes].every(e=>e.nodeType===Node.TEXT_NODE?!e.textContent?.trim():t.includes(e))){n.classList.add(`thumbs`);continue}let r=I(`div`,`thumbs`);r.append(...t),n.after(r)}}function Eo(e){let t=[];for(let n of e.querySelectorAll(`img`)){let e=n.getAttribute(`src`)??``;if(!so(e))continue;let r=Co(e,Zr(lo(e)));n.replaceWith(r),t.push(r)}for(let n of e.querySelectorAll(`a`)){let e=n.getAttribute(`href`)??``;if(!so(e))continue;let r=Zr(lo(e))||n.textContent?.trim()||`file`,i=Ya.has(to(r))?Co(e,r):wo(e,r);n.replaceWith(i),t.push(i)}t.length&&To(t)}var Do=null,Oo=`max-w-full cursor-pointer break-words rounded-full border border-indigo-200 bg-indigo-50 px-2.5 py-0.5 text-left text-[12.5px] text-indigo-700 transition-colors hover:border-indigo-300 hover:bg-indigo-100`;function ko(){Do=null}function Ao(e,t,n){if(Do?.remove(),Do=null,!t.length)return;let r=I(`div`,`mt-1.5 flex flex-wrap gap-1.5`);for(let e of t){let t=I(`button`,Oo,e);t.type=`button`,t.onclick=()=>{Do===r&&(Do=null),r.remove(),n(e)},r.append(t)}e.append(r),Do=r}var jo=8e3,Mo=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],No=e=>typeof e==`string`&&Mo.includes(e),Po,Fo;function Io(e,t){Po=e,Fo=t}var Lo=e=>e.slice(0,8),Ro=e=>`system-card group relative mt-1.5 rounded-xl px-4 py-2.5 ${e}`,zo=e=>I(`div`,Ro(e));function Bo(e){let t=e.length>240||e.split(`
|
|
74
|
+
`);return t.at(-1)===``&&t.pop(),t.map((e,t)=>({nums:[t+1],text:e,tone:``}))}function ta(e,t){let n=e.length<=$i?t:null,r=Math.max(2,...e.map(e=>e.nums.reduce((e,t)=>Math.max(e,String(t).length),0))),i=I(`div`,`py-2 font-mono text-[12px] leading-[1.5]`);for(let t of e){let e=I(`div`,`flex pl-2 pr-4 ${t.tone===`add`?`bg-emerald-50`:t.tone===`del`?`bg-red-50`:``}`);for(let n of t.nums){let t=I(`span`,`flex-none select-none pr-1.5 text-right text-neutral-300`,n===``?``:String(n));t.style.width=`calc(${r}ch + 0.375rem)`,e.append(t)}t.nums.length===1&&typeof t.nums[0]==`number`&&(e.dataset.line=String(t.nums[0])),e.append(na(t,n)),i.append(e)}return i}function na(e,t){let n=`min-w-0 flex-1 whitespace-pre-wrap [overflow-wrap:anywhere]`;if(!e.mark||e.mark[0]>=e.mark[1]){let r=Qi(e.text,t);return r.className=n,r}let[r,i]=e.mark,a=Qi(e.text.slice(r,i),t);return a.className=`rounded-xs ${e.tone===`add`?`bg-emerald-200/80`:`bg-red-200/70`}`,I(`span`,n,Qi(e.text.slice(0,r),t),a,Qi(e.text.slice(i),t))}var z=null,ra=null,ia=null;function aa(e){z&&!z.contains(e.target)&&e.target!==ia&&B()}var oa={ArrowDown:1,ArrowUp:-1},sa={n:1,j:1,p:-1,k:-1},ca=()=>z!==null;function la(e){if(!(e.altKey||e.metaKey||e.shiftKey||!e.key))return e.ctrlKey?sa[e.key.toLowerCase()]:oa[e.key]}function ua(e,t){let n=[...e.querySelectorAll(`button:not(:disabled)`)];if(!n.length)return!1;let r=n.indexOf(document.activeElement);return n[t===`first`?0:t===`last`?n.length-1:r<0?t>0?0:n.length-1:(r+t+n.length)%n.length]?.focus(),!0}function da(e){if(e.dataset.menu===`true`)return{rows:e,ends:!0};let t=e.querySelector(`[data-list]`);return t?{rows:t,ends:!1}:null}function fa(e){let t=z?da(z):null;if(t){let n=(t.ends?e.key===`Home`?`first`:e.key===`End`?`last`:void 0:void 0)??la(e);if(n!==void 0&&ua(t.rows,n)){e.preventDefault();return}}e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),B())}function pa(e){z&&!z.contains(e.target)&&B()}function B(){if(!z)return;document.removeEventListener(`pointerdown`,aa,!0),document.removeEventListener(`focusin`,aa,!0),document.removeEventListener(`keydown`,fa,!0),window.removeEventListener(`scroll`,pa,!0),window.removeEventListener(`resize`,B);let e=z;z=null,ia?.remove(),ia=null,e.contains(document.activeElement)&&ra?.focus({preventScroll:!0}),ra?.removeAttribute(`aria-expanded`),ra=null,e.inert=!0,e.dataset.closing=``,Promise.allSettled(e.getAnimations().map(e=>e.finished)).then(()=>e.remove())}var ma=null;function ha(e){let t=e.getBoundingClientRect(),n={top:t.bottom+4,left:t.left};return t.width||t.height?n:ma?.anchor===e?{top:ma.top,left:ma.left}:n}var ga=()=>window.innerWidth<640;function _a(e,t){B(),document.querySelectorAll(`.glass-menu[data-closing]`).forEach(e=>e.remove());let n=ga();z=I(`div`,`glass-menu fixed z-50 border border-neutral-200 p-2 font-sans leading-6 ${n?`rounded-3xl inset-x-2 bottom-2 max-h-[70dvh] overflow-y-auto pb-[calc(0.25rem+env(safe-area-inset-bottom))] text-[16px]`:`rounded-2xl min-w-60 max-w-[min(42rem,calc(100vw-1rem))] max-h-[calc(100dvh-1rem)] overflow-y-auto text-[15px]`}`),z.dataset.presentation=n?`sheet`:`popover`,z.append(t);let r=e.closest(`dialog[open]`)??document.body;if(n&&(ia=I(`div`,`fixed inset-0 z-50 bg-black/15`),ia.onclick=e=>{e.stopPropagation(),B()},r.append(ia)),r.append(z),!n){let t=ha(e);ma={anchor:e,...t},z.style.top=`${Math.max(8,Math.min(t.top,window.innerHeight-z.offsetHeight-8))}px`,z.style.left=`${Math.max(8,Math.min(t.left,window.innerWidth-z.offsetWidth-8))}px`}return ra=e,ra.setAttribute(`aria-expanded`,`true`),z.tabIndex=-1,(z.querySelector(`button, input, select, [tabindex='0']`)??z).focus({preventScroll:!0}),document.addEventListener(`pointerdown`,aa,!0),document.addEventListener(`focusin`,aa,!0),document.addEventListener(`keydown`,fa,!0),window.addEventListener(`scroll`,pa,!0),window.addEventListener(`resize`,B),z}function va(e){let t=I(`button`,`flex w-full cursor-pointer items-center gap-2 rounded-xl px-3 text-left transition-colors hover:bg-indigo-50 hover:text-indigo-700 active:bg-indigo-100 ${ga()?`min-h-12 py-3`:`min-h-10 py-2`}`,...e.checked===void 0?[]:[g(o,`h-3 w-3 text-indigo-600 ${e.checked?``:`invisible`}`)],I(`span`,`min-w-0 truncate`,e.label));if(e.hint){let n=I(`span`,`ml-auto max-w-28 shrink-[999] truncate text-[13px] text-neutral-500`,e.hint);n.title=e.hint,t.append(n)}return e.disabled&&(t.disabled=!0,t.classList.add(`cursor-default`,`text-neutral-400`,`hover:bg-transparent`,`hover:text-neutral-400`)),t.onclick=()=>e.onSelect(),t}function ya(e,t,n){let r=I(`div`,``);if(n&&ga()){let e=I(`button`,`icon-btn h-11 w-11`,g(ve));e.setAttribute(`aria-label`,`Close session actions`),e.onclick=B,r.append(I(`div`,`flex items-center gap-3 border-b border-neutral-200 px-3 pb-1 mb-1`,I(`span`,`min-w-0 flex-1 truncate text-sm font-medium text-neutral-500`,n),e))}for(let e of t)e.separatorBefore&&r.append(I(`hr`,`my-2 border-neutral-200`)),r.append(va(e));_a(e,r),z&&(z.dataset.menu=`true`,z.setAttribute(`aria-label`,n?`Actions for ${n}`:`Actions`),z.setAttribute(`role`,`group`))}var ba=async e=>{let t=await S(`/api/fs/ls${e?.startsWith(`/`)?`?path=${encodeURIComponent(e)}`:``}`,`Could not list directories`);return t.ok?t.value:null},xa=e=>e.entries.filter(e=>e.dir&&!e.name.startsWith(`.`)).map(e=>e.name),Sa=`flex w-full min-h-10 cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left transition-colors hover:bg-indigo-50 hover:text-indigo-700 active:bg-indigo-100`,Ca=`font-mono text-[0.875rem]`,wa=(e,t,n)=>{let r=L(e,`${Sa} ${t}`);return r.onclick=n,r};function Ta(e,t){let n=I(`div`,`mt-2 flex-none border-t border-neutral-200 pt-2`),r=wa(`New folder`,`text-neutral-500`,()=>{let r=document.createElement(`input`);r.className=`w-full rounded-xl border-0 bg-neutral-100 px-3 py-2 ${Ca} focus:outline-none`,r.placeholder=`folder-name`;let i=I(`p`,`hidden px-3 pt-1 text-[0.8125rem] text-red-600`);r.onkeydown=async n=>{if(n.key!==`Enter`)return;n.preventDefault();let a=await b(`/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 r.prepend(g(de)),n.append(r),n}function Ea(e,t,n){let r=e=>{n(e),B()};async function i(t){let n=await ba(t);if(!n)return;let a=I(`div`,`flex max-h-[60dvh] w-full flex-col sm:w-88`),o=L(`Use`,`btn btn-primary ml-auto flex-none px-3 py-1 text-[0.8125rem]`);o.onclick=()=>r(n.path);let s=document.createElement(`input`);s.className=`min-w-0 flex-1 border-0 bg-transparent ${Ca} text-neutral-600 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=I(`p`,`hidden flex-none px-3 pb-1 text-[0.8125rem] 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 ba(t);if(!n){c.textContent=`${t} is not a folder this can read`,c.classList.remove(`hidden`);return}r(n.path)};let l=I(`div`,`mb-2 flex flex-none items-center gap-2 border-b border-neutral-200 px-3 pb-2 pt-1`,s,o),u=I(`div`,`min-h-0 flex-1 overflow-y-auto`);u.dataset.list=``,n.parent&&u.append(wa(`../`,`${Ca} text-neutral-500`,()=>void i(n.parent)));let d=xa(n);for(let e of d)u.append(wa(e,`truncate`,()=>void i(`${n.path}/${e}`.replace(`//`,`/`))));d.length||u.append(I(`p`,`px-3 py-2 text-[0.8125rem] text-neutral-400`,`No sub-folders.`)),a.append(l,c,u,Ta(n.path,e=>void i(e))),_a(e,a)}i(t)}function Da(e,t,n,r){ya(e,[...t.map(e=>({label:e.path,...e.hint?{hint:e.hint}:{},checked:e.path===n,onSelect:()=>{B(),r(e.path)}})),{label:`Browse…`,onSelect:()=>Ea(e,n||void 0,r)}])}var Oa=(e,t)=>n=>{e.value=n,e.dispatchEvent(new Event(`input`,{bubbles:!0})),t?.(n)};function ka(e,t){let n=L(`Browse…`,`btn flex-none self-stretch rounded-xl px-3 text-[12.5px] text-neutral-600`);return n.onclick=()=>Ea(n,e.value.trim()||void 0,Oa(e,t)),n}function Aa(e,t,n){let r=document.createElement(`input`);return r.className=`${Ci} min-w-0 flex-1 font-mono`,r.value=e,r.placeholder=t,r.oninput=()=>n(r.value),{el:I(`div`,`flex items-center gap-1.5`,r,ka(r,n)),input:r}}var ja=F(`#image-dialog`),V=F(`#image-stage`),Ma=F(`#image-full`),Na=F(`#image-prev`),Pa=F(`#image-next`),Fa=F(`#image-close`),Ia=[],La=0;function Ra(e){Ia.length<2||(La=(La+e+Ia.length)%Ia.length,Va(!1),Ma.src=Ia[La])}var za=2.5,Ba=()=>V.dataset.zoom!==void 0;function Va(e,t){if(!e){delete V.dataset.zoom,Ma.style.cssText=``;return}let n=Ma.getBoundingClientRect(),r=V.getBoundingClientRect(),i=t?(t.x-n.left)/n.width:.5,a=t?(t.y-n.top)/n.height:.5,o=n.width*za,s=n.height*za;V.dataset.zoom=``,Ma.style.width=`${String(o)}px`,Ma.style.height=`${String(s)}px`,V.scrollLeft=i*o-r.width/2,V.scrollTop=a*s-r.height/2}function Ha(e){let t=e.closest(`[data-gallery]`);Ia=t?[...t.querySelectorAll(`img.thumb`)].map(e=>e.src):[e.src],La=Math.max(0,Ia.indexOf(e.src)),Ma.src=e.src;let n=Ia.length<2?`none`:`flex`;Na.style.display=n,Pa.style.display=n,ja.showModal()}var Ua=4,Wa,Ga=!1;V.onpointerdown=e=>{Ga=!1,!(!Ba()||e.button!==0)&&(Wa={x:e.clientX,y:e.clientY,left:V.scrollLeft,top:V.scrollTop},V.setPointerCapture(e.pointerId))},V.onpointermove=e=>{if(!Wa)return;let t=e.clientX-Wa.x,n=e.clientY-Wa.y;(Math.abs(t)>Ua||Math.abs(n)>Ua)&&(Ga=!0),V.scrollLeft=Wa.left-t,V.scrollTop=Wa.top-n};var Ka=()=>{Wa=void 0};V.onpointerup=Ka,V.onpointercancel=Ka,V.onclick=e=>{Ga||(e.target===Ma?Va(!Ba(),{x:e.clientX,y:e.clientY}):ja.close())},Fa.onclick=()=>ja.close(),ja.onclose=()=>Va(!1),Na.onclick=()=>Ra(-1),Pa.onclick=()=>Ra(1),ja.onkeydown=e=>{(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),Ra(e.key===`ArrowLeft`?-1:1))};function qa(e){let t=e.querySelector(`:scope > .thumbs`);if(t)return t;let n=I(`div`,`thumbs`);return e.append(n),n}function Ja(e){let t=document.createElement(`img`);return t.src=e,t.loading=`lazy`,t.className=`thumb`,t.onclick=()=>Ha(t),t}var Ya=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`avif`,`bmp`]),Xa=524288,Za=F(`#file-dialog`),Qa=F(`#file-name`),$a=F(`#file-text`),eo=F(`#file-download`);F(`#file-close`).onclick=()=>Za.close();var to=e=>e.split(`.`).pop()?.toLowerCase()??``,no=(e,t,n=!1)=>`/api/sessions/${encodeURIComponent(e)}/files?path=${encodeURIComponent(t)}${n?`&download=1`:``}`,ro=e=>decodeURIComponent(/^\/api\/sessions\/([^/]+)\//.exec(e)?.[1]??``),io=e=>e.slice(0,e.lastIndexOf(`/`))||`/`,ao=(e,t)=>`${e===`/`?``:e}/${t}`;function oo(e,t){return zi(e,/\]\(\s*<?file:\/\/(\/[^)>\s]*)>?\s*\)/g,e=>{let n=e[1];try{n=decodeURIComponent(n)}catch{}return`](${no(t,n)})`})}var so=e=>/^\/api\/sessions\/[^/]+\/files\?/.test(e);function co(e,t){let n=Zr(t)||`file`,r=no(e,t);return Ya.has(to(n))?Co(r,n):wo(r,n)}function lo(e){return new URLSearchParams(e.slice(e.indexOf(`?`)+1)).get(`path`)??``}var uo=(e,t=`text-neutral-500`)=>I(`div`,`px-3 py-2 text-[12.5px] [overflow-wrap:anywhere] ${t}`,e),fo=0;function po(e,t,n){if(eo.hidden=n,n){Qa.replaceChildren(t);return}let r=io(t),i=L(`${r}/`,`min-w-0 cursor-pointer truncate text-neutral-400 hover:text-indigo-600`);i.title=`Browse ${r}`,i.onclick=()=>void ho(e,r),Qa.replaceChildren(i,I(`span`,`flex-none`,Zr(t)))}function mo(e,t){let n=I(`div`,`flex flex-col py-1`),r=(e,t,n)=>{let r=L(e,`flex w-full cursor-pointer items-center px-3 py-1.5 text-left font-mono text-[12.5px] hover:bg-indigo-50 hover:text-indigo-700 ${t}`);return r.onclick=n,r};t.parent&&n.append(r(`../`,`text-neutral-500`,()=>void ho(e,t.parent)));for(let i of t.entries){let a=ao(t.path,i.name);n.append(i.dir?r(`${i.name}/`,`text-neutral-800`,()=>void ho(e,a)):r(i.name,`text-neutral-600`,()=>void go(no(e,a),i.name)))}return t.entries.length||n.append(uo(`Empty folder.`)),n}async function ho(e,t){let n=++fo;po(e,t,!0),$a.replaceChildren(uo(`loading…`)),Za.open||Za.showModal();let r=await ba(t);n===fo&&$a.replaceChildren(r?mo(e,r):uo(`failed to list: ${t}`,`text-red-600`))}async function go(e,t,n){let r=++fo;po(ro(e),lo(e)||t,!1),eo.href=`${e}&download=1`,$a.replaceChildren(uo(`loading…`)),Za.open||Za.showModal();let i=e=>{r===fo&&$a.replaceChildren(e)},a;try{a=await fetch(e)}catch(e){return i(uo(`failed to load: ${String(e)}`,`text-red-600`))}if(!a.ok){let t=lo(e),n=a.status===404?await ba(t):null;return r===fo?n?void ho(ro(e),t):i(uo(`${await x(a,`failed to load`)}: ${t}`,`text-red-600`)):void 0}let o=a.headers.get(`content-type`)??``;if(!o.startsWith(`text/`)&&!o.startsWith(`image/svg+xml`))return i(uo(`Binary file — use Download.`));let s=await a.text(),c=s.length>Xa?`${s.slice(0,Xa)}\n…`:s,l=await Zi(t),u=ta(ea(c),l);if(i(u),n===void 0||r!==fo)return;let d=u.querySelector(`[data-line="${String(n)}"]`);d?.classList.add(`bg-indigo-100`),d?.scrollIntoView({block:`center`})}var _o=new Set(`ts.tsx.mts.cts.js.jsx.mjs.cjs.json.md.css.html.py.rs.go.rb.java.c.h.cpp.hpp.sh.sql.yml.yaml.toml.ini.conf.txt.lock`.split(`.`)),vo=/^(?:~|\/(?:home|Users|root|tmp|var|opt|etc|srv|mnt|media|data|usr))(?:\/|$)/;function yo(e){let t=/^([^\s`"'()[\]{}<>]+?)(?::(\d+))?(?::\d+)?$/.exec(e);if(!t||e.includes(`://`))return null;let n=t[1],r=n.includes(`.`)?to(n):``;return!vo.test(n)&&(!r||!_o.has(r)&&!n.includes(`/`))?null:{path:n,line:t[2]===void 0?void 0:Number(t[2])}}var bo;async function xo(e,t,n){let r=t;r.startsWith(`~`)&&(bo??=ba().then(e=>e?.path??null),r=`${await bo??`~`}${r.slice(1)}`),await go(no(e,r),Zr(r),n)}function So(e,t,n){for(let r of e.querySelectorAll(`:not(pre) > code`)){let e=yo(r.textContent?.trim()??``);if(!e||r.closest(`a`))continue;let i=e.path.startsWith(`/`)||e.path.startsWith(`~`)?e.path:n?`${n}/${e.path}`:null;if(!i)continue;let a=()=>void xo(t,i,e.line);r.classList.add(`fileref`),r.tabIndex=0,r.setAttribute(`role`,`button`),r.title=e.line===void 0?i:`${i}:${String(e.line)}`,r.onclick=a,r.addEventListener(`pointerup`,()=>r.blur()),r.onkeydown=e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),a())}}}function Co(e,t){let n=Ja(e);return n.alt=t,n}function wo(e,t){let n=to(t),r=I(`span`,`inline-flex max-w-full items-center gap-2.5 rounded-lg border border-neutral-200 bg-neutral-50 px-2.5 py-1.5 no-underline`),i=I(`span`,`flex h-7 w-7 flex-none items-center justify-center rounded-md bg-indigo-50 text-[10px] font-semibold uppercase text-indigo-600`,n.slice(0,4)||`file`),a=I(`span`,`min-w-0 truncate text-[13px] font-medium text-neutral-800`,t),o=I(`span`,`ml-1 flex flex-none items-center gap-0.5`),s=I(`button`,`icon-btn h-6 w-6 text-[13px]`,g(ee));s.setAttribute(`aria-label`,`Preview`),s.title=`Preview`,s.onclick=r=>{r.preventDefault(),n===`pdf`?window.open(e,`_blank`,`noopener`):go(e,t)},o.append(s);let c=document.createElement(`a`);return c.className=`icon-btn h-6 w-6 text-[13px] no-underline`,c.href=`${e}&download=1`,c.download=t,c.title=`Download`,c.append(g(p)),c.setAttribute(`aria-label`,`Download`),o.append(c),r.append(i,a,o),r}function To(e){let t=new Set;for(let n of e)n.parentElement&&t.add(n.parentElement);for(let n of t){let t=[...n.children].filter(t=>e.includes(t));if([...n.childNodes].every(e=>e.nodeType===Node.TEXT_NODE?!e.textContent?.trim():t.includes(e))){n.classList.add(`thumbs`);continue}let r=I(`div`,`thumbs`);r.append(...t),n.after(r)}}function Eo(e){let t=[];for(let n of e.querySelectorAll(`img`)){let e=n.getAttribute(`src`)??``;if(!so(e))continue;let r=Co(e,Zr(lo(e)));n.replaceWith(r),t.push(r)}for(let n of e.querySelectorAll(`a`)){let e=n.getAttribute(`href`)??``;if(!so(e))continue;let r=Zr(lo(e))||n.textContent?.trim()||`file`,i=Ya.has(to(r))?Co(e,r):wo(e,r);n.replaceWith(i),t.push(i)}t.length&&To(t)}var Do=null,Oo=`max-w-full cursor-pointer break-words rounded-full border border-indigo-200 bg-indigo-50 px-2.5 py-0.5 text-left text-[12.5px] text-indigo-700 transition-colors hover:border-indigo-300 hover:bg-indigo-100`;function ko(){Do=null}function Ao(e,t,n){if(Do?.remove(),Do=null,!t.length)return;let r=I(`div`,`mt-1.5 flex flex-wrap gap-1.5`);for(let e of t){let t=I(`button`,Oo,e);t.type=`button`,t.onclick=()=>{Do===r&&(Do=null),r.remove(),n(e)},r.append(t)}e.append(r),Do=r}var jo=8e3,Mo=[`off`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],No=e=>typeof e==`string`&&Mo.includes(e),Po,Fo;function Io(e,t){Po=e,Fo=t}var Lo=e=>e.slice(0,8),Ro=e=>`system-card group relative mt-1.5 rounded-xl px-4 py-2.5 ${e}`,zo=e=>I(`div`,Ro(e));function Bo(e){let t=e.length>240||e.split(`
|
|
75
75
|
`).length>4,n=[`max-h-[4lh]`,`overflow-hidden`],r=I(`div`,`mt-1 whitespace-pre-wrap break-words text-[12.5px] leading-normal text-neutral-500 ${n.join(` `)}`,e),i=I(`button`,`mt-1 hidden w-fit rounded-md px-1 py-1 text-[11px] pointer-coarse:min-h-11 pointer-coarse:px-2 text-neutral-500 hover:bg-neutral-100 hover:text-neutral-700`,`Show full message`);return i.setAttribute(`type`,`button`),i.setAttribute(`aria-expanded`,`false`),i.onclick=()=>{let e=r.getBoundingClientRect().height;r.getAnimations().forEach(e=>e.cancel());let t=r.classList.toggle(n[0]),a=r.getBoundingClientRect().height,o=matchMedia(`(prefers-reduced-motion: reduce)`).matches;r.animate(o?[{opacity:.8},{opacity:1}]:[{maxHeight:`${e}px`,opacity:.8},{maxHeight:`${a}px`,opacity:1}],{duration:o?120:180,easing:`cubic-bezier(0.2, 0.8, 0.2, 1)`}),i.textContent=t?`Show full message`:`Collapse message`,i.setAttribute(`aria-expanded`,String(!t)),r.tabIndex=-1,r.focus({preventScroll:!0})},queueMicrotask(()=>{(r.clientHeight?r.scrollHeight>r.clientHeight+1:t)?i.classList.remove(`hidden`):r.classList.remove(...n)}),[r,i]}function Vo(e){let t=I(`div`,`flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-neutral-500`,e.glyph);t.append(I(`span`,`run-label flex-none font-semibold ${e.labelCls}`,e.label)),e.taskName&&t.append(I(`span`,`min-w-0 grow basis-0 truncate text-[12.5px] font-medium text-neutral-800 max-md:order-1 max-md:basis-full max-md:whitespace-normal max-md:line-clamp-2`,e.taskName));let n=I(`div`,`ml-auto flex min-w-0 flex-wrap items-center gap-x-2 font-mono`);if(e.note&&n.append(I(`span`,`flex-none`,e.note)),e.model){let t=I(`span`,`flex-none rounded bg-black/[0.05] px-1.5 py-px font-medium text-neutral-700 dark:bg-neutral-200`,e.model.id);t.title=`${e.model.provider} / ${e.model.id}`,n.append(t)}if(e.thinking){let t=I(`span`,`flex-none`,e.thinking);t.title=`Reasoning effort`,n.append(t)}let r=I(`button`,`flex-none hover:underline`,Lo(e.runId));if(r.title=`Run ${e.runId}`,r.onclick=()=>Po.showRun(e.runId),n.append(r),e.sessionId&&e.sessionId!==`console`){let t=e.sessionId,r=I(`button`,`flex-none text-indigo-600 hover:underline`,Lo(t));r.title=`Open session ${t}`,r.onclick=()=>Po.select(t),n.append(r)}return t.append(n),t}var Ho={queued:{edge:`border-l-amber-400`,label:`text-amber-700`,glyph:ie},running:{edge:`border-l-fuchsia-500`,label:`text-fuchsia-700`,glyph:ie},succeeded:{edge:`border-l-green-500`,label:`text-green-700`,glyph:o},failed:{edge:`border-l-red-500`,label:`text-red-600`,glyph:ve},cancelled:{edge:`border-l-neutral-300`,label:`text-neutral-500`,glyph:se},interrupted:{edge:`border-l-amber-400`,label:`text-amber-700`,glyph:le},skipped:{edge:`border-l-neutral-300`,label:`text-neutral-500`,glyph:se}},Uo=e=>g(Ho[e].glyph,`h-3 w-3 ${e===`queued`||e===`running`?`spinner`:``} ${Ho[e].label}`),Wo=new Map,Go=new WeakMap;function Ko(e){for(let[e,t]of Wo)t.isConnected||Wo.delete(e);let t=Wo.get(e.runId);t||(t=zo(Ho[e.state].edge),t.dataset.kind=`background-run`,Fo.el.append(t),Wo.set(e.runId,t)),t.className=Ro(Ho[e.state].edge);let n=e.state===`queued`||e.state===`running`;t.toggleAttribute(`data-active`,n);let r=Math.max(0,Math.round(((e.finishedAt??Date.now())-(e.startedAt??e.queuedAt))/1e3)),i=Vo({glyph:Uo(e.state),label:`run · ${e.state}`,labelCls:Ho[e.state].label,taskName:e.taskName,note:`${e.sessionMode??`task`} · ${String(r)}s`,runId:e.runId,sessionId:e.targetSessionId}),a=Go.get(t);!a&&e.prompt!==null&&(a=Bo(e.prompt),Go.set(t,a)),t.replaceChildren(i,...a??[]),Fo.scroll()}var H=null,qo=null,Jo=null,Yo=!1;function Xo(){if(!qo)return;qo.text=qo.text.slice(-4e3),qo.pre.textContent=qo.text;let e=qo.text.split(`
|
|
76
76
|
`).filter(Boolean).pop()??`thinking…`,t=qo.summary.lastElementChild;t.textContent=e.length>90?`…`+e.slice(-90):e}function Zo(){if(Jo){Yo=!0;return}Yo=!1,Xo(),Jo=setTimeout(()=>{Jo=null,Yo&&Zo()},80)}function Qo(){Jo&&clearTimeout(Jo),Jo=null,Yo&&Xo(),Yo=!1}var $o=new WeakMap,es=e=>{let t=$o.get(e)??[];return $o.set(e,t),t};function ts(){H&&!H.toolRows.size&&hs(`done`)}var ns=null;function rs(){H=null,ns=null,qo=null,Qo(),Wo.clear()}function is(){let e=ns;return!e||H?.el===e||(ns=null,e!==Fo.el.lastElementChild)?null:(e.remove(),e.dataset.adopted=`1`,os(e,e.dataset.status),e)}var as={running:`text-green-700 open:bg-green-50`,done:`text-neutral-400 hover:text-neutral-600 open:bg-black/[0.02] open:text-neutral-500 dark:open:bg-neutral-100`,failed:`text-red-600 open:bg-red-50`,interrupted:`text-amber-700 open:bg-amber-50`};function os(e,t){e.dataset.status=t,e.className=`px-2 py-1 rounded-xl text-[11.5px] leading-normal open:border open:border-neutral-200 open:px-3 open:py-2 ${as[t]}`}var ss={failed:ve,interrupted:le};function cs(e){return e===`running`?g(ie,`spinner`):e===`done`?I(`span`,`hidden`):g(ss[e],`h-3 w-3`)}function ls(e){if(H)return H;let t=cs(`running`),n=I(`span`,`min-w-0 truncate`,`working…`),{el:r}=ui(``,[t,n]);r.dataset.kind=`activity`,os(r,`running`);let i=I(`div`,`mt-1.5 flex max-h-64 flex-col gap-1 overflow-y-auto overscroll-contain border-t border-black/5 pt-1.5 dark:border-neutral-200`);return r.append(i),fs(r,i),Fo.el.append(r),ns=r,Fo.scroll(),H={el:r,statusIcon:t,headline:n,rowsEl:i,toolRows:new Map,thinking:null,steps:0,failedSteps:0,startTs:e,sawError:!1},H}function us(e,t=``){let n=ls(e);Qo(),n.thinking=null;let r=I(`div`,`whitespace-pre-wrap break-words text-[13px] text-neutral-600`,t);r.dataset.raw=t;let i=I(`div`,`rounded-lg bg-neutral-50 px-2 py-1.5`,I(`span`,`text-[10px] font-medium text-neutral-400`,`Update`),r);return i.dataset.kind=`progress`,n.rowsEl.append(i),ms(n,`running`,`writing…`),ps(n),Fo.scroll(),r}function ds(e){let t=e.closest(`details[data-kind="activity"]`);e.parentElement?.remove(),t&&!t.lastElementChild?.childElementCount&&(H?.el===t&&(H=null),ns===t&&(ns=null),t.remove())}function fs(e,t){t.dataset.follow=`1`,t.addEventListener(`scroll`,()=>{let e=t.scrollHeight-t.scrollTop-t.clientHeight<24;t.dataset.follow=e?`1`:``}),e.addEventListener(`toggle`,()=>{e.open&&(t.scrollTop=t.scrollHeight,t.dataset.follow=`1`)})}function ps(e){Fo.bulk()||!e.el.open||!e.rowsEl.dataset.follow||(e.rowsEl.scrollTop=e.rowsEl.scrollHeight)}function ms(e,t,n){let r=Math.max(1,Math.round((Date.now()-e.startTs)/1e3)),i=`${e.steps?`${e.steps} step${e.steps===1?``:`s`}`:`Progress`} · ${r}s`;e.headline.textContent=t===`running`&&n?`${i} · ${n}`:t===`done`?`Completed · ${i}`:`${i} · ${t}`,os(e.el,t);let a=cs(t);e.statusIcon.replaceWith(a),e.statusIcon=a}function hs(e){if(!H)return;Qo();for(let{statusEl:e}of H.toolRows.values())e.textContent===`running…`&&(e.textContent=`interrupted`);let t=H.steps>0&&H.failedSteps===H.steps;ms(H,(H.sawError||t)&&e===`done`?`failed`:e===`done`&&H.toolRows.size?`interrupted`:e),H=null}function gs(){H&&(H.sawError=!0)}function _s(e){let t=e.slice(0,400).replace(/\s+/g,` `);return t.length>100?t.slice(0,100)+`…`:t}function vs(e,t,n,r){let i=ls(e);i.steps+=1,Qo(),i.thinking=null;let a=JSON.stringify(r,null,2)??``,o=I(`span`,`ml-auto flex-none text-neutral-400`,`running…`),s=I(`span`,`min-w-0 truncate text-neutral-500`,_s(a)),{el:c}=ui(`rounded-md px-1 py-0.5 font-mono text-[12.5px] hover:bg-black/[0.03] dark:hover:bg-neutral-100`,[I(`span`,`flex-none font-semibold`,n),s,o]),l=I(`pre`,`max-h-40 overflow-y-auto whitespace-pre-wrap break-words rounded bg-black/[0.04] p-1.5 text-[12px] dark:bg-neutral-100`,a),u=I(`pre`,`hidden max-h-56 overflow-y-auto whitespace-pre-wrap break-words rounded bg-black/[0.04] p-1.5 text-[12px] dark:bg-neutral-100`);c.append(I(`div`,`mt-1 flex flex-col gap-1 pl-4`,l,u)),es(i.el).push({tool:n,call:t,preview:s,argsPre:l,outputPre:u}),i.toolRows.set(t,{el:c,statusEl:o,outputPre:u}),i.rowsEl.append(c),ps(i),ms(i,`running`,n),Fo.scroll()}function ys(e,t,n){let r=H;if(!r)return;let i=r.toolRows.get(e);r.toolRows.delete(e),i&&(i.statusEl.textContent=t?`failed`:`ok`,i.statusEl.className=`ml-auto flex-none ${t?`text-red-600`:`text-green-700`}`,i.el.classList.toggle(`bg-red-50`,t),i.el.classList.toggle(`text-red-700`,t),n&&(i.outputPre.textContent=n.length>8e3?n.slice(0,jo)+`…`:n,i.outputPre.classList.remove(`hidden`)),t&&(r.failedSteps+=1)),ms(r,`running`)}function bs(e,t){let n=ls(e);if(!n.thinking){Qo();let{el:e,summary:t}=ui(`rounded-md px-1 py-0.5 text-[12.5px] italic text-neutral-500 hover:bg-black/[0.03] dark:hover:bg-neutral-100`,[I(`span`,`min-w-0 truncate`,`thinking…`)]),r=I(`div`,`mt-1 max-h-56 overflow-y-auto whitespace-pre-wrap break-words pl-4 not-italic text-neutral-500`,``);e.append(r),n.rowsEl.append(e),n.thinking={pre:r,summary:t,text:``},qo=n.thinking,ps(n),ms(n,`running`,`thinking…`)}n.thinking.text+=t,Zo()}var xs=0;function Ss(e,t=0,n=!1,r){let i=Date.now()-t,a=ls(i).el;for(let t of e){if(t.kind===`progress`){us(i,t.text??``);continue}if(t.kind===`thinking`){bs(i,t.text??``);continue}let e=t.id??`replay-${++xs}`;vs(i,e,t.toolName??``,t.args),t.done&&ys(e,t.isError??!1,t.output??``)}r!==void 0&&e.some(e=>e.kind===`tool`&&e.args===void 0)&&Cs(a,r),!n&&hs(e.some(e=>e.kind===`tool`&&!e.done)?`interrupted`:`done`)}function Cs(e,t){let n=()=>{e.open&&(e.removeEventListener(`toggle`,n),ws(e,t))};e.addEventListener(`toggle`,n)}async function ws(e,t){let n=Po.sessionId(),r=es(e),i=new Set(r.filter(e=>!e.argsPre.textContent)),a=e=>{for(let t of i)t.argsPre.textContent=e};if(a(`loading…`),!n)return a(`no session`);let o=await S(`/api/sessions/${n}/turns/${t}/steps`,`could not load these steps`);if(!o.ok)return a(o.error);let s=o.value.steps.filter(e=>e.kind===`tool`);for(let[e,t]of r.entries()){if(!i.has(t))continue;let n=s[e];if(!(n&&(n.id?n.id===t.call:n.toolName===t.tool))){t.argsPre.textContent=`detail no longer available — reload the session`;continue}let r=JSON.stringify(n.args,null,2)??``;t.argsPre.textContent=r,t.preview.textContent=_s(r),n.output&&(t.outputPre.textContent=n.output,t.outputPre.classList.remove(`hidden`))}}var Ts,U=F(`#turns`);function Es(e){Ts=e,Io(e,{el:U,scroll:Ps,bulk:()=>Ds})}var Ds=!1,Os=()=>U.scrollHeight-U.scrollTop-U.clientHeight<80,ks=!0,As=0;U.addEventListener(`scroll`,()=>{let e=U.scrollTop,t=e<As-4;As=e,!Ds&&(t||Os())&&(ks=Os())},{passive:!0});var js=0;function Ms(){!ks||Ds||js||(js=requestAnimationFrame(()=>{js=0,ks&&!Ds&&(U.scrollTop=U.scrollHeight)}))}new ResizeObserver(Ms).observe(U),U.addEventListener(`load`,Ms,!0),new MutationObserver(Ms).observe(U,{childList:!0,subtree:!0,characterData:!0});function Ns(){Os()&&(ks=!0)}function Ps(e=!1){Ds||(e&&(ks=!0),ks&&(U.scrollTop=U.scrollHeight))}var Fs=1200;function Is(e,t){let n=U.querySelector(`[data-kind="${e}"][data-at="${t}"]`);return n?(Rs(n),!0):!1}function Ls(){let e=U.querySelectorAll(`[data-kind="background-run"][data-active]`),t=e[e.length-1];return t?(Rs(t),!0):!1}function Rs(e){ks=!1,e.scrollIntoView({block:e.offsetHeight>U.clientHeight?`start`:`center`}),e.dataset.reveal=``,setTimeout(()=>delete e.dataset.reveal,Fs)}var zs=500,Bs=0,Vs=0,Hs=null;function Us(){for(;U.childElementCount>zs;){let e=U.firstElementChild;e.remove(),e!==Hs&&(e.dataset.kind===`user`&&Bs++,Vs++)}Vs&&(Hs||(Hs=I(`div`,`px-5 py-2 text-center text-[11.5px] italic text-neutral-400`),Hs.dataset.kind=`trim`),Hs.textContent=`${Vs} earlier row${Vs===1?``:`s`} not shown — still in the transcript, not on this screen`,U.firstElementChild!==Hs&&U.prepend(Hs))}var Ws={user:{row:``,body:`text-inherit`},assistant:{row:``,body:`text-neutral-900`},error:{row:`border-l-red-400 bg-red-50`,body:`text-red-700`},system:{row:`system-card border-l-cyan-500`,body:`text-neutral-500`}};function W(e,t,n=!1,r){ts();let i=e===`assistant`?is():null,a=Ws[e],o=e===`user`&&r!==void 0&&oc(r)?r:void 0,s=o===void 0&&U.lastElementChild?.dataset.kind===e,c=I(`div`,`group relative ${a.row}`);c.dataset.kind=e,s&&(c.dataset.grouped=``),Ds||(c.dataset.enter=``);let l=e===`user`?Vi(t):null,u=l?.text??t,d=e===`user`?Le(u):null,f=d?.id||d?.when||d?.where?d:null,p=f&&(f.id?f.id!==`web`:f.name)?f:null,m=I(`div`,`whitespace-pre-wrap break-words ${a.body}`,f?.text??u);(l?.paths.length||f)&&(m.dataset.raw=t),n&&uc(m,t),r!==void 0&&sc(c,r),p&&c.append(Gs(p)),c.append(m);let ee=Ts.sessionId();if(l?.paths.length&&ee){let e=qa(c);for(let t of l.paths)e.append(co(ee,t))}if(e===`user`){Ys?.();let e=I(`button`,`message-edit absolute right-full top-1 flex h-8 w-8 items-center justify-center rounded-full`);e.title=`Edit message — resends it and drops everything after it`,e.setAttribute(`type`,`button`),e.setAttribute(`aria-label`,`Edit message`),e.append(g(ue)),e.onclick=()=>Qs(c,m),c.append(e)}if(o!==void 0){let e=I(`div`,`my-3 text-center text-[11px] text-neutral-400`);e.dataset.kind=`time`,e.dataset.at=String(o),rc(e),nc??=setInterval(ic,6e4),e.title=$r(o),U.append(e)}return i&&U.append(i),U.append(c),Us(),Ps(),m}function Gs(e){let t=I(`div`,`mb-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-[11.5px] leading-tight opacity-85`),n=e?.name??e?.id;if(n){let r=I(`span`,`font-semibold text-inherit`,n);e?.id&&(r.title=e.id),t.append(r)}let r=Ts.sessionChannel();return r&&r!==`web`&&t.append(I(`span`,`text-[10px] uppercase tracking-wide opacity-60`,r)),t}var Ks={"task-delegation":[i,`delegated`,`text-cyan-700`],"task-callback":[f,`callback`,`text-cyan-700`]};function qs(e){let t=e.indexOf(`
|
|
77
77
|
|
|
@@ -82,4 +82,4 @@ Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error
|
|
|
82
82
|
`),o=K.sessionState()===`idle`&&e===`auto`;o?K.setState(`streaming`):Cl(),(o||e===`steer`)&&(xl(a),W(`user`,a,!1,Date.now()),Ps(!0));let s=await b(`/api/sessions/${i}/messages`,{text:a,mode:e});if(!s.ok){let e=await x(s,`send failed`);await K.reload(i),W(`error`,e)}}finally{t===void 0&&(Bl=!1)}}}async function Hl(e){let t=K.sessionId();if(!t)return;El([],[]);let n=await b(`/api/sessions/${t}/queue/deliver`,{mode:e});if(!n.ok){let r=await x(n,`Queue ${e} failed`);await K.reload(t),K.sessionId()===t&&W(`error`,r)}}async function Ul(){let e=K.sessionId();if(!e||ml.has(e))return;ml.add(e);let t=pl,n=Pl,r=document.activeElement;try{Ll();let i=await fetch(`/api/sessions/${e}/queue/recall`,{method:`POST`});if(!i.ok){let t=await x(i,`Could not recall queued messages`);K.sessionId()===e&&W(`error`,t);return}let{messages:a}=await i.json(),o=K.sessionId()===e;if(a.length)try{let t=o?q.value:sessionStorage.getItem(Nl(e))??``,i=(t?[t,...a]:a).join(`
|
|
83
83
|
`);o&&(q.value=i,zl(),n===Pl&&K.chatVisible()&&document.activeElement===r&&q.focus()),Ll(e,i)}catch(t){W(`error`,`Could not save recalled messages for session ${e}: ${String(t)}\nRecalled messages (not saved):\n${a.join(`
|
|
84
84
|
`)}`)}o&&t===pl&&El([],[])}finally{ml.delete(e)}}function Wl(e){K=e,Fl(),_l(),vl();let t=()=>{let e=K.sessionId();e&&fetch(`/api/sessions/${e}/abort`,{method:`POST`})};al.onclick=t,Zc(al,`Stop the running turn`,t,()=>K.sessionState()===`streaming`&&K.chatVisible()),F(`#queue-steer`).onclick=()=>void Hl(`steer`),F(`#queue-restart`).onclick=()=>void Hl(`restart`),F(`#queue-recall`).onclick=()=>void Ul(),tl.onsubmit=e=>{e.preventDefault(),Vl(`auto`)},$c(q,[`/`],`Write a message`,yl,K.chatVisible),q.onfocus=Ns,q.oninput=()=>{zl(),Ll()};let n=!matchMedia(`(pointer: coarse)`).matches;q.onkeydown=e=>{e.isComposing||e.keyCode===229||n&&e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),Vl(`auto`))},q.onpaste=e=>{for(let t of e.clipboardData?.items??[]){let e=t.kind===`file`?t.getAsFile():null;e&&kl(e)}let t=e.clipboardData?.getData(`text/plain`)??``,n=t.trim();!n||n===t||(e.preventDefault(),q.setRangeText(n,q.selectionStart??0,q.selectionEnd??0,`end`),zl(),Ll())},U.ondragover=e=>e.preventDefault(),U.ondrop=e=>{e.preventDefault();for(let t of e.dataTransfer?.files??[])kl(t)},F(`#attach`).onclick=()=>dl.click(),dl.onchange=()=>{for(let e of dl.files??[])kl(e);dl.value=``},Cl()}var Gl=`pier.push`,Kl=`/app/sw.js`,ql=()=>/iPad|iPhone|iPod/.test(navigator.userAgent)||navigator.maxTouchPoints>1&&/Macintosh/.test(navigator.userAgent),Jl=()=>matchMedia(`(display-mode: standalone)`).matches||navigator.standalone===!0;function Yl(){return window.isSecureContext?ql()&&!Jl()?`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 Xl=[[/iPhone/,`iPhone`],[/iPad/,`iPad`],[/Android/,`Android`],[/Macintosh/,`Mac`],[/Windows/,`Windows`]],Zl=[[/Edg\//,`Edge`],[/Chrome\//,`Chrome`],[/Firefox\//,`Firefox`],[/Safari\//,`Safari`]];function Ql(){let e=navigator.userAgent,t=(t,n)=>t.find(([t])=>t.test(e))?.[1]??n;return`${t(Xl,`Linux`)} · ${t(Zl,`browser`)}${Jl()?` (installed)`:``}`}var $l=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},eu=null;async function tu(){return!(`serviceWorker`in navigator)||!window.isSecureContext?null:(eu??=await navigator.serviceWorker.register(Kl,{scope:`/app/`}).catch(e=>(console.warn(`service worker registration failed`,e),null)),eu)}var nu=(e,t)=>{let n=e?new Uint8Array(e):null;return n?.length===t.length&&n.every((e,n)=>e===t[n])};async function ru(e){let{publicKey:t}=await Ke(`/api/push`,`Could not read this instance's push key`),n=$l(t),r=await e.pushManager.getSubscription();if(r){if(nu(r.options.applicationServerKey,n))return r;await r.unsubscribe()}return e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:n})}async function iu(e){return b(`/api/push/subscribe`,{...e.toJSON(),label:Ql()})}async function au(){cu();let e=await tu();if(!(!e||localStorage.getItem(Gl)!==`on`)&&!(!(`Notification`in window)||Notification.permission!==`granted`))try{await iu(await ru(e))}catch(e){console.warn(`re-registering this browser for notifications failed`,e)}}var ou=null,su=null;function cu(){window.addEventListener(`beforeinstallprompt`,e=>{e.preventDefault(),ou=e,su?.()}),window.addEventListener(`appinstalled`,()=>{ou=null,su?.()})}function lu(e){let t=navigator;(e>0?t.setAppBadge?.(e):t.clearAppBadge?.())?.catch(()=>{})}function uu(){let e=I(`span`,`text-[11.5px]`,``),t=di(`Send a test notification`),n=I(`div`,`flex items-center gap-3`,t,e),r=I(`div`,`flex flex-col gap-4`),i=()=>localStorage.getItem(Gl)===`on`,a=I(`div`,`flex flex-col gap-2`),o=I(`span`,`text-[11.5px]`,``),s=I(`div`,`flex flex-col gap-2`,a,o);async function c(e){R(o,`saving`,`removing…`);try{let t=await b(`/api/push/unsubscribe`,{endpoint:e.endpoint});if(!t.ok)R(o,`failed`,await x(t,`Could not remove it`));else{let t=await(await tu())?.pushManager.getSubscription();t?.endpoint===e.endpoint&&(localStorage.setItem(Gl,`off`),await t.unsubscribe(),p()),R(o,`saved`,`Removed.`)}}catch(e){R(o,`failed`,`Could not remove it: ${String(e)}`)}await l()}async function l(){let e=await S(`/api/push/subscriptions`,`Could not load subscribed devices`);if(!e.ok)return R(o,`failed`,e.error);if(!e.value.devices.length){a.replaceChildren(Ni(`No device is subscribed.`));return}a.replaceChildren(...e.value.devices.map(e=>{let t=di(`Remove`);return t.onclick=()=>{t.disabled=!0,c(e)},Mi(e.label,`subscribed ${Xr(e.createdAt)}`,t,{tag:e.current?ji(`This browser`,`bg-neutral-50 text-neutral-500 ring-neutral-200`):void 0})}))}async function u(){R(e,`saving`,`asking this browser…`);let t=await Notification.requestPermission();if(t!==`granted`)return localStorage.setItem(Gl,`off`),p(),R(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 tu();if(!n)return R(e,`failed`,`This browser refused to register a service worker.`);try{let t=await iu(await ru(n));if(!t.ok)return R(e,`failed`,await x(t,`Could not register this browser`));localStorage.setItem(Gl,`on`),p(),R(e,`saved`,`This browser will be notified when a turn finishes unseen.`),l()}catch(t){R(e,`failed`,`Could not subscribe: ${String(t)}`)}}async function d(){localStorage.setItem(Gl,`off`),p();let t=await(await tu())?.pushManager.getSubscription();t&&(await b(`/api/push/unsubscribe`,{endpoint:t.endpoint}),await t.unsubscribe()),R(e,`idle`,`This browser will not be notified.`),l()}t.onclick=()=>{R(e,`saving`,`sending…`),(async()=>{let t=await b(`/api/push/test`,{});if(!t.ok)return R(e,`failed`,await x(t,`Could not send`));let{sent:n,failed:r}=await t.json();R(e,r?`failed`:`saved`,`Handed ${String(n)} device(s) to their push service${r?`, ${String(r)} refused`:``}.`)})()};function f(){if(!ou)return[];let e=di(`Install Pier`,!0);return e.onclick=()=>{let e=ou;e&&e.prompt().then(()=>e.userChoice).finally(()=>{ou=null,p()})},[I(`div`,`flex items-center gap-3`,e,I(`span`,`text-[11.5px] leading-snug text-neutral-500`,`Its own window and icon — and where notifications look like an app's.`))]}function p(){let e=Yl();if(e){r.replaceChildren(...f(),I(`p`,`text-[12.5px] leading-snug text-neutral-500`,e),s);return}let a=i()&&Notification.permission===`granted`;t.disabled=!a,r.replaceChildren(...f(),ki(`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.`,a,e=>void(e?u():d())),n,s)}return su=p,p(),{el:xi(`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),load:()=>{R(o,`idle`,``),l()}}}var J=F(`#sidebar`),du=F(`#drawer-scrim`),fu=F(`#mobile-title`),pu=F(`#mobile-menu`),mu=F(`#session-meta`);function hu(){delete J.dataset.open,du.classList.add(`hidden`),Cu()}function gu(e,t){fu.textContent=e,fu.classList.toggle(`cursor-pointer`,t),pu.classList.toggle(`hidden`,!t)}var _u=`pier.railClosed`;localStorage.getItem(_u)===`1`&&(document.body.dataset.rail=`closed`);function vu(e){document.body.dataset.rail=e?`closed`:``,localStorage.setItem(_u,e?`1`:`0`),Cu()}function yu(){if(J.dataset.open!==void 0)return hu();J.dataset.open=``,du.classList.remove(`hidden`),Cu()}var bu=window.matchMedia(`(width < 48rem)`),xu=()=>bu.matches;function Su(){xu()?F(`#mobile-bar`).append(mu):F(`#chat-menu`).before(mu)}function Cu(){let e=xu()&&J.dataset.open!==void 0,t=F(`main`);t.inert=e,J.inert=xu()?!e:document.body.dataset.rail===`closed`,F(`#drawer-toggle`).setAttribute(`aria-expanded`,String(e)),e&&!J.contains(document.activeElement)&&F(`#new-session`).focus(),J.inert&&J.contains(document.activeElement)&&F(xu()?`#drawer-toggle`:`#rail-toggle`).focus()}var wu=[F(`#rail-toggle`),F(`#drawer-toggle`)],Tu=`attention absolute -right-0.5 -top-0.5 rounded-full bg-amber-500`,Eu=e=>e===1?I(`span`,`${Tu} h-2 w-2`):I(`span`,`${Tu} 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 Du(e){for(let t of wu)t.querySelector(`.attention`)?.remove(),e&&t.append(Eu(e))}var Ou=20,ku=.35,Au=8;function ju(){let e=-1,t=0,n=!1,r=!1,i=1,a=e=>{J.style.transition=`none`,J.style.transform=`translateX(${String(e-i)}px)`,du.style.transition=`none`,du.classList.remove(`hidden`),du.style.opacity=String(e/i)},o=t=>{J.style.transition=``,J.style.transform=``,du.style.transition=``,du.style.opacity=``,t?(J.dataset.open=``,du.classList.remove(`hidden`),Cu()):hu(),e=-1,r=!1};window.addEventListener(`touchstart`,a=>{if(r||(e=-1,!xu()||a.touches.length!==1))return;let o=a.touches[0],s=J.dataset.open!==void 0;if(i=J.offsetWidth||1,s){if(o.clientX>i)return}else{if(o.clientX>Ou||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)<Au)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=J.getBoundingClientRect().right;o(n?t>i*ku:t>i*.65)};window.addEventListener(`touchend`,s),window.addEventListener(`touchcancel`,s)}function Mu(e){ju(),Cu(),Su(),bu.addEventListener(`change`,()=>{hu(),Su()}),F(`#drawer-toggle`).setAttribute(`aria-controls`,`sidebar`),J.addEventListener(`keydown`,e=>{if(!(!xu()||J.dataset.open===void 0||e.defaultPrevented||e.isComposing)){if(e.key===`Escape`)e.preventDefault(),e.stopPropagation(),hu();else if(e.key===`Tab`){let t=[...J.querySelectorAll(`button, a[href], summary`)].filter(e=>e.getClientRects().length&&!e.matches(`:disabled`)),n=e.shiftKey?t.at(-1):t[0],r=e.shiftKey?t[0]:t.at(-1);document.activeElement===r&&(e.preventDefault(),n?.focus())}}}),F(`#drawer-toggle`).onclick=yu,du.onclick=hu,pu.onclick=()=>e.sessionMenu(pu),fu.onclick=()=>{pu.classList.contains(`hidden`)||e.sessionInfo(fu)};let t=F(`#rail-toggle`);t.onclick=()=>vu(document.body.dataset.rail!==`closed`),Xc(t,`meta+b`,`Toggle sidebar`,()=>xu()?yu():vu(document.body.dataset.rail!==`closed`))}var Y,Nu=F(`#session-list`),Pu=F(`#new-session`),Fu=e=>e.modified??e.createdAt;function Iu(e){return{top:e.filter(e=>e.rank!==void 0).sort((e,t)=>(e.rank??0)-(t.rank??0)),rest:e.filter(e=>e.rank===void 0).sort((e,t)=>t.createdAt-e.createdAt)}}function Lu(e,t){let{top:n,rest:r}=Iu(e),i=[...n,...r].slice(0,t);return{rows:i,hidden:e.length-i.length}}function Ru(e,t,n){let{top:r,rest:i}=Iu(e),a=[...r,...i];if(!a.length)return;let o=a.findIndex(e=>e.id===t),s=o<0?a[0]:a[(o+n+a.length)%a.length];return s&&s.id!==t?s.id:void 0}var zu=8,Bu=`session-more hidden h-7 w-7 flex-none cursor-pointer items-center justify-center rounded-lg text-neutral-400 hover:bg-neutral-200 hover:text-neutral-700`,Vu=e=>e.unread,Hu=e=>`${e} subagent${e>1?`s`:``} running`,Uu=e=>e.state===`streaming`||Vu(e)||e.activeRuns>0;function Wu(e){if(!Uu(e))return[];let t=e.state===`streaming`?[`bg-green-500 animate-pulse`,`working…`]:Vu(e)?[`bg-amber-500`,`turn finished — not viewed yet`]:[`bg-sky-500`,Hu(e.activeRuns)],n=I(`span`,`h-2 w-2 flex-none rounded-full ${t[0]}`);return n.title=t[1],[n]}async function Gu(e){let t=window.prompt(`Session name — empty resets it to the first message`,e.title??``);if(t===null)return;let n=e.title,r=t=>{e.title=t,Qu(),Y.onTitleChanged()};r(t.trim()||void 0),(await b(`/api/sessions/${e.id}/rename`,{name:t})).ok||r(n)}var Ku=`flex-none text-xs font-medium uppercase leading-5 text-neutral-500`,qu=e=>e.channel&&e.channel!==`web`?[I(`span`,Ku,e.channel[0]??``)]:[];function Ju(e,t=I(`button`,Bu,g(m))){let n=e.id===Y.currentId(),r=I(`li`,`flex items-center gap-1 hover:bg-neutral-100 ${n?`bg-indigo-50 hover:bg-indigo-50`:``}`);t.setAttribute(`type`,`button`),t.setAttribute(`aria-label`,`Session actions: ${e.title??`untitled`}`),t.title=`Session actions`,t.onclick=n=>{n.stopPropagation(),Y.sessionMenu(t,e)};let i=I(`button`,`session-open flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 rounded-lg text-left`,I(`span`,`min-w-0 flex-1 truncate`,e.title??`untitled`),...Wu(e));return i.setAttribute(`type`,`button`),n&&i.setAttribute(`aria-current`,`page`),i.onclick=()=>Y.select(e.id),r.dataset.sessionId=e.id,r.append(i,...qu(e),t),r.title=[e.cwd,`active ${Yr(Fu(e))} ago · created ${new Date(e.createdAt).toLocaleDateString()}`,...e.channel&&e.channel!==`web`?[`answering ${e.channel}`]:[]].join(`
|
|
85
|
-
`),r}var Yu=()=>`${Y.currentId()??``}\n${Zu}\n${JSON.stringify(Y.sessions())}`,Xu=``,Zu=20;function Qu(){let e=Yu();if(e===Xu)return;Xu=e;let t=Y.sessions(),n=t.filter(Vu);Du(n.length),lu(n.length);let{rows:r,hidden:i}=Lu(t,Zu),a=Nu.querySelector(`.session-more[aria-expanded='true']`),o=a?.closest(`[data-session-id]`)?.dataset.sessionId,s=r.map(e=>Ju(e,e.id===o?a:void 0));if(i>0){let e=I(`button`,`session-open w-full cursor-pointer rounded-lg text-left text-sm text-neutral-500`,`Load more (${i})`);e.id=`session-load-more`,e.setAttribute(`type`,`button`),e.onclick=()=>{Zu+=20,Qu(),Nu.querySelectorAll(`.session-open`)[r.length]?.focus()},s.push(I(`li`,`hover:bg-neutral-100`,e))}let c=document.activeElement,l=c?.closest(`[data-session-id]`)?.dataset.sessionId,u=c?.classList.contains(`session-more`)?`.session-more`:`.session-open`;if(Nu.replaceChildren(...s.length?[I(`ul`,`pb-1`,...s)]:[I(`p`,`px-3 py-2 text-sm leading-normal text-neutral-500`,`No sessions yet — create one.`)]),l){let e=[...Nu.querySelectorAll(`[data-session-id]`)].find(e=>e.dataset.sessionId===l);e?.querySelector(`.session-open`)?.focus({preventScroll:!0}),u===`.session-more`&&e?.querySelector(u)?.focus({preventScroll:!0})}else c?.id===`session-load-more`&&(Nu.querySelector(`#session-load-more`)??Nu.querySelector(`.session-open`)??F(`#new-session`)).focus({preventScroll:!0});jd()}function $u(){if(Pu.getAttribute(`aria-expanded`)===`true`)return B();let e=Y.sessions().find(e=>e.id===Y.currentId())?.cwd,t=He(Y.sessions()).slice(0,zu);if(e&&!t.includes(e)&&t.unshift(e),!t.length)return Ea(Pu,void 0,Y.createSession);Da(Pu,t.map(e=>({path:e,hint:Zr(e)})),e,Y.createSession)}function ed(e){Y=e,Pu.onclick=$u,Xc(Pu,`shift+o`,`New session`,$u,Kc);let t=e=>{let t=Ru(Y.sessions(),Y.currentId(),e);t&&Y.select(t)};el(`shift+[`,()=>t(-1),Kc),el(`shift+]`,()=>t(1),Kc)}var td,nd=F(`#palette`),rd=F(`#palette-input`),id=F(`#palette-list`),ad=F(`#palette-count`),od=[{name:`tasks`,icon:re,label:`Tasks`,detail:`Automation — task definitions and schedules`},{name:`runs`,icon:re,label:`Runs`,detail:`Automation — executions, subagents and callbacks`},{name:`activity`,icon:re,label:`Activity`,detail:`Automation — sessions and relationships`},{name:`boards`,icon:ne,label:`Boards`,detail:`Console — the static pages Pier publishes`},{name:`settings`,icon:me,label:`Settings`,detail:`Console — models and providers, agent files and extensions, channels, password, sign out, security`}],sd=7,cd=3,ld=8,ud=80,dd=``,fd,pd,md;function hd(e){dd!==e&&(clearTimeout(md),pd?.abort(),pd=void 0,dd=e,fd=void 0,e&&(md=setTimeout(()=>{let t=pd=new AbortController;S(`/api/search?q=${encodeURIComponent(e)}`,`Search unavailable`,{signal:t.signal}).then(n=>{t.signal.aborted||dd!==e||(pd=void 0,fd=n.ok?{hits:n.value.hits}:{error:n.error},nd.open&&Ad())})},ud)))}var gd=[],_d=0;function vd(e){if(gd.length){_d=(e+gd.length)%gd.length;for(let[e,{el:t}]of gd.entries())t.classList.toggle(`bg-indigo-50`,e===_d),t.setAttribute(`aria-selected`,String(e===_d));gd[_d]?.el.scrollIntoView({block:`nearest`})}}var yd=e=>e.hit?.at??e.session?.createdAt;function bd(e){let t=I(`span`,`min-w-0 flex-1 truncate text-neutral-500`);for(let n of e.replaceAll(/\s+/g,` `).split(``)){let[e=``,r]=n.split(``,2);r===void 0?t.append(e):t.append(I(`span`,`font-medium text-neutral-800`,e),r)}return t}var xd=`flex min-w-0 flex-1 items-baseline gap-2`,Sd=`shrink-0 truncate`,Cd=`min-w-[2.5em] truncate text-[0.8125rem] text-neutral-400`,wd=`flex-none text-[0.75rem] tabular-nums text-neutral-400`,Td=`flex h-7 w-7 flex-none items-center justify-center rounded-[8px] bg-neutral-100 text-neutral-500`;function Ed(e){let t=I(`li`,`palette-row flex cursor-pointer items-center gap-3 rounded-[10px] px-2 leading-5 ${e.hit?`py-1.5`:`min-h-10`}`);t.setAttribute(`role`,`option`),t.append(I(`span`,Td,g(e.icon,`h-4 w-4`)));let n=I(`div`,`flex min-w-0 flex-1 flex-col`),r=I(`div`,`flex items-center gap-2`);e.session&&r.append(...Wu(e.session));let i=I(`span`,xd,I(`span`,`${Sd} ${e.detail?`max-w-[calc(100%-3em)]`:`max-w-full`}`,e.label));e.detail&&i.append(I(`span`,Cd,e.detail)),r.append(i);let a=yd(e);return a!==void 0&&r.append(I(`span`,wd,Yr(a))),n.append(r),e.hit&&n.append(I(`div`,`flex items-baseline gap-2 text-[0.8125rem] leading-5`,I(`span`,`flex-none text-[0.75rem] text-neutral-400`,e.hit.role===`user`?`You`:`Agent`),bd(e.hit.snippet))),t.append(n),t.onclick=e.open,t}var Dd=e=>I(`li`,`px-2 pb-1.5 pt-4 text-[0.6875rem] font-semibold leading-4 tracking-[0.02em] text-neutral-400 first:pt-2`,e);function Od(e,t){let n=I(`li`,`px-2 py-2 pl-12 text-[0.8125rem] leading-5 text-neutral-400`,e);return t&&(n.title=t),n}var kd=e=>e.channel&&e.channel!==`web`?e.channel:``;function Ad(){let e=rd.value.trim(),t=e.toLowerCase().split(/\s+/).filter(Boolean),n=e=>{let n=e.toLowerCase();return t.every(e=>n.includes(e))},r=e=>()=>{nd.close(),e()},i=td.sessions(),a=new Map(i.map(e=>[e.id,e])),{top:o,rest:s}=Iu(i),c=[...o,...s],l=e=>({icon:oe,label:e.title??Qr(e.cwd),detail:[Zr(e.cwd),kd(e)].filter(Boolean).join(` · `),open:r(()=>void td.select(e.id)),session:e}),u=e=>({icon:te,label:Qr(e),detail:e,open:r(()=>void td.createSession(e))}),d=od.filter(t=>!e||n(`${t.label} ${t.detail}`)).map(({name:e,icon:t,label:n,detail:i})=>({icon:t,label:n,detail:i,open:r(()=>td.openConsole(e))})),f={icon:te,label:`New session in…`,detail:`Pick a directory`,open:r($u)},p=[];if(e){let t=He(i).filter(e=>n(Zr(e))).slice(0,cd),o=c.filter(e=>n(`${e.title??``} ${e.cwd} ${kd(e)}`)).slice(0,ld),s=new Set(o.map(e=>e.id)),m=o.map(l);if(dd!==e||!fd)m.push(Od(`Searching messages…`));else if(`error`in fd)m.push(Od(`Message search unavailable`,fd.error));else{for(let e of fd.hits){if(m.length>=ld)break;let t=a.get(e.sessionId);!t||s.has(t.id)||m.push({...l(t),hit:e,open:r(()=>void td.select(t.id).then(()=>Is(e.role,e.at)))})}m.length||m.push(Od(`No sessions match`))}p.push([`Actions`,[...t.map(u),...n(f.label)?[f]:[],...d]],[`Sessions`,m])}else{let e=a.get(td.currentId()??``);p.push([`Running`,c.filter(Uu).map(l)],[`Recent`,c.filter(e=>!Uu(e)).slice(0,sd).map(l)],[`Actions`,[...e?[u(e.cwd)]:[],f]],[`Console`,d])}gd=[];let m=[];for(let[e,t]of p)if(t.length){m.push(Dd(e));for(let e of t){if(e instanceof HTMLElement){m.push(e);continue}let t=Ed(e);gd.push({el:t,open:e.open}),m.push(t)}}id.replaceChildren(...m.length?m:[Od(`Nothing matches`)]),ad.textContent=`${gd.length} ${gd.length===1?`row`:`rows`}`,vd(Math.min(_d,Math.max(0,gd.length-1)))}function jd(){nd.open&&Ad()}function Md(){if(nd.open)return nd.close();rd.value=``,_d=0,hd(``),Ad(),nd.showModal(),rd.focus(),td.loadSessions().then(jd)}function Nd(e){td=e;let t=F(`#open-palette`);t.onclick=Md,Xc(t,`k`,`Search sessions, messages and Console`,Md,()=>nd.open||ca()),nd.onclick=e=>{e.target===nd&&nd.close()},nd.onclose=()=>hd(``),rd.oninput=()=>{_d=0,hd(rd.value.trim()),Ad()},rd.onkeydown=e=>{let t=la(e);if(t!==void 0){e.preventDefault(),vd(_d+t);return}e.key===`Enter`&&!e.ctrlKey&&(e.preventDefault(),gd[_d]?.open())}}var Pd=0,Fd=e=>`${e.provider}/${e.id}`,Id=null;async function Ld(){let{modelMenu:e}=await Ke(`/api/settings`,`Could not read the pinned model menu`);return e}function Rd(e){let t=I(`button`,`flex w-full min-w-0 cursor-pointer items-center gap-2 px-3 py-1.5 text-left hover:bg-neutral-100`,g(o,`h-3 w-3 text-indigo-600 ${e.checked?``:`invisible`}`),I(`span`,`truncate`,e.label));return e.hint&&t.append(I(`span`,`ml-auto flex-none text-[11.5px] text-neutral-400`,e.hint)),e.title&&(t.title=e.title),t.onclick=()=>e.onSelect(),t}function zd({models:e,current:t,thinkingLevel:n,thinkingLevels:r,onPick:i,onThinkingPick:a}){let o=n,s=I(`div`,`flex w-full min-w-0 flex-col sm:min-w-72`),c=I(`div`,`flex flex-col gap-2 border-b border-neutral-200 px-2 py-2`),u=document.createElement(`input`);if(u.type=`search`,u.placeholder=`Search models`,u.setAttribute(`aria-label`,`Search models`),u.className=`w-full rounded-md border border-neutral-300 px-2 py-1.5 text-[12.5px] focus:border-indigo-400 focus:outline-none`,c.append(u),r.length){let e=document.createElement(`details`),t=I(`span`,`ml-auto font-medium text-indigo-700`,Se(o)),n=I(`summary`,`flex min-h-11 cursor-pointer list-none items-center gap-2 rounded-xl px-3 text-sm text-neutral-700 hover:bg-neutral-100 [&::-webkit-details-marker]:hidden`,I(`span`,`font-medium`,`Reasoning effort`),t,g(l,`chev h-3 w-3 text-neutral-400`)),i=I(`fieldset`,`grid grid-cols-2 gap-1 rounded-xl bg-neutral-50 p-1`);i.append(I(`legend`,`sr-only`,`Reasoning effort`));let s=`reasoning-${++Pd}`;for(let e of r){let n=document.createElement(`input`);n.type=`radio`,n.name=s,n.value=e,n.checked=e===o,n.className=`peer sr-only`,n.onchange=()=>{n.checked&&(o=e,t.textContent=Se(o),m(u.value),a(o))},i.append(I(`label`,`relative cursor-pointer`,n,I(`span`,`flex min-h-11 items-center rounded-lg border border-transparent px-3 text-sm text-neutral-700 hover:bg-neutral-100 peer-checked:border-indigo-200 peer-checked:bg-indigo-50 peer-checked:font-semibold peer-checked:text-indigo-700 peer-focus-visible:outline-2 peer-focus-visible:outline-indigo-500`,Se(e))))}e.append(n,i),c.append(e)}let d=I(`div`,`max-h-72 overflow-y-auto py-1`),f=new Map(e.map(e=>[Fd(e),e])),p=e=>{let n=(Id??[]).map(e=>({e,model:f.get(Fd(e))})).filter(t=>!!t.model&&(!e||Fd(t.model).toLowerCase().includes(e)));n.length&&d.append(I(`div`,`px-3 pb-0.5 pt-1 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,`Pinned`),...n.map(({e,model:n})=>Rd({label:n.id,hint:Se(e.thinking),title:e.note,checked:!!t&&Fd(t)===Fd(n)&&o===e.thinking,onSelect:()=>i(n,e.thinking)})),I(`div`,`my-1 border-t border-neutral-100`))},m=n=>{d.replaceChildren();let r=n.trim().toLowerCase();p(r);let a=new Map;for(let t of e){if(r&&!Fd(t).toLowerCase().includes(r))continue;let e=a.get(t.provider);e?e.push(t):a.set(t.provider,[t])}if(!a.size){d.append(I(`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 a){let a=n.some(e=>!!t&&Fd(t)===Fd(e)),o=document.createElement(`details`);o.open=a||r.length>0;let s=I(`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`,g(l,`chev h-3 w-3`),I(`span`,`truncate`,e),I(`span`,`ml-auto flex-none normal-case text-neutral-300`,String(n.length)));o.append(s,...n.map(e=>Rd({label:e.id,checked:!!t&&Fd(t)===Fd(e),onSelect:()=>i(e)}))),d.append(o)}};return u.oninput=()=>m(u.value),m(``),Ld().then(e=>{let t=JSON.stringify(e)!==JSON.stringify(Id);Id=e,t&&m(u.value)}).catch(e=>Fc(`model menu unavailable`,e)),s.append(c,d),queueMicrotask(()=>u.focus()),s}function Bd(e,t,n,r){let i=L(t.model?`${t.model.id}${t.thinking?` · ${Se(t.thinking)}`:``}`:t.thinking?`Pi default · ${Se(t.thinking)}`:`Pi default`,`${wi} flex items-center gap-1.5 ${t.model?`text-neutral-700`:`text-neutral-400`}`);return i.title=t.model?`${t.model.provider}/${t.model.id}`:`Whatever the project and Pi pick`,i.onclick=()=>{let e=zd({models:n,current:t.model,thinkingLevel:t.thinking??`medium`,thinkingLevels:[...Mo],onPick:(e,n)=>{B(),r({model:e,thinking:n??t.thinking})},onThinkingPick:e=>{t={...t,thinking:e},r(t)}}),a=L(`Pi default`,`w-full cursor-pointer px-3 py-1.5 text-left text-[12.5px] text-neutral-500 hover:bg-neutral-100`);a.onclick=()=>{B(),r({model:null,thinking:null})};let o=I(`div`,`flex flex-col`);o.append(e,I(`div`,`border-t border-neutral-200`),a),_a(i,o)},Si(e,i)}var X;function Vd(e){X=e,el(Hd,()=>{X.currentSession()&&(B(),X.toggleFiles())},Kc)}var Hd=`i`,Ud=F(`#chat-title`),Wd=F(`#chat-menu`),Gd=F(`#session-meta`),Kd=null,qd=new Map,Jd=e=>`${e.provider}/${e.id}`,Z=null,Yd=null,Xd=null,Zd=null;function Qd(){Z=null,Yd=null,Xd=null,Zd=null,cf()}function $d(e,t,n,r){Z=e,Yd=t,Xd=n,Zd=r,rf()}function ef(e){Zd=e.completedAt,Yd&&={...Yd,tokens:e.tokens},cf()}var tf=null;function nf(e){tf=e===null?null:Qr(e),rf()}function rf(){let e=X.currentSession();e&&(tf=null),Ud.textContent=e?e.title??Qr(e.cwd):tf??X.currentId()??`no session`,Ud.classList.toggle(`cursor-pointer`,!!e),Ud.title=e?`Session info`:``,Ud.onclick=e?()=>lf(Ud,e):null,Wd.classList.toggle(`hidden`,!e),e&&(Wd.onclick=()=>gf(Wd,e)),cf(),X.syncBar()}var af=70,of=(e,t)=>Math.min(100,Math.round(e/t.contextWindow*100)),sf=e=>e.tokens===null?`?/${Ce(e.contextWindow)}`:`${Ce(e.tokens)}/${Ce(e.contextWindow)} · ${100-of(e.tokens,e)}% left`;function cf(){let e=Yd,t=e?.tokens??null,n=X.currentId(),r=X.currentSession()?.activeRuns??0,i=[];if(r>0){let e=I(`button`,`flex flex-none cursor-pointer items-center gap-1 rounded bg-sky-50 px-1.5 py-px font-medium text-sky-700 hover:bg-sky-100`,g(ie,`spinner h-3 w-3`),`${r} running`);e.title=`${Hu(r)} · show the newest`,e.onclick=()=>{Ls()||W(`error`,`no run card left in this transcript — reload the session to see it`)},i.push(e)}if(!n&&tf&&i.push(I(`span`,`flex flex-none items-center gap-1.5 text-neutral-500`,g(ie,`spinner`),`starting…`)),n){let e=(e,t)=>{let r=I(`button`,`cursor-pointer font-mono ${t}`,e);return r.title=`Change model or reasoning`,r.onclick=()=>void uf(r,n),r};Z&&i.push(e(Z.id,`min-w-0 truncate rounded bg-indigo-50 px-1.5 py-px font-medium text-indigo-700 hover:bg-indigo-100`)),Xd&&i.push(e(Xd,`flex-none text-neutral-500 hover:text-indigo-700`))}let a=0;if(e&&t!==null){a=of(t,e);let n=a>=90?`text-red-700`:a>=af?`text-amber-700`:`text-neutral-500`;i.push(I(`span`,`flex-none font-mono ${n}`,Ce(t).toLowerCase()))}let o=i.flatMap((e,t)=>t===0?[e]:[I(`span`,`flex-none text-neutral-300`,`·`),e]);Gd.replaceChildren(...o),Gd.classList.toggle(`hidden`,i.length===0),Gd.classList.toggle(`flex`,i.length>0),Gd.toggleAttribute(`data-urgent`,!n&&!!tf||r>0||a>=af)}function lf(e,t,n){let i=[[`Directory`,t.cwd],[`Session`,t.id]],a=t.id===X.currentId();if(a&&(i.push([`Model`,Z?.id??`—`]),i.push([`Reasoning`,Xd??`—`]),i.push([`Context`,Yd?sf(Yd):`—`])),i.push([`Created`,$r(t.createdAt),Xr(t.createdAt)]),a){let e=Zd;i.push(e===null?[`Last reply`,`—`]:[`Last reply`,$r(e),Xr(e)])}let o=I(`div`,`w-[min(26rem,calc(100vw-2rem))] max-sm:w-full rounded-xl bg-white px-3 py-3 font-sans text-[15px] leading-normal`),s=I(`button`,`icon-btn h-11 w-11 sm:h-8 sm:w-8`,g(ve));s.setAttribute(`aria-label`,`Close session info`),s.onclick=B;let c=I(`div`,`sticky top-0 z-10 flex items-start gap-2 bg-white pb-2`,I(`div`,`min-w-0 flex-1`,I(`div`,`text-sm font-medium text-neutral-500`,`Session info`),I(`h2`,`mt-1 [overflow-wrap:anywhere] text-lg leading-7 font-semibold text-neutral-900`,t.title??Qr(t.cwd))),s);if(n){let e=I(`button`,`icon-btn h-11 w-11 sm:h-8 sm:w-8`,g(r));e.setAttribute(`aria-label`,`Back to session actions`),e.onclick=n,c.prepend(e)}o.append(c);let l=I(`dl`,``);for(let[e,t,n]of i){let r=e===`Directory`||e===`Session`,i=I(`dd`,`min-w-0 flex items-start gap-2 text-neutral-700 ${r?`font-mono text-sm leading-6`:``}`,I(`span`,`min-w-0 flex-1 [overflow-wrap:anywhere]`,t));if(r){let n=ai(`min-h-11 min-w-11 sm:min-h-8 shrink-0 cursor-pointer rounded-lg px-2 py-1 text-[13px] font-sans text-neutral-500 hover:bg-neutral-100 focus-visible:outline-2`,()=>t);n.setAttribute(`aria-label`,`Copy ${e.toLowerCase()}`),i.append(n)}n&&i.firstElementChild?.append(I(`span`,`ml-2 inline-block font-sans text-[13px] leading-5 text-neutral-500`,n));let a=e===`Model`||e===`Created`;l.append(I(`div`,`grid gap-1 py-1.5 sm:grid-cols-[5.5rem_minmax(0,1fr)] sm:gap-3 ${a?`mt-2 border-t border-neutral-200 pt-2.5`:``}`,I(`dt`,`text-[15px] text-neutral-500`,e===`Session`?`Session ID`:e),i))}return o.append(l),_a(e,o)}async function uf(e,t,n){let r=I(`div`,`px-3 py-3 text-[15px] text-neutral-500`,`Loading models…`),i=I(`div`,`w-[min(24rem,calc(100vw-2rem))] min-w-0 max-sm:w-full`,r),a=r;n&&i.prepend(mf(e,n,`Close model picker`)),_a(e,i);let o=()=>a.isConnected&&!a.closest(`[inert]`),s=``,c=(n,r,o)=>{let c=JSON.stringify([n,r,o]);if(c===s)return;s=c;let l=zd({models:n,current:t===X.currentId()?Z:null,thinkingLevel:r,thinkingLevels:o,onPick:(e,n)=>{B(),df(t,e,n)},onThinkingPick:e=>void pf(t,e)});a.replaceWith(l),a=l,_a(e,i)},l=t===X.currentId()&&Z?qd.get(Jd(Z)):void 0;Kd&&l&&Xd&&c(Kd,Xd,l);try{let[e,n]=await Promise.all([Ke(`/api/sessions/${t}/models`,`Could not load models`),Ke(`/api/sessions/${t}/thinking`,`Could not read the reasoning level`)]);if(Kd=e,t===X.currentId()&&Z&&qd.set(Jd(Z),n.levels),!o())return;c(e,n.level,n.levels)}catch(e){s?W(`error`,`model options are stale: ${String(e)}`):o()?(r.textContent=`Could not load models: ${String(e)}`,r.setAttribute(`role`,`alert`)):W(`error`,`model options failed: ${String(e)}`)}}async function df(e,t,n){await ff(e,t)&&n&&await pf(e,n)}async function ff(e,t){let n=Z;e===X.currentId()&&(Z=t,rf());let r=await b(`/api/sessions/${e}/model`,t);if(!r.ok){let{error:t}=await r.json().catch(()=>({}));return e===X.currentId()&&(Z=n,rf()),W(`error`,`model change failed: ${t??r.status}`),!1}let{model:i}=await r.json();return e===X.currentId()&&i&&(Z=i,rf()),!0}async function pf(e,t){let n=await b(`/api/sessions/${e}/thinking`,{level:t});if(!n.ok){W(`error`,`reasoning change failed: ${n.status}`);return}let{level:r}=await n.json();e===X.currentId()&&(Xd=r,cf())}function mf(e,t,n){let i=I(`button`,`icon-btn h-11 w-11`,g(r));i.setAttribute(`aria-label`,`Back to session actions`),i.onclick=()=>gf(e,t);let a=I(`button`,`icon-btn h-11 w-11`,g(ve));a.setAttribute(`aria-label`,n),a.onclick=B;let o=I(`span`,`min-w-0 flex-1 truncate text-sm font-medium`,t.title??Qr(t.cwd));return o.title=o.textContent??``,I(`div`,`flex items-center gap-2 border-b border-neutral-200 pb-2 mb-2`,i,o,a)}async function hf(e,t){let n=I(`p`,`px-3 py-2 text-[15px] text-neutral-500`,`Loading chats…`),r=I(`div`,`w-[min(24rem,calc(100vw-2rem))] min-w-0 max-sm:w-full`,mf(e,t,`Close chat picker`),I(`div`,`px-3 pb-1 text-sm font-medium text-neutral-500`,`Continue in a direct message`),I(`p`,`px-3 pb-2 text-[13px] text-neutral-500`,`DMs the bot has seen. A DM appears here after its first message to the bot.`),n);_a(e,r);let i=await S(`/api/handoff/targets`,`Could not list chats`);if(!r.isConnected)return;if(!i.ok){n.textContent=i.error,n.setAttribute(`role`,`alert`);return}if(!i.value.targets.length){n.textContent=`No DMs yet — message the bot once in Lark or Slack, then come back.`;return}let a=I(`p`,`hidden px-3 pt-1 text-[13px] text-red-600`);a.setAttribute(`role`,`alert`);let o=I(`div`,``);o.dataset.list=``;for(let e of i.value.targets){let n=I(`button`,`flex w-full min-h-10 cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left transition-colors hover:bg-indigo-50 hover:text-indigo-700 active:bg-indigo-100`,I(`span`,`min-w-0 truncate`,`${e.platform[0].toUpperCase()}${e.platform.slice(1)} · ${e.name||e.chatId}`));n.onclick=async()=>{let n=await b(`/api/handoff`,{sessionId:t.id,platform:e.platform,chatId:e.chatId});if(n.ok)return B();a.textContent=(await n.json().catch(()=>({}))).error??`handoff failed: ${String(n.status)}`,a.classList.remove(`hidden`)},o.append(n)}n.replaceWith(o,a),o.querySelector(`button`)?.focus({preventScroll:!0})}function gf(e,t){let n=t.id===X.currentId();ya(e,[{label:`Rename…`,onSelect:()=>{B(),Gu(t)}},{label:`Session info`,onSelect:()=>lf(e,t,()=>gf(e,t))},{label:`New session here`,separatorBefore:!0,hint:Zr(t.cwd),onSelect:()=>{B(),X.createSession(t.cwd)}},{label:`Browse files`,hint:n?Gc(Hd):``,onSelect:()=>{B(),X.openFiles(n?void 0:t.cwd)}},{label:`Continue in Lark/Slack…`,...t.channel&&t.channel!==`web`?{hint:`answers in ${t.channel}`,disabled:!0}:{},onSelect:()=>void hf(e,t)},{label:`Model & reasoning…`,separatorBefore:!0,hint:n?Z?.id??`…`:``,onSelect:()=>void uf(e,t.id,t)}],t.title??Qr(t.cwd))}var _f=`pier.theme`,vf=[`system`,`light`,`dark`],yf=window.matchMedia(`(prefers-color-scheme: dark)`),bf={system:ce,light:ge,dark:h},xf=()=>{let e=null;try{e=localStorage.getItem(_f)}catch{return`system`}return e===`light`||e===`dark`?e:`system`},Sf=()=>{let e=xf();return e===`system`?yf.matches?`dark`:`light`:e};function Cf(){let e=Sf();document.documentElement.dataset.theme=e;let t=getComputedStyle(document.documentElement).getPropertyValue(`--workbench-canvas`).trim();F(`meta[name="theme-color"]`).setAttribute(`content`,t),window.dispatchEvent(new Event(`pier:theme`))}function wf(){let e=F(`#theme-toggle`),t=()=>{let t=xf();e.title=`Theme: ${t}${t===`system`?` (${Sf()})`:``}`,e.replaceChildren(g(bf[t])),e.setAttribute(`aria-label`,e.title),Cf()};e.onclick=()=>{let e=vf[(vf.indexOf(xf())+1)%vf.length];try{e===`system`?localStorage.removeItem(_f):localStorage.setItem(_f,e)}catch{}t()},yf.addEventListener(`change`,t),t()}var Tf=`https://github.com/timqi/pier`,Ef=[`text-neutral-400`,`hover:text-neutral-700`],Df=[`rounded-full`,`bg-emerald-50`,`px-1.5`,`text-emerald-700`,`ring-1`,`ring-inset`,`ring-emerald-600/20`,`hover:bg-emerald-100`],Of=18e5,kf=null,Af=F(`#version`);function jf(e){let t=kf?.available===!0&&kf.latest!==null;Af.textContent=`v${e}`,Af.title=t?`Pier ${kf?.latest} is out`:``,Af.classList.remove(...t?Ef:Df),Af.classList.add(...t?Df:Ef)}var Mf=(e,t=`px-3 py-1 text-[12px] leading-snug text-neutral-500`)=>I(`p`,t,e);function Nf(){let e=I(`div`,`flex w-72 flex-col gap-1 py-1`);if(!kf)return e.append(Mf(`Checking the registry…`)),e;let{current:t,latest:n,available:r,canApply:i,problem:a}=kf,o=I(`span`,``,``),s=(e,t)=>R(o,e?`failed`:`idle`,t),c=I(`div`,`flex items-center gap-2 px-3 py-1.5`);if(e.append(Mf(r?`Pier ${n} is out`:`Pier ${t}`,`px-3 py-1 text-[12.5px] font-medium text-neutral-700`),Mf(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.`)),a&&e.append(Mf(a,`mx-3 my-1 rounded-md bg-red-50 px-2 py-1.5 text-[11.5px] leading-snug text-red-700`)),r&&i&&!a){let e=di(`Update now`,!0);e.onclick=()=>void(async()=>{e.disabled=!0,s(!1,`starting the updater…`);let t=await b(`/api/update`,{});if(!t.ok)return e.disabled=!1,s(!0,await x(t,`Could not update`));let{draining:n}=await t.json();s(!1,n?`Waiting for running work to finish — Pier then installs and restarts.`:`Installing — Pier restarts once it is on disk, and this page reconnects on its own.`)})(),c.append(e)}c.append(Object.assign(I(`a`,`btn text-[12.5px] no-underline`,`Source`),{href:r?`${Tf}/releases`:Tf,target:`_blank`,rel:`noreferrer`,title:`Pier is free software (AGPL-3.0)`})),e.append(c,I(`div`,`px-3`,o)),r&&!i&&!a&&e.append(Mf(`No service manager owns this Pier, so it cannot restart itself — update it with: pier update`));let l=ki(`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.`,kf.autoUpdate,e=>void(async()=>{kf&&(kf.autoUpdate=e);let t=await b(`/api/settings`,{autoUpdate:e},`PUT`);t.ok||(kf&&(kf.autoUpdate=!e),u&&(u.checked=!e),s(!0,await x(t,`Could not save`)))})()),u=l.querySelector(`input`);return u&&(u.disabled=!i),e.append(I(`div`,`mt-1 border-t border-neutral-200 px-3 pb-1 pt-2`,l)),e}async function Pf(e){let t=await S(`/api/update`,`Update check failed`);t.ok&&jf((kf=t.value).current||e)}function Ff(e){jf(e),Af.onclick=e=>{e.preventDefault(),_a(Af,Nf())};let t=()=>void Pf(e);t(),setInterval(t,Of)}var Q,If=F(`#chat-header`),Lf=F(`#chat-title`),Rf=[If,U,F(`#composer`)],zf=()=>Kf===null,Bf,Vf,Hf,Uf=new Map,Wf=new Map,Gf=new Map,Kf=null,qf=0,Jf=[`files`],Yf=new Map,Xf={tasks:`Tasks`,runs:`Runs`,activity:`Activity`,boards:`Boards`,settings:`Settings`,files:`Files`},Zf=[`tasks`,`runs`,`activity`],Qf=`Automation`,$f=F(`#automation-view`),ep=F(`#automation-tabs`),tp=e=>Zf.includes(e)?`tasks`:e;function np(e,t){let n=e!==null&&Zf.includes(e);if($f.classList.toggle(`hidden`,!n),$f.classList.toggle(`flex`,n),!n)return;let r=[];if(e===`tasks`&&!t){let e=di(`New task`,!0);e.classList.add(`ml-auto`),e.disabled=!Bf,e.onclick=()=>Bf?.create(),r.push(e)}ep.replaceChildren(fi(Qf),...Zf.map(t=>gi(Xf[t],t===e,()=>sp(t))),...r)}var rp=e=>Bf?.refresh(e),ip=()=>Vf?.refresh(),ap=()=>Hf?.refresh();function op(){Kf?gu(Zf.includes(Kf)?Qf:Xf[Kf],!1):gu(Lf.textContent??``,Q.currentSession()!==void 0)}function sp(e,t,n){if(Jf.includes(e)){let t=yp();t&&(t.kind!==`console`||t.name!==e)&&Yf.set(e,t)}xp({kind:`console`,name:e,arg:t,query:n}),hu(),Kf=e;for(let e of Rf)e.classList.add(`hidden`);wl();for(let[t,n]of Uf)t!==e&&n.hide();for(let[t,n]of Gf)n.classList.toggle(`bg-indigo-50`,t===tp(e));np(e,t),op(),cp(e,t,n,++qf)}async function cp(e,t,n,r){let i=Uf.get(e);if(!i){let t=Wf.get(e);if(!t){let n=F(`#${e}-view`);t=wp[e](n).catch(t=>(console.warn(`${e} view failed to load`,t),ti(n,()=>n.replaceChildren(I(`p`,`p-4 text-[13px] text-red-600`,`Could not load ${Xf[e]} — reload the page.`))))),Wf.set(e,t)}i=await t,Uf.set(e,i),Wf.delete(e)}Kf===e&&r===qf&&(i.show(t,n),e===`tasks`&&np(e,t))}var lp=e=>sp(`tasks`,e),up=(e={},t)=>sp(`runs`,t,new URLSearchParams(e).toString()),dp=e=>up({},e),fp=(e,t)=>sp(`files`,e,t?new URLSearchParams({select:t}).toString():void 0),pp=(e,t)=>{Kf===e?hp(e):sp(e,t)},mp=e=>pp(`files`,e);function hp(e){let t=Q.currentId(),n=Yf.get(e)??(t?{kind:`session`,id:t}:null);Yf.delete(e),n?xp(n):(history.replaceState(null,``,`#/`),gp())}function gp(){if(Kf){Kf=null;for(let e of Uf.values())e.hide();for(let e of Gf.values())e.classList.remove(`bg-indigo-50`);np(null);for(let e of Rf)e.classList.remove(`hidden`);wl(),op(),Q.maybeAckRead()}}var _p=e=>e.kind===`session`?`#/session/${encodeURIComponent(e.id)}`:`#/${e.name}${e.arg?`/${encodeURIComponent(e.arg)}`:``}${e.query?`?${e.query}`:``}`,vp={config:`files`,channels:`channels`,providers:`models`};function yp(){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 vp[n]?{kind:`console`,name:`settings`,arg:vp[n]}:Object.hasOwn(Xf,n)?{kind:`console`,name:n,arg:a,query:i}:n===`session`&&a?{kind:`session`,id:a}:null}var bp=!1;function xp(e,t=!1){if(bp)return;let n=_p(e);location.hash!==n&&(t?history.replaceState(null,``,n):location.hash=n)}var Sp=e=>xp({kind:`session`,id:e});function Cp(){let e=yp(),t=Q.sessions(),n=Q.currentId(),r=e?.kind===`session`?e.id:null,{top:i,rest:a}=Iu(t),o=r??n??(i[0]??a[0])?.id??null;bp=!0;try{o&&o!==n&&Q.select(o),e?.kind===`console`?sp(e.name,e.arg,e.query):gp(),o||rf()}finally{bp=!1}e?.kind!==`console`&&o&&xp({kind:`session`,id:o},!0)}var wp={tasks:async e=>Bf=(await Gi(async()=>{let{createTasksView:e}=await import(`./tasks-DqrNu2Tz.js`);return{createTasksView:e}},__vite__mapDeps([0,1]))).createTasksView(e,()=>Q.sessions().map(({id:e,cwd:t,title:n})=>({id:e,cwd:t,title:n})),Q.loadSessions,Q.select,()=>Q.currentId(),up,lp),runs:async e=>Vf=(await Gi(async()=>{let{createRunsView:e}=await import(`./runs-BNv9MSL2.js`);return{createRunsView:e}},__vite__mapDeps([2,1]))).createRunsView(e,Q.select,up,lp),activity:async e=>Hf=(await Gi(async()=>{let{createActivityView:e}=await import(`./activity-C9PhqKVX.js`);return{createActivityView:e}},[])).createActivityView(e,Q.select,dp),boards:async e=>(await Gi(async()=>{let{createBoardsView:e}=await import(`./boards-YW0uAwJI.js`);return{createBoardsView:e}},[])).createBoardsView(e,Q.select),files:async e=>(await Gi(async()=>{let{createExplorerView:e}=await import(`./explorer-BNm0Cr51.js`);return{createExplorerView:e}},[])).createExplorerView(e,()=>Q.currentSession(),e=>sp(`files`,e),()=>hp(`files`)),settings:async e=>(await Gi(async()=>{let{createSettingsView:e}=await import(`./settings-Dxxux4Un.js`);return{createSettingsView:e}},[])).createSettingsView(e,()=>He(Q.sessions()),e=>sp(`settings`,e),fp)};function Tp(e){Q=e;for(let e of[`tasks`,`boards`,`settings`]){let t=F(`#open-${e}`);Gf.set(e,t),t.onclick=()=>sp(e)}let t=F(`#console-section`);t.open=localStorage.getItem(`pier.consoleCollapsed`)!==`1`,t.ontoggle=()=>localStorage.setItem(`pier.consoleCollapsed`,t.open?`0`:`1`),window.onhashchange=Cp}var Ep=[],Dp=null,Op=0,kp=0,Ap=!1,$=null,jp=`idle`,Mp=null,Np=0,Pp=!1,Fp=!1;async function Ip(e){let t=++Op;++kp,Ap=!1,gp(),hu(),$=null,Mp?.close(),Mp=null,Ec(),Tl([]),Qd(),nf(e),Dc(!0),Fp=!0,Cl();let n=await b(`/api/sessions`,{cwd:e});if(t!==Op)return;if(Fp=!1,!n.ok){Dc(!1),nf(null),Cl(),W(`error`,`session create failed: ${n.status}`);return}let{id:r}=await n.json();t===Op&&(Ep.unshift({id:r,cwd:e,createdAt:Date.now(),state:`idle`,unread:!1,channel:`web`,activeRuns:0}),await qp(r),$===r&&yl())}function Lp(e){Ep=e.map(e=>({...e,title:Be(e.title)})),Ep.sort((e,t)=>t.createdAt-e.createdAt),Qu(),rf(),zp()}var Rp=Ue(async()=>{Lp(await Ke(`/api/sessions`,`Could not load sessions`))});function zp(){if(document.hidden||!document.hasFocus()||!zf())return;let e=Ep.find(e=>e.id===$);e?.unread&&(e.unread=!1,Qu(),fetch(`/api/sessions/${e.id}/read`,{method:`POST`}))}function Bp(){return Ep.find(e=>e.id===$)??(Dp&&Dp.id===$?Dp:void 0)}async function Vp(e){let t=await S(`/api/sessions/${e}`,`failed to load session`);$!==e||!t.ok||(Dp={...t.value,title:Be(t.value.title)},rf())}function Hp(e,t){let n=Ep.find(t=>t.id===e);!n||n.title||!t.trim()||(n.title=t.trim().slice(0,80),Qu(),rf())}function Up(e){jp=e;let t=Ep.find(e=>e.id===$);t&&(t.state=e),Qu(),rf(),Cl(),e===`idle`&&Rp()}function Wp(e){if(!(e.sessionId!==$||e.seq<=Np))switch(Np=e.seq,e.type){case`turn-start`:Pp=!0;break;case`system-input`:Sc(),Js(e.text,e.origin);break;case`task-status`:Ko(e.run);break;case`user-message`:{let t=Le(e.text).text;if(Hp(e.sessionId,t),bl(t))break;Sc(),W(`user`,e.text,!1,e.ts),Ps();break}case`text-start`:Sc();break;case`text-delta`:xc(e.text);break;case`thinking-delta`:Sc(),bs(e.ts,e.text);break;case`tool-start`:Sc(),vs(e.ts,e.toolCallId,e.toolName,e.args);break;case`tool-end`:ys(e.toolCallId,e.isError,e.output);break;case`turn-end`:Pp=!1,wc(e.text,e.meta),e.meta&&ef(e.meta);break;case`queue-state`:El(e.steering,e.followUp);break;case`queue-recovery`:Tl(e.batches,e.uncertain);break;case`context-compacted`:Sc(),W(`system`,`Context compacted — ${Ce(e.before)} → ${Ce(e.after)}`,!1,e.ts),Ps();break;case`error`:gs(),W(`error`,e.message);break;case`state`:e.state===`idle`&&Pp&&(Pp=!1,Tc()),e.state===`idle`&&El([],[]),Up(e.state)}}function Gp(){let e=new EventSource(`/api/events`);e.onopen=()=>{Rp(),rp(),ip(),ap()},e.onerror=()=>Bc(e,`Workspace`),e.onmessage=e=>{let t=JSON.parse(e.data);if(t.type===`sessions-changed`){Rp();return}if(t.type===`tasks-changed`||t.type===`task-run-changed`||t.type===`task-message-changed`||t.type===`task-group-changed`){rp(t.type===`task-run-changed`?t.taskId:void 0),ip(),ap(),t.type===`task-run-changed`&&Rp();return}if(ap(),t.sessionId===$)return;let n=Ep.find(e=>e.id===t.sessionId);n&&(n.state=t.state,Qu())}}function Kp(e,t,n){Mp?.close();let r=new EventSource(`/api/sessions/${e}/events?after=${t}`),i=()=>Mp===r&&$===e&&n===kp;r.onmessage=e=>{i()&&Wp(JSON.parse(e.data))},r.addEventListener(`reset`,()=>{i()&&Jp(e)}),r.onerror=()=>{i()&&Bc(r,`Session`)},Mp=r}async function qp(e){gp(),hu(),Sp(e),!(e===$&&(Mp||Ap))&&(++Op,++kp,Fp=!1,Ll(),$=e,Dp=null,Ep.some(t=>t.id===e)||Vp(e),jp=Ep.find(t=>t.id===e)?.state??`idle`,Rl(e),Qu(),rf(),zp(),await Jp(e))}async function Jp(e){if($!==e)return;let t=++kp;Mp?.close(),Mp=null,Ap=!0,Ec(),El([],[]),Tl([]),Qd(),Pp=!1,Sl(),Np=0,Dc(!0);let n=await S(`/api/sessions/${e}/history`,`failed to load session`);if($!==e||t!==kp)return;if(Ap=!1,!n.ok){Dc(!1),W(`error`,n.error);return}let r=n.value;Oc(r.turns,r.state,r.backgroundRuns),Np=r.lastSeq,Pp=r.state===`streaming`,Up(r.state),El(r.queue.steering,r.queue.followUp),Tl(r.queueRecovery,r.queueUncertain);let i=r.turns.reduce((e,t)=>t.meta?.completedAt??e,null);$d(r.model,r.context,r.thinkingLevel,i),Kp(e,`${r.epoch}:${r.lastSeq}`,t)}Ic(),ye(),zc(),wf();var Yp=async e=>{$===e&&await Jp(e)};Es({sessionId:()=>$,sessionCwd:()=>Bp()?.cwd??null,sessionChannel:()=>Bp()?.channel??null,sessionState:()=>jp,select:e=>void qp(e),showRun:dp,send:(e,t)=>void Vl(e,t),ownTurn:e=>{xl(e),Up(`streaming`)},reload:Yp}),Wl({sessionId:()=>$,starting:()=>Fp,sessionState:()=>jp,chatVisible:zf,setState:Up,reload:Yp}),Mu({sessionMenu:e=>{let t=Bp();t&&gf(e,t)},sessionInfo:e=>{let t=Bp();t&&lf(e,t)}}),ed({sessions:()=>Ep,currentId:()=>$,select:e=>void qp(e),sessionMenu:gf,createSession:Ip,onTitleChanged:rf}),Nd({sessions:()=>Ep,loadSessions:Rp,currentId:()=>$,select:qp,createSession:Ip,openConsole:sp}),Vd({currentId:()=>$,currentSession:Bp,createSession:e=>void Ip(e),syncBar:op,openFiles:fp,toggleFiles:mp}),Tp({sessions:()=>Ep,loadSessions:Rp,currentId:()=>$,currentSession:Bp,select:e=>void qp(e),maybeAckRead:zp}),Ff(`0.1.10`),au(),document.addEventListener(`gesturestart`,e=>e.preventDefault()),document.addEventListener(`visibilitychange`,zp),window.addEventListener(`focus`,zp),Gp(),Rp().then(Cp);export{x as $,Pi as A,ki as B,ji as C,Mi as D,xi as E,Di as F,ti as G,Fi as H,R as I,ei as J,ai as K,hi as L,fi as M,gi as N,Ni as O,mi as P,Ue as Q,Ti as R,Ai as S,di as T,Xr as U,pi as V,Zr as W,Yr as X,I as Y,Qr as Z,Ci as _,$c as a,Be as at,_i as b,Aa as c,ve as ct,ya as d,l as dt,S as et,_a as f,s as ft,bi as g,Zi as h,uu as i,b as it,Ei as j,Si as k,Da as l,de as lt,ea as m,a as mt,Bd as n,Ge as nt,Mo as o,Se as ot,ta as p,o as pt,ui as q,zd as r,qe as rt,No as s,g as st,lf as t,Ke as tt,B as u,ie as ut,wi as v,L as w,vi as x,yi as y,Oi as z};
|
|
85
|
+
`),r}var Yu=()=>`${Y.currentId()??``}\n${Zu}\n${JSON.stringify(Y.sessions())}`,Xu=``,Zu=20;function Qu(){let e=Yu();if(e===Xu)return;Xu=e;let t=Y.sessions(),n=t.filter(Vu);Du(n.length),lu(n.length);let{rows:r,hidden:i}=Lu(t,Zu),a=Nu.querySelector(`.session-more[aria-expanded='true']`),o=a?.closest(`[data-session-id]`)?.dataset.sessionId,s=r.map(e=>Ju(e,e.id===o?a:void 0));if(i>0){let e=I(`button`,`session-open w-full cursor-pointer rounded-lg text-left text-sm text-neutral-500`,`Load more (${i})`);e.id=`session-load-more`,e.setAttribute(`type`,`button`),e.onclick=()=>{Zu+=20,Qu(),Nu.querySelectorAll(`.session-open`)[r.length]?.focus()},s.push(I(`li`,`hover:bg-neutral-100`,e))}let c=document.activeElement,l=c?.closest(`[data-session-id]`)?.dataset.sessionId,u=c?.classList.contains(`session-more`)?`.session-more`:`.session-open`;if(Nu.replaceChildren(...s.length?[I(`ul`,`pb-1`,...s)]:[I(`p`,`px-3 py-2 text-sm leading-normal text-neutral-500`,`No sessions yet — create one.`)]),l){let e=[...Nu.querySelectorAll(`[data-session-id]`)].find(e=>e.dataset.sessionId===l);e?.querySelector(`.session-open`)?.focus({preventScroll:!0}),u===`.session-more`&&e?.querySelector(u)?.focus({preventScroll:!0})}else c?.id===`session-load-more`&&(Nu.querySelector(`#session-load-more`)??Nu.querySelector(`.session-open`)??F(`#new-session`)).focus({preventScroll:!0});jd()}function $u(){if(Pu.getAttribute(`aria-expanded`)===`true`)return B();let e=Y.sessions().find(e=>e.id===Y.currentId())?.cwd,t=He(Y.sessions()).slice(0,zu);if(e&&!t.includes(e)&&t.unshift(e),!t.length)return Ea(Pu,void 0,Y.createSession);Da(Pu,t.map(e=>({path:e,hint:Zr(e)})),e,Y.createSession)}function ed(e){Y=e,Pu.onclick=$u,Xc(Pu,`shift+o`,`New session`,$u,Kc);let t=e=>{let t=Ru(Y.sessions(),Y.currentId(),e);t&&Y.select(t)};el(`shift+[`,()=>t(-1),Kc),el(`shift+]`,()=>t(1),Kc)}var td,nd=F(`#palette`),rd=F(`#palette-input`),id=F(`#palette-list`),ad=F(`#palette-count`),od=[{name:`tasks`,icon:re,label:`Tasks`,detail:`Automation — task definitions and schedules`},{name:`runs`,icon:re,label:`Runs`,detail:`Automation — executions, subagents and callbacks`},{name:`activity`,icon:re,label:`Activity`,detail:`Automation — sessions and relationships`},{name:`boards`,icon:ne,label:`Boards`,detail:`Console — the static pages Pier publishes`},{name:`settings`,icon:me,label:`Settings`,detail:`Console — models and providers, agent files and extensions, channels, password, sign out, security`}],sd=7,cd=3,ld=8,ud=80,dd=``,fd,pd,md;function hd(e){dd!==e&&(clearTimeout(md),pd?.abort(),pd=void 0,dd=e,fd=void 0,e&&(md=setTimeout(()=>{let t=pd=new AbortController;S(`/api/search?q=${encodeURIComponent(e)}`,`Search unavailable`,{signal:t.signal}).then(n=>{t.signal.aborted||dd!==e||(pd=void 0,fd=n.ok?{hits:n.value.hits}:{error:n.error},nd.open&&Ad())})},ud)))}var gd=[],_d=0;function vd(e){if(gd.length){_d=(e+gd.length)%gd.length;for(let[e,{el:t}]of gd.entries())t.classList.toggle(`bg-indigo-50`,e===_d),t.setAttribute(`aria-selected`,String(e===_d));gd[_d]?.el.scrollIntoView({block:`nearest`})}}var yd=e=>e.hit?.at??e.session?.createdAt;function bd(e){let t=I(`span`,`min-w-0 flex-1 truncate text-neutral-500`);for(let n of e.replaceAll(/\s+/g,` `).split(``)){let[e=``,r]=n.split(``,2);r===void 0?t.append(e):t.append(I(`span`,`font-medium text-neutral-800`,e),r)}return t}var xd=`flex min-w-0 flex-1 items-baseline gap-2`,Sd=`shrink-0 truncate`,Cd=`min-w-[2.5em] truncate text-[0.8125rem] text-neutral-400`,wd=`flex-none text-[0.75rem] tabular-nums text-neutral-400`,Td=`flex h-7 w-7 flex-none items-center justify-center rounded-[8px] bg-neutral-100 text-neutral-500`;function Ed(e){let t=I(`li`,`palette-row flex cursor-pointer items-center gap-3 rounded-[10px] px-2 leading-5 ${e.hit?`py-1.5`:`min-h-10`}`);t.setAttribute(`role`,`option`),t.append(I(`span`,Td,g(e.icon,`h-4 w-4`)));let n=I(`div`,`flex min-w-0 flex-1 flex-col`),r=I(`div`,`flex items-center gap-2`);e.session&&r.append(...Wu(e.session));let i=I(`span`,xd,I(`span`,`${Sd} ${e.detail?`max-w-[calc(100%-3em)]`:`max-w-full`}`,e.label));e.detail&&i.append(I(`span`,Cd,e.detail)),r.append(i);let a=yd(e);return a!==void 0&&r.append(I(`span`,wd,Yr(a))),n.append(r),e.hit&&n.append(I(`div`,`flex items-baseline gap-2 text-[0.8125rem] leading-5`,I(`span`,`flex-none text-[0.75rem] text-neutral-400`,e.hit.role===`user`?`You`:`Agent`),bd(e.hit.snippet))),t.append(n),t.onclick=e.open,t}var Dd=e=>I(`li`,`px-2 pb-1.5 pt-4 text-[0.6875rem] font-semibold leading-4 tracking-[0.02em] text-neutral-400 first:pt-2`,e);function Od(e,t){let n=I(`li`,`px-2 py-2 pl-12 text-[0.8125rem] leading-5 text-neutral-400`,e);return t&&(n.title=t),n}var kd=e=>e.channel&&e.channel!==`web`?e.channel:``;function Ad(){let e=rd.value.trim(),t=e.toLowerCase().split(/\s+/).filter(Boolean),n=e=>{let n=e.toLowerCase();return t.every(e=>n.includes(e))},r=e=>()=>{nd.close(),e()},i=td.sessions(),a=new Map(i.map(e=>[e.id,e])),{top:o,rest:s}=Iu(i),c=[...o,...s],l=e=>({icon:oe,label:e.title??Qr(e.cwd),detail:[Zr(e.cwd),kd(e)].filter(Boolean).join(` · `),open:r(()=>void td.select(e.id)),session:e}),u=e=>({icon:te,label:Qr(e),detail:e,open:r(()=>void td.createSession(e))}),d=od.filter(t=>!e||n(`${t.label} ${t.detail}`)).map(({name:e,icon:t,label:n,detail:i})=>({icon:t,label:n,detail:i,open:r(()=>td.openConsole(e))})),f={icon:te,label:`New session in…`,detail:`Pick a directory`,open:r($u)},p=[];if(e){let t=He(i).filter(e=>n(Zr(e))).slice(0,cd),o=c.filter(e=>n(`${e.title??``} ${e.cwd} ${kd(e)}`)).slice(0,ld),s=new Set(o.map(e=>e.id)),m=o.map(l);if(dd!==e||!fd)m.push(Od(`Searching messages…`));else if(`error`in fd)m.push(Od(`Message search unavailable`,fd.error));else{for(let e of fd.hits){if(m.length>=ld)break;let t=a.get(e.sessionId);!t||s.has(t.id)||m.push({...l(t),hit:e,open:r(()=>void td.select(t.id).then(()=>Is(e.role,e.at)))})}m.length||m.push(Od(`No sessions match`))}p.push([`Actions`,[...t.map(u),...n(f.label)?[f]:[],...d]],[`Sessions`,m])}else{let e=a.get(td.currentId()??``);p.push([`Running`,c.filter(Uu).map(l)],[`Recent`,c.filter(e=>!Uu(e)).slice(0,sd).map(l)],[`Actions`,[...e?[u(e.cwd)]:[],f]],[`Console`,d])}gd=[];let m=[];for(let[e,t]of p)if(t.length){m.push(Dd(e));for(let e of t){if(e instanceof HTMLElement){m.push(e);continue}let t=Ed(e);gd.push({el:t,open:e.open}),m.push(t)}}id.replaceChildren(...m.length?m:[Od(`Nothing matches`)]),ad.textContent=`${gd.length} ${gd.length===1?`row`:`rows`}`,vd(Math.min(_d,Math.max(0,gd.length-1)))}function jd(){nd.open&&Ad()}function Md(){if(nd.open)return nd.close();rd.value=``,_d=0,hd(``),Ad(),nd.showModal(),rd.focus(),td.loadSessions().then(jd)}function Nd(e){td=e;let t=F(`#open-palette`);t.onclick=Md,Xc(t,`k`,`Search sessions, messages and Console`,Md,()=>nd.open||ca()),nd.onclick=e=>{e.target===nd&&nd.close()},nd.onclose=()=>hd(``),rd.oninput=()=>{_d=0,hd(rd.value.trim()),Ad()},rd.onkeydown=e=>{let t=la(e);if(t!==void 0){e.preventDefault(),vd(_d+t);return}e.key===`Enter`&&!e.ctrlKey&&(e.preventDefault(),gd[_d]?.open())}}var Pd=0,Fd=e=>`${e.provider}/${e.id}`,Id=null;async function Ld(){let{modelMenu:e}=await Ke(`/api/settings`,`Could not read the pinned model menu`);return e}function Rd(e){let t=I(`button`,`flex w-full min-w-0 cursor-pointer items-center gap-2 px-3 py-1.5 text-left hover:bg-neutral-100`,g(o,`h-3 w-3 text-indigo-600 ${e.checked?``:`invisible`}`),I(`span`,`truncate`,e.label));return e.hint&&t.append(I(`span`,`ml-auto flex-none text-[11.5px] text-neutral-400`,e.hint)),e.title&&(t.title=e.title),t.onclick=()=>e.onSelect(),t}function zd({models:e,current:t,thinkingLevel:n,thinkingLevels:r,onPick:i,onThinkingPick:a}){let o=n,s=I(`div`,`flex w-full min-w-0 flex-col sm:min-w-72`),c=I(`div`,`flex flex-col gap-2 border-b border-neutral-200 px-2 py-2`),u=document.createElement(`input`);if(u.type=`search`,u.placeholder=`Search models`,u.setAttribute(`aria-label`,`Search models`),u.className=`w-full rounded-md border border-neutral-300 px-2 py-1.5 text-[12.5px] focus:border-indigo-400 focus:outline-none`,c.append(u),r.length){let e=document.createElement(`details`),t=I(`span`,`ml-auto font-medium text-indigo-700`,Se(o)),n=I(`summary`,`flex min-h-11 cursor-pointer list-none items-center gap-2 rounded-xl px-3 text-sm text-neutral-700 hover:bg-neutral-100 [&::-webkit-details-marker]:hidden`,I(`span`,`font-medium`,`Reasoning effort`),t,g(l,`chev h-3 w-3 text-neutral-400`)),i=I(`fieldset`,`grid grid-cols-2 gap-1 rounded-xl bg-neutral-50 p-1`);i.append(I(`legend`,`sr-only`,`Reasoning effort`));let s=`reasoning-${++Pd}`;for(let e of r){let n=document.createElement(`input`);n.type=`radio`,n.name=s,n.value=e,n.checked=e===o,n.className=`peer sr-only`,n.onchange=()=>{n.checked&&(o=e,t.textContent=Se(o),m(u.value),a(o))},i.append(I(`label`,`relative cursor-pointer`,n,I(`span`,`flex min-h-11 items-center rounded-lg border border-transparent px-3 text-sm text-neutral-700 hover:bg-neutral-100 peer-checked:border-indigo-200 peer-checked:bg-indigo-50 peer-checked:font-semibold peer-checked:text-indigo-700 peer-focus-visible:outline-2 peer-focus-visible:outline-indigo-500`,Se(e))))}e.append(n,i),c.append(e)}let d=I(`div`,`max-h-72 overflow-y-auto py-1`),f=new Map(e.map(e=>[Fd(e),e])),p=e=>{let n=(Id??[]).map(e=>({e,model:f.get(Fd(e))})).filter(t=>!!t.model&&(!e||Fd(t.model).toLowerCase().includes(e)));n.length&&d.append(I(`div`,`px-3 pb-0.5 pt-1 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,`Pinned`),...n.map(({e,model:n})=>Rd({label:n.id,hint:Se(e.thinking),title:e.note,checked:!!t&&Fd(t)===Fd(n)&&o===e.thinking,onSelect:()=>i(n,e.thinking)})),I(`div`,`my-1 border-t border-neutral-100`))},m=n=>{d.replaceChildren();let r=n.trim().toLowerCase();p(r);let a=new Map;for(let t of e){if(r&&!Fd(t).toLowerCase().includes(r))continue;let e=a.get(t.provider);e?e.push(t):a.set(t.provider,[t])}if(!a.size){d.append(I(`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 a){let a=n.some(e=>!!t&&Fd(t)===Fd(e)),o=document.createElement(`details`);o.open=a||r.length>0;let s=I(`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`,g(l,`chev h-3 w-3`),I(`span`,`truncate`,e),I(`span`,`ml-auto flex-none normal-case text-neutral-300`,String(n.length)));o.append(s,...n.map(e=>Rd({label:e.id,checked:!!t&&Fd(t)===Fd(e),onSelect:()=>i(e)}))),d.append(o)}};return u.oninput=()=>m(u.value),m(``),Ld().then(e=>{let t=JSON.stringify(e)!==JSON.stringify(Id);Id=e,t&&m(u.value)}).catch(e=>Fc(`model menu unavailable`,e)),s.append(c,d),queueMicrotask(()=>u.focus()),s}function Bd(e,t,n,r){let i=L(t.model?`${t.model.id}${t.thinking?` · ${Se(t.thinking)}`:``}`:t.thinking?`Pi default · ${Se(t.thinking)}`:`Pi default`,`${wi} flex items-center gap-1.5 ${t.model?`text-neutral-700`:`text-neutral-400`}`);return i.title=t.model?`${t.model.provider}/${t.model.id}`:`Whatever the project and Pi pick`,i.onclick=()=>{let e=zd({models:n,current:t.model,thinkingLevel:t.thinking??`medium`,thinkingLevels:[...Mo],onPick:(e,n)=>{B(),r({model:e,thinking:n??t.thinking})},onThinkingPick:e=>{t={...t,thinking:e},r(t)}}),a=L(`Pi default`,`w-full cursor-pointer px-3 py-1.5 text-left text-[12.5px] text-neutral-500 hover:bg-neutral-100`);a.onclick=()=>{B(),r({model:null,thinking:null})};let o=I(`div`,`flex flex-col`);o.append(e,I(`div`,`border-t border-neutral-200`),a),_a(i,o)},Si(e,i)}var X;function Vd(e){X=e,el(Hd,()=>{X.currentSession()&&(B(),X.toggleFiles())},Kc)}var Hd=`i`,Ud=F(`#chat-title`),Wd=F(`#chat-menu`),Gd=F(`#session-meta`),Kd=null,qd=new Map,Jd=e=>`${e.provider}/${e.id}`,Z=null,Yd=null,Xd=null,Zd=null;function Qd(){Z=null,Yd=null,Xd=null,Zd=null,cf()}function $d(e,t,n,r){Z=e,Yd=t,Xd=n,Zd=r,rf()}function ef(e){Zd=e.completedAt,Yd&&={...Yd,tokens:e.tokens},cf()}var tf=null;function nf(e){tf=e===null?null:Qr(e),rf()}function rf(){let e=X.currentSession();e&&(tf=null),Ud.textContent=e?e.title??Qr(e.cwd):tf??X.currentId()??`no session`,Ud.classList.toggle(`cursor-pointer`,!!e),Ud.title=e?`Session info`:``,Ud.onclick=e?()=>lf(Ud,e):null,Wd.classList.toggle(`hidden`,!e),e&&(Wd.onclick=()=>gf(Wd,e)),cf(),X.syncBar()}var af=70,of=(e,t)=>Math.min(100,Math.round(e/t.contextWindow*100)),sf=e=>e.tokens===null?`?/${Ce(e.contextWindow)}`:`${Ce(e.tokens)}/${Ce(e.contextWindow)} · ${100-of(e.tokens,e)}% left`;function cf(){let e=Yd,t=e?.tokens??null,n=X.currentId(),r=X.currentSession()?.activeRuns??0,i=[];if(r>0){let e=I(`button`,`flex flex-none cursor-pointer items-center gap-1 rounded bg-sky-50 px-1.5 py-px font-medium text-sky-700 hover:bg-sky-100`,g(ie,`spinner h-3 w-3`),`${r} running`);e.title=`${Hu(r)} · show the newest`,e.onclick=()=>{Ls()||W(`error`,`no run card left in this transcript — reload the session to see it`)},i.push(e)}if(!n&&tf&&i.push(I(`span`,`flex flex-none items-center gap-1.5 text-neutral-500`,g(ie,`spinner`),`starting…`)),n){let e=(e,t)=>{let r=I(`button`,`cursor-pointer font-mono ${t}`,e);return r.title=`Change model or reasoning`,r.onclick=()=>void uf(r,n),r};Z&&i.push(e(Z.id,`min-w-0 truncate rounded bg-indigo-50 px-1.5 py-px font-medium text-indigo-700 hover:bg-indigo-100`)),Xd&&i.push(e(Xd,`flex-none text-neutral-500 hover:text-indigo-700`))}let a=0;if(e&&t!==null){a=of(t,e);let n=a>=90?`text-red-700`:a>=af?`text-amber-700`:`text-neutral-500`;i.push(I(`span`,`flex-none font-mono ${n}`,Ce(t).toLowerCase()))}let o=i.flatMap((e,t)=>t===0?[e]:[I(`span`,`flex-none text-neutral-300`,`·`),e]);Gd.replaceChildren(...o),Gd.classList.toggle(`hidden`,i.length===0),Gd.classList.toggle(`flex`,i.length>0),Gd.toggleAttribute(`data-urgent`,!n&&!!tf||r>0||a>=af)}function lf(e,t,n){let i=[[`Directory`,t.cwd],[`Session`,t.id]],a=t.id===X.currentId();if(a&&(i.push([`Model`,Z?.id??`—`]),i.push([`Reasoning`,Xd??`—`]),i.push([`Context`,Yd?sf(Yd):`—`])),i.push([`Created`,$r(t.createdAt),Xr(t.createdAt)]),a){let e=Zd;i.push(e===null?[`Last reply`,`—`]:[`Last reply`,$r(e),Xr(e)])}let o=I(`div`,`w-[min(26rem,calc(100vw-2rem))] max-sm:w-full rounded-xl bg-white px-3 py-3 font-sans text-[15px] leading-normal`),s=I(`button`,`icon-btn h-11 w-11 sm:h-8 sm:w-8`,g(ve));s.setAttribute(`aria-label`,`Close session info`),s.onclick=B;let c=I(`div`,`sticky top-0 z-10 flex items-start gap-2 bg-white pb-2`,I(`div`,`min-w-0 flex-1`,I(`div`,`text-sm font-medium text-neutral-500`,`Session info`),I(`h2`,`mt-1 [overflow-wrap:anywhere] text-lg leading-7 font-semibold text-neutral-900`,t.title??Qr(t.cwd))),s);if(n){let e=I(`button`,`icon-btn h-11 w-11 sm:h-8 sm:w-8`,g(r));e.setAttribute(`aria-label`,`Back to session actions`),e.onclick=n,c.prepend(e)}o.append(c);let l=I(`dl`,``);for(let[e,t,n]of i){let r=e===`Directory`||e===`Session`,i=I(`dd`,`min-w-0 flex items-start gap-2 text-neutral-700 ${r?`font-mono text-sm leading-6`:``}`,I(`span`,`min-w-0 flex-1 [overflow-wrap:anywhere]`,t));if(r){let n=ai(`min-h-11 min-w-11 sm:min-h-8 shrink-0 cursor-pointer rounded-lg px-2 py-1 text-[13px] font-sans text-neutral-500 hover:bg-neutral-100 focus-visible:outline-2`,()=>t);n.setAttribute(`aria-label`,`Copy ${e.toLowerCase()}`),i.append(n)}n&&i.firstElementChild?.append(I(`span`,`ml-2 inline-block font-sans text-[13px] leading-5 text-neutral-500`,n));let a=e===`Model`||e===`Created`;l.append(I(`div`,`grid gap-1 py-1.5 sm:grid-cols-[5.5rem_minmax(0,1fr)] sm:gap-3 ${a?`mt-2 border-t border-neutral-200 pt-2.5`:``}`,I(`dt`,`text-[15px] text-neutral-500`,e===`Session`?`Session ID`:e),i))}return o.append(l),_a(e,o)}async function uf(e,t,n){let r=I(`div`,`px-3 py-3 text-[15px] text-neutral-500`,`Loading models…`),i=I(`div`,`w-[min(24rem,calc(100vw-2rem))] min-w-0 max-sm:w-full`,r),a=r;n&&i.prepend(mf(e,n,`Close model picker`)),_a(e,i);let o=()=>a.isConnected&&!a.closest(`[inert]`),s=``,c=(n,r,o)=>{let c=JSON.stringify([n,r,o]);if(c===s)return;s=c;let l=zd({models:n,current:t===X.currentId()?Z:null,thinkingLevel:r,thinkingLevels:o,onPick:(e,n)=>{B(),df(t,e,n)},onThinkingPick:e=>void pf(t,e)});a.replaceWith(l),a=l,_a(e,i)},l=t===X.currentId()&&Z?qd.get(Jd(Z)):void 0;Kd&&l&&Xd&&c(Kd,Xd,l);try{let[e,n]=await Promise.all([Ke(`/api/sessions/${t}/models`,`Could not load models`),Ke(`/api/sessions/${t}/thinking`,`Could not read the reasoning level`)]);if(Kd=e,t===X.currentId()&&Z&&qd.set(Jd(Z),n.levels),!o())return;c(e,n.level,n.levels)}catch(e){s?W(`error`,`model options are stale: ${String(e)}`):o()?(r.textContent=`Could not load models: ${String(e)}`,r.setAttribute(`role`,`alert`)):W(`error`,`model options failed: ${String(e)}`)}}async function df(e,t,n){await ff(e,t)&&n&&await pf(e,n)}async function ff(e,t){let n=Z;e===X.currentId()&&(Z=t,rf());let r=await b(`/api/sessions/${e}/model`,t);if(!r.ok){let{error:t}=await r.json().catch(()=>({}));return e===X.currentId()&&(Z=n,rf()),W(`error`,`model change failed: ${t??r.status}`),!1}let{model:i}=await r.json();return e===X.currentId()&&i&&(Z=i,rf()),!0}async function pf(e,t){let n=await b(`/api/sessions/${e}/thinking`,{level:t});if(!n.ok){W(`error`,`reasoning change failed: ${n.status}`);return}let{level:r}=await n.json();e===X.currentId()&&(Xd=r,cf())}function mf(e,t,n){let i=I(`button`,`icon-btn h-11 w-11`,g(r));i.setAttribute(`aria-label`,`Back to session actions`),i.onclick=()=>gf(e,t);let a=I(`button`,`icon-btn h-11 w-11`,g(ve));a.setAttribute(`aria-label`,n),a.onclick=B;let o=I(`span`,`min-w-0 flex-1 truncate text-sm font-medium`,t.title??Qr(t.cwd));return o.title=o.textContent??``,I(`div`,`flex items-center gap-2 border-b border-neutral-200 pb-2 mb-2`,i,o,a)}async function hf(e,t){let n=I(`p`,`px-3 py-2 text-[15px] text-neutral-500`,`Loading chats…`),r=I(`div`,`w-[min(24rem,calc(100vw-2rem))] min-w-0 max-sm:w-full`,mf(e,t,`Close chat picker`),I(`div`,`px-3 pb-1 text-sm font-medium text-neutral-500`,`Continue in a direct message`),I(`p`,`px-3 pb-2 text-[13px] text-neutral-500`,`DMs the bot has seen. A DM appears here after its first message to the bot.`),n);_a(e,r);let i=await S(`/api/handoff/targets`,`Could not list chats`);if(!r.isConnected)return;if(!i.ok){n.textContent=i.error,n.setAttribute(`role`,`alert`);return}if(!i.value.targets.length){n.textContent=`No DMs yet — message the bot once in Lark or Slack, then come back.`;return}let a=I(`p`,`hidden px-3 pt-1 text-[13px] text-red-600`);a.setAttribute(`role`,`alert`);let o=I(`div`,``);o.dataset.list=``;for(let e of i.value.targets){let n=I(`button`,`flex w-full min-h-10 cursor-pointer items-center gap-2 rounded-xl px-3 py-2 text-left transition-colors hover:bg-indigo-50 hover:text-indigo-700 active:bg-indigo-100`,I(`span`,`min-w-0 truncate`,`${e.platform[0].toUpperCase()}${e.platform.slice(1)} · ${e.name||e.chatId}`));n.onclick=async()=>{let n=await b(`/api/handoff`,{sessionId:t.id,platform:e.platform,chatId:e.chatId});if(n.ok)return B();a.textContent=(await n.json().catch(()=>({}))).error??`handoff failed: ${String(n.status)}`,a.classList.remove(`hidden`)},o.append(n)}n.replaceWith(o,a),o.querySelector(`button`)?.focus({preventScroll:!0})}function gf(e,t){let n=t.id===X.currentId();ya(e,[{label:`Rename…`,onSelect:()=>{B(),Gu(t)}},{label:`Session info`,onSelect:()=>lf(e,t,()=>gf(e,t))},{label:`New session here`,separatorBefore:!0,hint:Zr(t.cwd),onSelect:()=>{B(),X.createSession(t.cwd)}},{label:`Browse files`,hint:n?Gc(Hd):``,onSelect:()=>{B(),X.openFiles(n?void 0:t.cwd)}},{label:`Continue in Lark/Slack…`,...t.channel&&t.channel!==`web`?{hint:`answers in ${t.channel}`,disabled:!0}:{},onSelect:()=>void hf(e,t)},{label:`Model & reasoning…`,separatorBefore:!0,hint:n?Z?.id??`…`:``,onSelect:()=>void uf(e,t.id,t)}],t.title??Qr(t.cwd))}var _f=`pier.theme`,vf=[`system`,`light`,`dark`],yf=window.matchMedia(`(prefers-color-scheme: dark)`),bf={system:ce,light:ge,dark:h},xf=()=>{let e=null;try{e=localStorage.getItem(_f)}catch{return`system`}return e===`light`||e===`dark`?e:`system`},Sf=()=>{let e=xf();return e===`system`?yf.matches?`dark`:`light`:e};function Cf(){let e=Sf();document.documentElement.dataset.theme=e;let t=getComputedStyle(document.documentElement).getPropertyValue(`--workbench-canvas`).trim();F(`meta[name="theme-color"]`).setAttribute(`content`,t),window.dispatchEvent(new Event(`pier:theme`))}function wf(){let e=F(`#theme-toggle`),t=()=>{let t=xf();e.title=`Theme: ${t}${t===`system`?` (${Sf()})`:``}`,e.replaceChildren(g(bf[t])),e.setAttribute(`aria-label`,e.title),Cf()};e.onclick=()=>{let e=vf[(vf.indexOf(xf())+1)%vf.length];try{e===`system`?localStorage.removeItem(_f):localStorage.setItem(_f,e)}catch{}t()},yf.addEventListener(`change`,t),t()}var Tf=`https://github.com/timqi/pier`,Ef=[`text-neutral-400`,`hover:text-neutral-700`],Df=[`rounded-full`,`bg-emerald-50`,`px-1.5`,`text-emerald-700`,`ring-1`,`ring-inset`,`ring-emerald-600/20`,`hover:bg-emerald-100`],Of=18e5,kf=null,Af=F(`#version`);function jf(e){let t=kf?.available===!0&&kf.latest!==null;Af.textContent=`v${e}`,Af.title=t?`Pier ${kf?.latest} is out`:``,Af.classList.remove(...t?Ef:Df),Af.classList.add(...t?Df:Ef)}var Mf=(e,t=`px-3 py-1 text-[12px] leading-snug text-neutral-500`)=>I(`p`,t,e);function Nf(){let e=I(`div`,`flex w-72 flex-col gap-1 py-1`);if(!kf)return e.append(Mf(`Checking the registry…`)),e;let{current:t,latest:n,available:r,canApply:i,problem:a}=kf,o=I(`span`,``,``),s=(e,t)=>R(o,e?`failed`:`idle`,t),c=I(`div`,`flex items-center gap-2 px-3 py-1.5`);if(e.append(Mf(r?`Pier ${n} is out`:`Pier ${t}`,`px-3 py-1 text-[12.5px] font-medium text-neutral-700`),Mf(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.`)),a&&e.append(Mf(a,`mx-3 my-1 rounded-md bg-red-50 px-2 py-1.5 text-[11.5px] leading-snug text-red-700`)),r&&i&&!a){let e=di(`Update now`,!0);e.onclick=()=>void(async()=>{e.disabled=!0,s(!1,`starting the updater…`);let t=await b(`/api/update`,{});if(!t.ok)return e.disabled=!1,s(!0,await x(t,`Could not update`));let{draining:n}=await t.json();s(!1,n?`Waiting for running work to finish — Pier then installs and restarts.`:`Installing — Pier restarts once it is on disk, and this page reconnects on its own.`)})(),c.append(e)}c.append(Object.assign(I(`a`,`btn text-[12.5px] no-underline`,`Source`),{href:r?`${Tf}/releases`:Tf,target:`_blank`,rel:`noreferrer`,title:`Pier is free software (AGPL-3.0)`})),e.append(c,I(`div`,`px-3`,o)),r&&!i&&!a&&e.append(Mf(`No service manager owns this Pier, so it cannot restart itself — update it with: pier update`));let l=ki(`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.`,kf.autoUpdate,e=>void(async()=>{kf&&(kf.autoUpdate=e);let t=await b(`/api/settings`,{autoUpdate:e},`PUT`);t.ok||(kf&&(kf.autoUpdate=!e),u&&(u.checked=!e),s(!0,await x(t,`Could not save`)))})()),u=l.querySelector(`input`);return u&&(u.disabled=!i),e.append(I(`div`,`mt-1 border-t border-neutral-200 px-3 pb-1 pt-2`,l)),e}async function Pf(e){let t=await S(`/api/update`,`Update check failed`);t.ok&&jf((kf=t.value).current||e)}function Ff(e){jf(e),Af.onclick=e=>{e.preventDefault(),_a(Af,Nf())};let t=()=>void Pf(e);t(),setInterval(t,Of)}var Q,If=F(`#chat-header`),Lf=F(`#chat-title`),Rf=[If,U,F(`#composer`)],zf=()=>Kf===null,Bf,Vf,Hf,Uf=new Map,Wf=new Map,Gf=new Map,Kf=null,qf=0,Jf=[`files`],Yf=new Map,Xf={tasks:`Tasks`,runs:`Runs`,activity:`Activity`,boards:`Boards`,settings:`Settings`,files:`Files`},Zf=[`tasks`,`runs`,`activity`],Qf=`Automation`,$f=F(`#automation-view`),ep=F(`#automation-tabs`),tp=e=>Zf.includes(e)?`tasks`:e;function np(e,t){let n=e!==null&&Zf.includes(e);if($f.classList.toggle(`hidden`,!n),$f.classList.toggle(`flex`,n),!n)return;let r=[];if(e===`tasks`&&!t){let e=di(`New task`,!0);e.classList.add(`ml-auto`),e.disabled=!Bf,e.onclick=()=>Bf?.create(),r.push(e)}ep.replaceChildren(fi(Qf),...Zf.map(t=>gi(Xf[t],t===e,()=>sp(t))),...r)}var rp=e=>Bf?.refresh(e),ip=()=>Vf?.refresh(),ap=()=>Hf?.refresh();function op(){Kf?gu(Zf.includes(Kf)?Qf:Xf[Kf],!1):gu(Lf.textContent??``,Q.currentSession()!==void 0)}function sp(e,t,n){if(Jf.includes(e)){let t=yp();t&&(t.kind!==`console`||t.name!==e)&&Yf.set(e,t)}xp({kind:`console`,name:e,arg:t,query:n}),hu(),Kf=e;for(let e of Rf)e.classList.add(`hidden`);wl();for(let[t,n]of Uf)t!==e&&n.hide();for(let[t,n]of Gf)n.classList.toggle(`bg-indigo-50`,t===tp(e));np(e,t),op(),cp(e,t,n,++qf)}async function cp(e,t,n,r){let i=Uf.get(e);if(!i){let t=Wf.get(e);if(!t){let n=F(`#${e}-view`);t=wp[e](n).catch(t=>(console.warn(`${e} view failed to load`,t),ti(n,()=>n.replaceChildren(I(`p`,`p-4 text-[13px] text-red-600`,`Could not load ${Xf[e]} — reload the page.`))))),Wf.set(e,t)}i=await t,Uf.set(e,i),Wf.delete(e)}Kf===e&&r===qf&&(i.show(t,n),e===`tasks`&&np(e,t))}var lp=e=>sp(`tasks`,e),up=(e={},t)=>sp(`runs`,t,new URLSearchParams(e).toString()),dp=e=>up({},e),fp=(e,t)=>sp(`files`,e,t?new URLSearchParams({select:t}).toString():void 0),pp=(e,t)=>{Kf===e?hp(e):sp(e,t)},mp=e=>pp(`files`,e);function hp(e){let t=Q.currentId(),n=Yf.get(e)??(t?{kind:`session`,id:t}:null);Yf.delete(e),n?xp(n):(history.replaceState(null,``,`#/`),gp())}function gp(){if(Kf){Kf=null;for(let e of Uf.values())e.hide();for(let e of Gf.values())e.classList.remove(`bg-indigo-50`);np(null);for(let e of Rf)e.classList.remove(`hidden`);wl(),op(),Q.maybeAckRead()}}var _p=e=>e.kind===`session`?`#/session/${encodeURIComponent(e.id)}`:`#/${e.name}${e.arg?`/${encodeURIComponent(e.arg)}`:``}${e.query?`?${e.query}`:``}`,vp={config:`files`,channels:`channels`,providers:`models`};function yp(){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 vp[n]?{kind:`console`,name:`settings`,arg:vp[n]}:Object.hasOwn(Xf,n)?{kind:`console`,name:n,arg:a,query:i}:n===`session`&&a?{kind:`session`,id:a}:null}var bp=!1;function xp(e,t=!1){if(bp)return;let n=_p(e);location.hash!==n&&(t?history.replaceState(null,``,n):location.hash=n)}var Sp=e=>xp({kind:`session`,id:e});function Cp(){let e=yp(),t=Q.sessions(),n=Q.currentId(),r=e?.kind===`session`?e.id:null,{top:i,rest:a}=Iu(t),o=r??n??(i[0]??a[0])?.id??null;bp=!0;try{o&&o!==n&&Q.select(o),e?.kind===`console`?sp(e.name,e.arg,e.query):gp(),o||rf()}finally{bp=!1}e?.kind!==`console`&&o&&xp({kind:`session`,id:o},!0)}var wp={tasks:async e=>Bf=(await Gi(async()=>{let{createTasksView:e}=await import(`./tasks-8l1M8EJU.js`);return{createTasksView:e}},__vite__mapDeps([0,1]))).createTasksView(e,()=>Q.sessions().map(({id:e,cwd:t,title:n})=>({id:e,cwd:t,title:n})),Q.loadSessions,Q.select,()=>Q.currentId(),up,lp),runs:async e=>Vf=(await Gi(async()=>{let{createRunsView:e}=await import(`./runs-DtvDXSfo.js`);return{createRunsView:e}},__vite__mapDeps([2,1]))).createRunsView(e,Q.select,up,lp),activity:async e=>Hf=(await Gi(async()=>{let{createActivityView:e}=await import(`./activity-dxSOEHmf.js`);return{createActivityView:e}},[])).createActivityView(e,Q.select,dp),boards:async e=>(await Gi(async()=>{let{createBoardsView:e}=await import(`./boards-BRwn5UZi.js`);return{createBoardsView:e}},[])).createBoardsView(e,Q.select),files:async e=>(await Gi(async()=>{let{createExplorerView:e}=await import(`./explorer-CCJQ22Dp.js`);return{createExplorerView:e}},[])).createExplorerView(e,()=>Q.currentSession(),e=>sp(`files`,e),()=>hp(`files`)),settings:async e=>(await Gi(async()=>{let{createSettingsView:e}=await import(`./settings-CJbHCEZo.js`);return{createSettingsView:e}},[])).createSettingsView(e,()=>He(Q.sessions()),e=>sp(`settings`,e),fp)};function Tp(e){Q=e;for(let e of[`tasks`,`boards`,`settings`]){let t=F(`#open-${e}`);Gf.set(e,t),t.onclick=()=>sp(e)}let t=F(`#console-section`);t.open=localStorage.getItem(`pier.consoleCollapsed`)!==`1`,t.ontoggle=()=>localStorage.setItem(`pier.consoleCollapsed`,t.open?`0`:`1`),window.onhashchange=Cp}var Ep=[],Dp=null,Op=0,kp=0,Ap=!1,$=null,jp=`idle`,Mp=null,Np=0,Pp=!1,Fp=!1;async function Ip(e){let t=++Op;++kp,Ap=!1,gp(),hu(),$=null,Mp?.close(),Mp=null,Ec(),Tl([]),Qd(),nf(e),Dc(!0),Fp=!0,Cl();let n=await b(`/api/sessions`,{cwd:e});if(t!==Op)return;if(Fp=!1,!n.ok){Dc(!1),nf(null),Cl(),W(`error`,`session create failed: ${n.status}`);return}let{id:r}=await n.json();t===Op&&(Ep.unshift({id:r,cwd:e,createdAt:Date.now(),state:`idle`,unread:!1,channel:`web`,activeRuns:0}),await qp(r),$===r&&yl())}function Lp(e){Ep=e.map(e=>({...e,title:Be(e.title)})),Ep.sort((e,t)=>t.createdAt-e.createdAt),Qu(),rf(),zp()}var Rp=Ue(async()=>{Lp(await Ke(`/api/sessions`,`Could not load sessions`))});function zp(){if(document.hidden||!document.hasFocus()||!zf())return;let e=Ep.find(e=>e.id===$);e?.unread&&(e.unread=!1,Qu(),fetch(`/api/sessions/${e.id}/read`,{method:`POST`}))}function Bp(){return Ep.find(e=>e.id===$)??(Dp&&Dp.id===$?Dp:void 0)}async function Vp(e){let t=await S(`/api/sessions/${e}`,`failed to load session`);$!==e||!t.ok||(Dp={...t.value,title:Be(t.value.title)},rf())}function Hp(e,t){let n=Ep.find(t=>t.id===e);!n||n.title||!t.trim()||(n.title=t.trim().slice(0,80),Qu(),rf())}function Up(e){jp=e;let t=Ep.find(e=>e.id===$);t&&(t.state=e),Qu(),rf(),Cl(),e===`idle`&&Rp()}function Wp(e){if(!(e.sessionId!==$||e.seq<=Np))switch(Np=e.seq,e.type){case`turn-start`:Pp=!0;break;case`system-input`:Sc(),Js(e.text,e.origin);break;case`task-status`:Ko(e.run);break;case`user-message`:{let t=Le(e.text).text;if(Hp(e.sessionId,t),bl(t))break;Sc(),W(`user`,e.text,!1,e.ts),Ps();break}case`text-start`:Sc();break;case`text-delta`:xc(e.text);break;case`thinking-delta`:Sc(),bs(e.ts,e.text);break;case`tool-start`:Sc(),vs(e.ts,e.toolCallId,e.toolName,e.args);break;case`tool-end`:ys(e.toolCallId,e.isError,e.output);break;case`turn-end`:Pp=!1,wc(e.text,e.meta),e.meta&&ef(e.meta);break;case`queue-state`:El(e.steering,e.followUp);break;case`queue-recovery`:Tl(e.batches,e.uncertain);break;case`context-compacted`:Sc(),W(`system`,`Context compacted — ${Ce(e.before)} → ${Ce(e.after)}`,!1,e.ts),Ps();break;case`error`:gs(),W(`error`,e.message);break;case`state`:e.state===`idle`&&Pp&&(Pp=!1,Tc()),e.state===`idle`&&El([],[]),Up(e.state)}}function Gp(){let e=new EventSource(`/api/events`);e.onopen=()=>{Rp(),rp(),ip(),ap()},e.onerror=()=>Bc(e,`Workspace`),e.onmessage=e=>{let t=JSON.parse(e.data);if(t.type===`sessions-changed`){Rp();return}if(t.type===`tasks-changed`||t.type===`task-run-changed`||t.type===`task-message-changed`||t.type===`task-group-changed`){rp(t.type===`task-run-changed`?t.taskId:void 0),ip(),ap(),t.type===`task-run-changed`&&Rp();return}if(ap(),t.sessionId===$)return;let n=Ep.find(e=>e.id===t.sessionId);n&&(n.state=t.state,Qu())}}function Kp(e,t,n){Mp?.close();let r=new EventSource(`/api/sessions/${e}/events?after=${t}`),i=()=>Mp===r&&$===e&&n===kp;r.onmessage=e=>{i()&&Wp(JSON.parse(e.data))},r.addEventListener(`reset`,()=>{i()&&Jp(e)}),r.onerror=()=>{i()&&Bc(r,`Session`)},Mp=r}async function qp(e){gp(),hu(),Sp(e),!(e===$&&(Mp||Ap))&&(++Op,++kp,Fp=!1,Ll(),$=e,Dp=null,Ep.some(t=>t.id===e)||Vp(e),jp=Ep.find(t=>t.id===e)?.state??`idle`,Rl(e),Qu(),rf(),zp(),await Jp(e))}async function Jp(e){if($!==e)return;let t=++kp;Mp?.close(),Mp=null,Ap=!0,Ec(),El([],[]),Tl([]),Qd(),Pp=!1,Sl(),Np=0,Dc(!0);let n=await S(`/api/sessions/${e}/history`,`failed to load session`);if($!==e||t!==kp)return;if(Ap=!1,!n.ok){Dc(!1),W(`error`,n.error);return}let r=n.value;Oc(r.turns,r.state,r.backgroundRuns),Np=r.lastSeq,Pp=r.state===`streaming`,Up(r.state),El(r.queue.steering,r.queue.followUp),Tl(r.queueRecovery,r.queueUncertain);let i=r.turns.reduce((e,t)=>t.meta?.completedAt??e,null);$d(r.model,r.context,r.thinkingLevel,i),Kp(e,`${r.epoch}:${r.lastSeq}`,t)}Ic(),ye(),zc(),wf();var Yp=async e=>{$===e&&await Jp(e)};Es({sessionId:()=>$,sessionCwd:()=>Bp()?.cwd??null,sessionChannel:()=>Bp()?.channel??null,sessionState:()=>jp,select:e=>void qp(e),showRun:dp,send:(e,t)=>void Vl(e,t),ownTurn:e=>{xl(e),Up(`streaming`)},reload:Yp}),Wl({sessionId:()=>$,starting:()=>Fp,sessionState:()=>jp,chatVisible:zf,setState:Up,reload:Yp}),Mu({sessionMenu:e=>{let t=Bp();t&&gf(e,t)},sessionInfo:e=>{let t=Bp();t&&lf(e,t)}}),ed({sessions:()=>Ep,currentId:()=>$,select:e=>void qp(e),sessionMenu:gf,createSession:Ip,onTitleChanged:rf}),Nd({sessions:()=>Ep,loadSessions:Rp,currentId:()=>$,select:qp,createSession:Ip,openConsole:sp}),Vd({currentId:()=>$,currentSession:Bp,createSession:e=>void Ip(e),syncBar:op,openFiles:fp,toggleFiles:mp}),Tp({sessions:()=>Ep,loadSessions:Rp,currentId:()=>$,currentSession:Bp,select:e=>void qp(e),maybeAckRead:zp}),Ff(`0.1.11`),au(),document.addEventListener(`gesturestart`,e=>e.preventDefault()),document.addEventListener(`visibilitychange`,zp),window.addEventListener(`focus`,zp),Gp(),Rp().then(Cp);export{x as $,Pi as A,ki as B,ji as C,Mi as D,xi as E,Di as F,ti as G,Fi as H,R as I,ei as J,ai as K,hi as L,fi as M,gi as N,Ni as O,mi as P,Ue as Q,Ti as R,Ai as S,di as T,Xr as U,pi as V,Zr as W,Yr as X,I as Y,Qr as Z,Ci as _,$c as a,Be as at,_i as b,Aa as c,ve as ct,ya as d,l as dt,S as et,_a as f,s as ft,bi as g,Zi as h,uu as i,b as it,Ei as j,Si as k,Da as l,de as lt,ea as m,a as mt,Bd as n,Ge as nt,Mo as o,Se as ot,ta as p,o as pt,ui as q,zd as r,qe as rt,No as s,g as st,lf as t,Ke as tt,B as u,ie as ut,wi as v,L as w,vi as x,yi as y,Oi as z};
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,G as t,O as n,Q as r,T as i,Y as a,_ as o,dt as s,et as c,rt as l,st as u}from"./index-
|
|
1
|
+
import{F as e,G as t,O as n,Q as r,T as i,Y as a,_ as o,dt as s,et as c,rt as l,st as u}from"./index-CzV2cZEH.js";import{c as d,i as f,n as p,o as m,s as h}from"./task-runs-DcORJXHU.js";function g(g,_,v,y){let b=new URLSearchParams,x=[],S=``,C=a(`div`,`automation-list min-h-0 flex-1 overflow-auto`),w,T={selectedId:null,rawOpen:!1,scrollTop:0,drawn:``},E=(e,t)=>v(Object.fromEntries(e),t),D=e=>{g.querySelector(`[role=alert]`)?.remove();let t=a(`p`,`p-4 text-[13px] text-red-600`,e);t.setAttribute(`role`,`alert`),g.append(t)},O={openSession:_,openTask:y,openRun:e=>E(b,e),mutate:async e=>{let t=await l(e,`POST`,`Run update failed`);t?D(t):await k()}},k=r(async()=>{let e=T.selectedId;if(e)return f(C,e,()=>E(b),O,T);let t=b.toString(),n=await c(`/api/task-runs?${t}`,`Could not load runs`);if(t!==b.toString()||T.selectedId)return;if(!n.ok)return D(n.error);g.querySelector(`[role=alert]`)?.remove();let r=JSON.stringify(n.value);S!==t+r&&(S=t+r,P(n.value))});function A(e,t){let n=new URLSearchParams(b);t?n.set(e,t):n.delete(e),n.delete(`cursor`),E(n)}function j(){if(S=``,C=a(`div`,`automation-list min-h-0 flex-1 overflow-auto`),w=void 0,T.selectedId){g.replaceChildren(C);return}g.replaceChildren(N(),C)}function M(){let e=x.map(e=>[e.name+(e.archived?` (archived)`:``),e.id]),t=b.get(`taskId`);return t&&!x.some(e=>e.id===t)&&e.push([t,t]),[[`All tasks`,``],...e]}function N(){let t=a(`div`,`automation-filters run-filters`),n=(n,r,i)=>{let o=e(i,b.get(r)??``);return o.dataset.active=String(!!b.get(r)),o.setAttribute(`aria-label`,n),o.onchange=()=>A(r,o.value),t.append(a(`label`,`filter-field ${r===`taskId`?`filter-wide`:``}`,a(`span`,``,n),o)),o};n(`State`,`state`,[[`All states`,``],...[`queued`,`running`,`succeeded`,`failed`,`cancelled`,`interrupted`,`skipped`].map(e=>[e,e])]),n(`Source`,`source`,[[`All sources`,``],...[`manual`,`agent`,`cron`,`watch`,`task`].map(e=>[e,e])]),w=n(`Task`,`taskId`,M());let r=a(`details`,`filter-dates`),c=Number(b.has(`since`))+Number(b.has(`until`));r.open=c>0,r.append(a(`summary`,`flex cursor-pointer items-center gap-1.5 py-1 text-[12px] text-neutral-600`,u(s,`chev h-3 w-3`),c?`Date range (${c})`:`Date range`));let l=a(`div`,`filter-date-fields`);for(let[e,t]of[[`From`,`since`],[`Through`,`until`]]){let n=a(`input`,o);n.type=`datetime-local`,n.setAttribute(`aria-label`,e);let r=b.get(t);if(r){let e=new Date(Number(r));Number.isFinite(e.getTime())&&(n.value=new Date(e.getTime()-e.getTimezoneOffset()*6e4).toISOString().slice(0,16))}n.dataset.active=String(!!n.value),n.onchange=()=>A(t,n.value?String(new Date(n.value).getTime()):``),l.append(a(`label`,`filter-field`,a(`span`,``,e),n))}r.append(l);let d=a(`input`,`h-4 w-4 flex-none`);d.type=`checkbox`,d.checked=b.get(`showUnmatched`)===`true`,d.onchange=()=>A(`showUnmatched`,d.checked?`true`:``);let f=a(`label`,`flex min-h-10 cursor-pointer items-center gap-2 text-[11.5px] text-neutral-500`,d,`Show unmatched probes`),p=[...b.keys()].filter(e=>e!==`cursor`).length,m=i(p?`Reset filters (${p})`:`Reset filters`);return m.classList.add(`filter-action`),m.disabled=!p,m.onclick=()=>v({}),t.append(r,a(`div`,`filter-footer`,f,m)),t}function P(e){let t=a(`div`,`divide-y divide-neutral-100`);for(let n of e.runs){let e=a(`div`,`px-4 py-3 text-[12px] transition-colors hover:bg-neutral-50`),r=a(`button`,`grid w-full cursor-pointer grid-cols-[minmax(0,1fr)_auto] items-center gap-x-4 gap-y-1 text-left md:grid-cols-[minmax(0,1fr)_12rem_5rem]`);r.setAttribute(`type`,`button`),r.onclick=()=>E(b,n.id),r.append(a(`span`,`flex min-w-0 items-center gap-2`,h(n),a(`span`,`min-w-0 truncate font-medium text-neutral-800`,n.context.definition.name)),a(`span`,`text-right font-mono text-[11.5px] text-neutral-400 md:order-2`,d(n)),a(`span`,`col-span-2 text-neutral-500 md:order-1 md:col-span-1`,p(n.queuedAt)),a(`span`,`col-span-2 break-all font-mono text-[11px] text-neutral-400 md:order-3 md:col-span-3`,`${n.id} · ${n.triggerSource}`)),e.append(r);let i=m(n);i&&e.append(a(`p`,`mt-1.5 inline-block break-words rounded-md bg-amber-50 px-2 py-0.5 text-[11.5px] text-amber-700 ring-1 ring-amber-200`,i));let o=a(`div`,`mt-1.5 flex flex-wrap gap-1.5 text-[11px] text-neutral-500`),s=`max-w-full break-all rounded-md bg-neutral-100 px-1.5 py-0.5 text-left`,c=(e,t)=>{let n=a(`button`,`${s} cursor-pointer transition-colors hover:bg-neutral-200 hover:text-neutral-800`,e);n.setAttribute(`type`,`button`),n.onclick=t,o.append(n)};if(n.parentRunId&&c(`Parent ${n.parentRunId}`,()=>E(b,n.parentRunId)),n.resumedFromRunId&&c(`Resumed from ${n.resumedFromRunId}`,()=>E(b,n.resumedFromRunId)),n.result?.type===`task`){let e=n.result.runId;c(`Child result ${e}`,()=>E(b,e))}n.groupId&&o.append(a(`span`,s,`Group ${n.groupId}`)),o.childElementCount&&e.append(o),t.append(e)}e.runs.length||t.append(a(`div`,`p-4`,n(`No matching runs.`)));let r=a(`div`,`flex items-center gap-3 border-t border-neutral-200 p-4`);if(b.has(`cursor`)){let e=i(`Newest`);e.onclick=()=>A(`cursor`,``),r.append(e)}if(e.nextCursor){let t=i(`Older runs`);t.onclick=()=>{let t=new URLSearchParams(b);t.set(`cursor`,JSON.stringify(e.nextCursor)),E(t)},r.append(t)}let o=C.scrollTop;C.replaceChildren(t,r),C.scrollTop=o}async function F(){let e=await c(`/api/tasks?kind=task`,`Could not load task filters`);if(!e.ok)return D(e.error);JSON.stringify(x)!==JSON.stringify(e.value)&&(x=e.value,!T.selectedId&&w?.isConnected&&(w.replaceChildren(...M().map(([e,t])=>new Option(e,t))),w.value=b.get(`taskId`)??``))}let I=t(g,(e,t)=>{b=new URLSearchParams(t),T.selectedId!==(e||null)&&(T.rawOpen=!1,T.scrollTop=0),T.selectedId=e||null,j(),k(),e||F()});return Object.assign(I,{refresh(){I.visible&&k()}})}export{g as createRunsView};
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,W as b,Y as x,_ as S,b as C,c as w,d as T,dt as E,et as D,f as O,ft as k,g as A,h as j,i as M,it as N,j as P,k as F,lt as ee,m as I,n as L,nt as R,o as z,ot as B,p as V,pt as H,r as te,rt as U,st as W,u as ne,ut as G,v as K,w as q,x as J,y as re,z as ie}from"./index-Bfy7U1wv.js";var ae=[[`path`,{d:`m18 15-6-6-6 6`}]],oe=[[`path`,{d:`M15 3h6v6`}],[`path`,{d:`M10 14 21 3`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`}]],se=[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`}],[`path`,{d:`M12 9v4`}],[`path`,{d:`M12 17h.01`}]],Y={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}},ce=()=>`https://api.slack.com/apps?new_app=1&manifest_json=${encodeURIComponent(JSON.stringify(Y))}`;function le(){let e=v(`Create Slack app`,!0);e.append(W(oe)),e.classList.add(`inline-flex`,`items-center`,`gap-1.5`),e.classList.add(`mt-1`,`w-fit`),e.onclick=()=>window.open(ce(),`_blank`,`noreferrer`);let n=u(`btn w-fit text-[12.5px]`,()=>JSON.stringify(Y,null,2));return t(`Creating a Slack app`,[c(`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.",c(`Prefer to paste it yourself? Create the app from a manifest and use this:`,n)])}var X=()=>t(`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>`. `@bot s <question>`, as the first message of a thread, drafts a session — directory, model, reasoning — and Start runs the question in it. Slack's client swallows an unregistered `/command` before it ever reaches an app."]),ue=()=>t(`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.`]),de=()=>t(`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>`. `/s <question>` or `s <question>`, outside any topic, drafts a session — directory, model, reasoning — and Start runs the question in it. A bare @mention with nothing else also opens the settings panel."]),fe=[[`slack`,`Slack`],[`lark`,`Lark`]],Z={dm:`bg-sky-50 text-sky-700 ring-sky-200`,group:`bg-neutral-100 text-neutral-600 ring-neutral-200`},pe=`pier.channelsPlatform`;function me(e){let t=localStorage.getItem(pe),i=fe.some(([e])=>e===t)?t:`slack`,o=null,c=[],l=x(`div`,`ml-auto flex items-center gap-1.5 text-[11.5px]`),u=x(`div`,`pagehead pagehead-hug sticky top-[-8px] z-30`,l),d=x(`div`,`px-4 pb-5 pt-4`);e.append(x(`div`,`min-h-0 flex-1 overflow-y-auto`,u,d));function f(){u.replaceChildren(h(fe.map(([e,t])=>[t,e]),i,e=>{p&&O(),i=e,localStorage.setItem(pe,e),k()}),l)}let p,y=!1,b=null;function S(e){if(l.replaceChildren(),e!==`clean`){if(l.className=`ml-auto flex items-center gap-1.5 text-[11.5px] ${_[e]}`,e===`saving`)l.append(W(G,`spinner`),x(`span`,``,`Saving…`));else if(e===`saved`)l.append(W(H),x(`span`,``,`Saved`)),setTimeout(()=>{l.textContent?.includes(`Saved`)&&S(`clean`)},2e3);else{let e=q(`Retry`,`cursor-pointer underline`);e.onclick=O,l.append(W(se),x(`span`,``,`Save failed`),e)}}}function C(){S(`saving`),clearTimeout(p),p=setTimeout(O,500)}let T=e=>t=>{e(t),C()};async function E(e){y=!0,S(`saving`);try{S((await N(`/api/channels/${e.platform}`,e.config,`PUT`)).ok?`saved`:`failed`)}catch{S(`failed`)}finally{y=!1;let e=b;b=null,e&&E(e)}}function O(){if(clearTimeout(p),p=void 0,!o)return;let e={platform:i,config:o};y?b=e:E(e)}async function k(){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/${i}`,`Failed to load`);if(!e.ok){o=null,f(),d.replaceChildren(m(e.error));return}o=e.value,S(`clean`),I()}function A(e){let t=i===`lark`,r=g(e.token,t?`cli_…`:`xoxb-…`,T(t=>e.token=t),!0),o=g(e.appToken,t?``:`xapp-…`,T(t=>e.appToken=t),!0),s=w(e.cwd,`(pier process cwd)`,T(t=>e.cwd=t));return a(`Connection`,t?`Pier connects over Feishu's WebSocket long connection; no public URL or webhook needed.`:`Pier connects over Socket Mode; no public URL or webhook needed.`,n(`Enabled`,`Start the adapter when Pier boots.`,e.enabled,T(t=>{e.enabled=t,f()})),F(t?`App ID`:`Bot token`,r,{hint:`Stored locally, shown masked once saved.`,help:t?ue():le()}),t?F(`App Secret`,o,{hint:`From Credentials & Basic Info, beside the App ID.`}):F(`App-level token`,o,{hint:`Opens the Socket Mode connection. Needs connections:write.`}),F(`Default working directory`,s.el,{hint:`Where sessions this channel opens start.`}),x(`span`,`flex items-center gap-1.5 text-[13px] text-neutral-400`,x(`span`,``,t?`Every topic is its own session.`:`Every thread is its own session.`),t?de():X()))}function j(e){return a(`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.`,n(`Require mention in groups`,`Ignore group messages that do not @mention or reply to the bot.`,e.requireMention,T(t=>e.requireMention=t)),n(`Require bound user`,`Only users bound with a code below can drive the agent.`,e.requireBind,T(t=>e.requireBind=t)),L(`Model & reasoning`,e,c,T(t=>{e.model=t.model,e.thinking=t.thinking,I()})))}function M(e){let t=x(`span`,`font-mono text-[15px] font-semibold tracking-widest`),n=x(`div`,`hidden items-center gap-2 rounded-lg bg-indigo-50 px-3 py-2 text-[12.5px] text-indigo-800`,t,x(`span`,`text-[11.5px] text-indigo-500`,`DM the bot /bind <code> · expires in 10 min`)),r=v(`Generate bind code`);r.onclick=async()=>{let e=await fetch(`/api/channels/${i}/bind-code`,{method:`POST`});if(!e.ok)return;let{code:r}=await e.json();t.textContent=r,n.classList.replace(`hidden`,`flex`)};let o=x(`div`,`flex flex-col`);e.users.length||o.append(m(`No bound users yet.`));for(let t of e.users){let e=q(`Remove`,`cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-red-600 group-hover:opacity-100 pointer-coarse:opacity-100`);e.onclick=async()=>{await fetch(`/api/channels/${i}/users/${encodeURIComponent(t.id)}`,{method:`DELETE`}),await k()},o.append(x(`div`,`group flex items-center gap-2.5 border-b border-neutral-100 py-2 last:border-0`,x(`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()),x(`span`,`min-w-0 flex-1 truncate text-[13px] text-neutral-700`,t.name),x(`span`,`flex-none font-mono text-[11.5px] text-neutral-400`,t.id),e))}return a(`Bound users`,`A code is single-use and expires; redeeming it in a DM binds that account.`,o,x(`div`,`flex flex-col gap-2`,r,n))}function P(e,t){let i=x(`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`}`),a=x(`div`,`flex items-center gap-2`,x(`span`,`min-w-0 flex-1 truncate text-[13px] font-medium ${t.enabled?`text-neutral-800`:`text-neutral-400`}`,t.name||t.id),r(t.kind,Z[t.kind]),x(`span`,`flex-none font-mono text-[11px] text-neutral-400`,t.id)),o=n(``,``,t.enabled,T(e=>{t.enabled=e,I()}));o.classList.add(`flex-none`,`items-center`),a.append(o);let s=x(`div`,`mt-3 flex flex-wrap items-center gap-x-6 gap-y-2`);t.kind===`dm`?s.append(x(`span`,`text-[13px] text-neutral-400`,`Direct message · bound users only, mention not applicable`)):s.append(n(`Require mention`,``,t.requireMention,T(e=>t.requireMention=e)),n(`Require bind`,``,t.requireBind,T(e=>t.requireBind=e)));let l=w(t.cwd,``,T(e=>t.cwd=e)),u=x(`div`,`mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2`,F(`Working directory`,l.el),L(`Model & reasoning`,t,c,T(e=>{t.model=e.model,t.thinking=e.thinking,I()})));return i.append(a,s,u),i}function ee(e){let t=x(`div`,`flex flex-col gap-2.5`);return e.chats.length?t.append(...e.chats.map(t=>P(e,t))):t.append(m(`None yet. Chats appear here after the bot sees a message in them.`)),a(i===`slack`?`Channels`:`Chats`,`Discovered from inbound traffic — no platform reliably lists every chat a bot is in.`,t)}function I(){if(!o)return;f();let e=x(`div`,`mx-auto flex max-w-3xl flex-col gap-4`);e.append(A(o),j(o),M(o),ee(o)),d.replaceChildren(e)}return s(e,()=>void k(),()=>{p&&O()})}function he(){let t=x(`div`,`min-h-0 min-w-0 flex-1 overflow-y-auto p-4`),r=x(`div`,`mx-auto flex max-w-3xl min-w-0 flex-col gap-4`),i=x(`p`,`text-[12px] break-words`),a=x(`section`,`flex min-w-0 flex-col gap-3 border-b border-neutral-200 pb-4`),o=x(`section`,`flex min-w-0 flex-col gap-3`);r.append(x(`h2`,`text-[14px] font-semibold text-neutral-700`,`Configuration sync`),i,a,o),t.append(r);let s=null,c=!1,d=!1,f=0,p=``,m=!1,h=e=>e?new Date(e).toLocaleString():`Never`;async function _(){let e=f,t=await D(`/api/config-sync`,`Could not load configuration sync`,{cache:`no-store`});if(!(d||e!==f)){if(!t.ok){l(i,`failed`,t.error);return}s=t.value,m||(p=s.sourceUrl),S()}}async function y(t){if(!c){++f,c=!0,S(),l(i,`saving`,`Working...`);try{let n=await N(`/api/config-sync`,{action:t,...t===`subscribe`?{url:p}:{}});if(!n.ok)throw Error(await e(n,`Configuration sync failed`));let r=await n.json();s=r,m=!1,p=r.sourceUrl,l(i,`saved`,r.result??`Saved`)}catch(e){l(i,`failed`,e instanceof Error?e.message:`Configuration sync failed`),await _()}finally{c=!1,d||S()}}}function b(e,t){let n=v(e);return n.disabled=c,n.onclick=()=>{y(t)},n}function S(){if(!s||d)return;if(a.replaceChildren(x(`h3`,`text-[13px] font-medium text-neutral-700`,`Publish`)),s.publishedPath){let e=`${s.publicUrl||window.location.origin}${s.publishedPath}`,t=g(e,``,()=>{},!0);t.readOnly=!0,t.setAttribute(`aria-label`,`Sharing URL`),a.append(t,x(`div`,`flex flex-wrap items-center gap-2`,u(`btn text-[12px]`,()=>e),b(`Revoke link`,`revoke`)))}else a.append(x(`div`,``,b(`Generate link`,`publish`)));a.append(x(`p`,`text-[12px] text-neutral-500`,`Anyone with the link can read shared prompts, model definitions, the default model and its reasoning effort. API keys, headers and endpoints stay private.`));let e=g(p,`https://example.com/config-sync/...`,e=>{p=e,m=!0},!0);e.type=`url`,e.setAttribute(`aria-label`,`Configuration source URL`),e.disabled=c||s.enabled;let t=n(`Automatic sync`,``,s.enabled,e=>{y(e?`subscribe`:`pause`)});t.querySelector(`input`).disabled=c;let r=x(`div`,`flex flex-wrap items-center gap-3`,t);s.enabled&&r.append(b(`Sync now`,`sync`)),o.replaceChildren(x(`h3`,`text-[13px] font-medium text-neutral-700`,`Source`),F(`Source URL`,e),r);let i=x(`dl`,`grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1 text-[12px]`);for(let[e,t]of[[`Last checked`,h(s.lastChecked)],[`Last applied`,h(s.lastApplied)],[`Next check`,s.enabled?h(s.nextRunAt):`Paused`]])i.append(x(`dt`,`text-neutral-500`,e),x(`dd`,`min-w-0 break-words text-neutral-700`,t));if(o.append(i),s.error&&o.append(x(`p`,`text-[12px] break-words text-red-600`,s.error)),s.needsReload&&o.append(x(`p`,`text-[12px] text-amber-700`,`Reload pending; retry synchronization.`)),s.taskId){let e=x(`a`,`text-[12px] text-indigo-600 hover:underline`,`Sync task history`);e.href=`#/tasks/${encodeURIComponent(s.taskId)}`,o.append(e)}}_();let C=setInterval(()=>{!c&&!m&&_()},15e3);return{el:t,dispose:()=>{d=!0,clearInterval(C)}}}var ge=`text-[11.5px] text-neutral-400`,Q=`bg-neutral-50 text-neutral-500 ring-neutral-200`,_e=`bg-amber-50 text-amber-700 ring-amber-100`,ve=`Pi packages run with full system access: an extension executes arbitrary code, and a skill can instruct the model to run anything. Review the source before installing.`,ye=e=>e===`pier`||e===`local`?e:e.replace(/^(npm|git):/,``).replace(/\.git$/,``).replace(/@[^@/]*$/,``).split(`/`).filter(Boolean).pop()??e,be=e=>e.startsWith(`npm:`)?`npm`:/^(git:|(https?|ssh|git):\/\/)/.test(e)?`git`:`path`,xe=e=>e.kind===`pier`||e.kind===`local`,Se=e=>e.slice(0,e.lastIndexOf(`/`))||`/`;function Ce(t){let i=null,a=``,o=()=>{let e=t.cwd();return e?`?cwd=${encodeURIComponent(e)}`:``},s=e=>!xe(e)&&e.scope===`global`&&t.cwd()===void 0;async function c(){let e=await D(`/api/packages${o()}`,`packages could not be loaded`,{cache:`no-store`});i=e.ok?e.value:null,a=e.ok?``:e.error}let u=(e,t)=>i?.packages.find(n=>n.source===e&&n.scope===t),d=(e,t,n)=>{for(let r of i?.packages.filter(t=>t.source===e)??[]){let e=r.resources.find(e=>e.kind===t&&e.path===n);if(e)return{pkg:r,resource:e}}};async function f(e,n,r){let i=t.cwd(),a=await R(`/api/packages/resource`,{source:e.source,kind:n.kind,path:n.path,enabled:r,...i?{cwd:i}:{}},`could not save`,`PUT`);return a.ok?(e.resources=e.resources.map(e=>e.kind===n.kind&&e.path===n.path?a.value:e),t.changed(),{state:`saved`,text:`Saved — sessions take it on their next message.`}):{state:`failed`,text:a.error}}let p=e=>{t.pane.replaceChildren(x(`p`,`px-4 py-3 text-[12.5px] leading-relaxed text-red-600`,e))},h=(...e)=>x(`div`,`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4`,...e),_=(e,t,n=!0)=>[x(`dt`,`text-[12px] text-neutral-500`,e),x(`dd`,`text-[12px] leading-snug text-neutral-700 ${n?`font-mono break-all`:``}`,t)],v=(e,n)=>{let r=q(`Browse files`,`btn text-[12px]`);return r.onclick=()=>t.browse(e,n),r},S=(e,t,r,i,a)=>{let o=n(r,i,t.enabled,n=>void f(e,t,n).then(a));if(t.locked)for(let e of o.querySelectorAll(`input`))e.disabled=!0;return o};function C(e,n,i){let a=q(n.name,`font-mono text-[13px] text-neutral-700 hover:text-indigo-600 hover:underline`);a.onclick=()=>{let r={type:`resource`,source:e.source,kind:n.kind,path:n.path};t.select(r),E(r.source,r.kind,r.path)};let o=x(`div`,`flex min-w-0 flex-1 flex-col gap-0.5`,x(`span`,`flex flex-wrap items-center gap-2`,a,r(n.kind,Q)),...n.state?[x(`span`,`text-[11.5px] leading-snug text-amber-700`,n.state)]:[]);return x(`div`,`flex max-w-2xl items-start gap-3 border-b border-neutral-100 py-2.5 last:border-0`,o,S(e,n,``,``,i))}function w(e,n,a){let o=t.claim(),d=u(e,n);if(!d)return p(`unknown package: ${e}`);let f=x(`span`,ge,``);a&&l(f,a.state,a.text);let g=i?.busy===d.source;g&&!a&&l(f,`saving`,`${d.installedPath?`updating`:`installing`}…`);let b=r=>{t.live(o)&&w(e,n,r)},S=[..._(`Source`,d.source),..._(`Kind`,d.kind===`pier`?`built in — ships with Pier`:d.kind===`local`?`the agent directory's own files`:d.kind,!1),...d.version?_(`Version`,d.version):[],...d.installedPath===null?xe(d)?[]:_(`Installed at`,`not installed`,!1):_(`Installed at`,x(`span`,`flex flex-wrap items-center gap-2`,x(`span`,`font-mono break-all`,d.installedPath),v(d.installedPath)),!1)],T=[];if(s(d)&&d.kind!==`path`){let r=i?.checkedAt?`checked ${y(Date.parse(i.checkedAt))}`:`not checked yet`,a=q(`Check for updates`,`btn text-[12px]`);a.disabled=g,a.onclick=()=>{a.disabled=!0,l(f,`saving`,`checking…`),R(`/api/packages/check`,{},`update check failed`).then(r=>{r.ok&&(i=r.value),t.changed();let a=u(e,n);b(r.ok?{state:`saved`,text:a?.updateAvailable?`Checked — an update is available.`:`Checked — up to date.`}:{state:`failed`,text:r.error})})},S.push(..._(`Updates`,x(`span`,`flex flex-wrap items-center gap-2`,x(`span`,d.updateAvailable?`text-emerald-700`:``,d.updateAvailable?`update available (${r})`:r),a),!1));let o=q(`Update`,`btn text-[12.5px]`);o.disabled=g,o.onclick=()=>{o.disabled=!0,i&&={...i,busy:d.source},t.changed(),b({state:`saved`,text:`updating…`}),R(`/api/packages/update`,{source:d.source},`update failed`).then(async e=>{await c(),t.changed();let n=e.ok?e.value.packages.find(e=>e.source===d.source):void 0;b(e.ok?{state:`saved`,text:`Updated${n?.version?` to ${n.version}`:``} — sessions take it on their next message.`}:{state:`failed`,text:e.error})})},T.push(o)}if(s(d)){let e=q(`Remove`,`btn text-[12.5px] text-neutral-600 hover:text-red-600`);e.disabled=g,e.onclick=()=>{let n=d.kind===`path`?`settings.json forgets it; the directory stays.`:`Its files are deleted and settings.json forgets it.`;window.confirm(`Remove ${d.source}? ${n}`)&&(e.disabled=!0,l(f,`saving`,`removing…`),R(`/api/packages/remove`,{source:d.source},`remove failed`).then(async e=>{if(!e.ok)return b({state:`failed`,text:e.error});await c(),t.select(null),t.live(o)&&t.pane.replaceChildren(x(`div`,`flex min-h-0 flex-1 items-center justify-center p-6`,m(`Removed ${d.source}.`)))}))},T.push(e)}t.pane.replaceChildren(t.paneBar(ye(d.source),r(d.kind,Q),...d.scope===`project`?[r(`project`,_e)]:[],...T.length?[x(`div`,`ml-auto flex flex-none items-center gap-2`,...T)]:[]),h(x(`dl`,`grid max-w-2xl grid-cols-[auto_1fr] gap-x-4 gap-y-1.5`,...S),d.resources.length?x(`div`,`flex max-w-2xl flex-col`,...d.resources.map(e=>C(d,e,b))):m(d.installedPath?`No extensions or skills.`:`Not installed — nothing to load.`),f))}let T=(e,n)=>n.locked?`Switch it under Tools: the tool's install writes this file and its uninstall removes it.`:e.kind===`pier`?n.kind===`skill`?`Pier's own skill. Off, no session is offered it.`:`Loaded from inside Pier — nothing installed, nothing to update. A session mid-turn keeps the tools it started with.`:`Written to ${t.cwd()?`this project's .pi/settings.json`:`settings.json`} as +path / −path for ${ye(e.source)}; sessions pick it up on their next open.`;async function E(e,n,i,a){let o=t.claim(),s=d(e,n,i);if(!s)return p(`unknown ${n}: ${i}`);let{pkg:c,resource:u}=s,f=x(`span`,ge,``);a&&l(f,a.state,a.text);let m=x(`div`,`min-h-0 flex-1 overflow-auto`),h=i.startsWith(`/`);if(t.pane.replaceChildren(t.paneBar(u.name,r(ye(c.source),Q),r(u.kind,Q),x(`span`,`ml-auto flex flex-wrap items-center gap-2`,x(`span`,`font-mono text-[11px] text-neutral-400 break-all`,u.path),...h?[v(Se(i),b(i))]:[])),x(`div`,`flex flex-none flex-col gap-2 border-b border-neutral-200 px-4 py-3`,S(c,u,`Enabled`,T(c,u),r=>{t.live(o)&&E(e,n,i,r)}),...u.state?[x(`p`,`text-[12px] text-amber-700`,u.state)]:[],f),m),i.startsWith(`<inline:`)){m.append(x(`p`,`px-4 py-3 text-[12.5px] text-neutral-400`,`Loaded from inside Pier — there is no file to show.`));return}let g=await O(i);if(!t.live(o))return;if(!g.ok)return m.append(x(`p`,`px-4 py-3 text-[12.5px] text-red-600`,g.error));let _=await j(i);t.live(o)&&m.append(V(I(g.value),_))}async function O(t){let n=`/api/fs/file?root=${encodeURIComponent(Se(t))}&path=${encodeURIComponent(b(t))}`,r;try{r=await fetch(n,{cache:`no-store`})}catch(e){return{ok:!1,error:`could not read ${t}: ${String(e)}`}}return r.ok?{ok:!0,value:await r.text()}:{ok:!1,error:await e(r,`could not read ${t}`)}}function k(e,n=``){let r=t.claim(),a=x(`span`,ge,``);e&&l(a,e.state,e.text);let o=n,s=g(n,`npm:@scope/name · git:github.com/owner/repo · /path/to/package`,e=>o=e,!0),u=q(`Install`,`btn btn-primary text-[12.5px]`),d=()=>{let e=o.trim();if(!e)return l(a,`failed`,`A package source is required.`);u.disabled=!0,l(a,`saving`,`installing ${e}…`),i&&(i={...i,busy:e,packages:[...i.packages,{source:e,kind:be(e),scope:`global`,version:null,installedPath:null,updateAvailable:!1,resources:[]}]},t.changed()),R(`/api/packages`,{source:e},`install failed`).then(async n=>{if(await c(),t.changed(),!t.live(r))return;if(!n.ok)return k({state:`failed`,text:n.error},e);let{package:i}=n.value;t.select({type:`package`,source:i.source,scope:i.scope}),w(i.source,i.scope,{state:`saved`,text:`Installed ${i.source} — sessions take it on their next message.`})})};u.onclick=d,s.onkeydown=e=>{e.key===`Enter`&&d()},t.pane.replaceChildren(t.paneBar(`Add package`),h(x(`div`,`flex max-w-2xl flex-col gap-3`,F(`Source`,s,{hint:"What `pi install` takes: an npm package, a git URL (both may pin @version), or a directory on this machine."}),x(`p`,`text-[12.5px] leading-relaxed text-amber-800`,ve),x(`div`,`flex items-center gap-3`,u,a)))),s.focus()}return{get registry(){return i},get error(){return a},load:c,openPackage:w,openResource:E,openAdd:k}}async function we(t,n){let r;try{r=await N(`/api/settings`,t,`PUT`)}catch(e){return{outcome:{state:`failed`,text:`Could not save: ${String(e)}`}}}if(!r.ok)return{outcome:{state:`failed`,text:await e(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 Te(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 Ee(t,i,a){let o=`global`,c=null,u=0,d=0,f=``,p=()=>f?`Global (${f})`:`Global`,h=null,_=[],v=``,y=null,C=null,w=()=>{C?.dispose(),C=null},O=()=>{w(),++d,C=he(),H.replaceChildren(C.el)},M=[],P=e=>e.custom===!0,ee=x(`span`,`min-w-0 flex-1 truncate`),L=x(`button`,`${K} flex items-center gap-1.5`,ee,W(k,`h-3.5 w-3.5 text-neutral-500`));L.setAttribute(`aria-haspopup`,`true`),L.onclick=()=>{if(L.getAttribute(`aria-expanded`)===`true`)return ne();T(L,[{label:p(),checked:o===`global`,onSelect:()=>Ee(`global`)},...i().map(e=>({label:e,hint:b(e),checked:o===e,onSelect:()=>Ee(e)}))],`Scope`)};let R=x(`div`,`${A} flex-col items-stretch gap-1.5 px-3 py-2.5`);R.append(x(`span`,`field-label`,`Scope`),L);let z=x(`div`,`min-h-0 flex-1 overflow-y-auto py-1.5`),B=x(`nav`,`${re} w-64 flex-none text-[13px] leading-5 max-md:max-h-48 max-md:w-full`);B.append(R,z);let H=x(`div`,`${re} min-w-0 flex-1`),te=x(`div`,`flex min-h-0 flex-1 gap-3 px-4 pb-4 pt-1 max-md:flex-col`);te.append(B,H),t.append(te);let U=(e,...t)=>x(`div`,`${A} flex-wrap gap-3 px-4 py-2.5`,x(`span`,`font-mono text-[12.5px] text-neutral-500`,e),...t),G=Ce({pane:H,paneBar:U,claim:()=>++d,live:e=>e===d,cwd:()=>o===`global`?void 0:o,changed:()=>Z(h),browse:a,select:e=>{c=e,e?.type===`resource`&&ue.set(e.source,!0),Z(h)}}),J=(e=``)=>`?scope=${encodeURIComponent(o)}${e}`;async function ie(){if(o!==`global`){_=[],v=``;return}let e=await D(`/api/settings`,`could not be loaded`,{cache:`no-store`});if(!e.ok){_=[],v=e.error;return}ae(e.value),v=``}function ae(e){_=e.catalog,M=e.customTools,y=e.toolsTaskId}async function oe(e,t){let{outcome:n,answer:r}=await we(e,t);return r&&(ae(r),Z(h)),n}async function se(){let e=++u;d++;let[t]=await Promise.all([D(`/api/config${J()}`,`failed to load config`,{cache:`no-store`}),ie(),G.load()]);if(e!==u)return;if(!t.ok){Z(null),me(t.error);return}let n=t.value;o===`global`&&n.dir&&(f=n.dir,De()),h=n,Z(n),c?c.type===`sync`&&O():pe()}function Y(e,t){return x(`div`,`flex items-center justify-between gap-2 px-3 pb-1 pt-3 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,x(`span`,``,e),...t?[t]:[])}let ce=e=>x(`span`,`flex-none rounded bg-neutral-100 px-1 text-[10px] font-semibold uppercase tracking-wide text-neutral-500`,e),le=()=>x(`span`,`flex-none rounded bg-emerald-50 px-1 text-[10px] font-semibold uppercase tracking-wide text-emerald-700`,`on`);function X(e,t,n,r,i={}){let a=x(`button`,`config-row flex w-full cursor-pointer items-center gap-1.5 py-1.5 pr-3 text-left transition-colors hover:bg-neutral-100 ${t?`bg-indigo-50 font-medium hover:bg-indigo-50`:``} ${n?`text-neutral-400`:``}`),o=x(`span`,`truncate`,e);if(i.note){let e=x(`span`,`truncate text-[11px] font-normal leading-4 text-amber-700`,i.note);e.title=i.note,a.append(x(`span`,`flex min-w-0 flex-1 flex-col`,o,e))}else a.append(o);return a.append(...i.tags??[]),a.style.paddingLeft=`${i.flush?0:20+(i.depth??0)*14}px`,a.title=e,a.onclick=r,a}let ue=new Map,de=e=>ue.get(e.source)??(e.kind===`pier`||e.kind===`local`);function fe(e,t,n){let r={type:`package`,source:e.source,scope:e.scope},i=[];G.registry?.busy===e.source?i.push(x(`span`,`flex-none text-[11px] text-neutral-400`,e.installedPath?`updating…`:`installing…`)):e.resources.some(e=>e.enabled)&&i.push(le()),e.scope===`project`&&i.push(ce(`project`));let a=e.installedPath===null&&!xe(e),o=de(e),s=x(`button`,`flex w-5 flex-none cursor-pointer items-center justify-center self-stretch text-neutral-500 hover:bg-neutral-100`,W(E,`chev h-3 w-3`));o&&s.classList.add(`chev-open`),s.title=`${o?`Collapse`:`Expand`} ${ye(e.source)}`,s.setAttribute(`aria-label`,s.title),s.setAttribute(`aria-expanded`,String(o)),s.onclick=()=>{ue.set(e.source,!o),Z(h)};let c=X(ye(e.source),t(r),a,()=>n(r),{tags:i,flush:!0}),l=[x(`div`,`flex items-stretch ${t(r)?`bg-indigo-50`:``}`,s,c)];if(!o)return l;let u=e.resources.map(e=>e.name),d=new Set(u.filter((e,t)=>u.indexOf(e)!==t));for(let[r,i]of[[`extensions`,`extension`],[`skills`,`skill`]]){let a=e.resources.filter(e=>e.kind===i);if(!a.length)continue;let o=x(`div`,`py-0.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,r);o.style.paddingLeft=`34px`,l.push(o);for(let r of a){let a={type:`resource`,source:e.source,kind:i,path:r.path};l.push(X(r.name,t(a),!r.enabled,()=>n(a),{depth:2,note:r.state,tags:d.has(r.name)?[ce(i)]:[]}))}}return l}function Z(e){if(!e){z.replaceChildren();return}let t=e=>JSON.stringify(e)===JSON.stringify(c),n=t=>{w(),c=t,Z(e),t.type===`file`?ge(t.name,t.readonly):t.type===`tools`?be():t.type===`sync`?O():t.type===`package`?G.openPackage(t.source,t.scope):t.type===`resource`?G.openResource(t.source,t.kind,t.path):G.openAdd()},r=[];if(o===`global`){let e={type:`sync`};r.push(Y(`Instance`),X(`Configuration sync`,t(e),!1,()=>n(e)))}r.push(Y(`Files`));for(let i of e.files){let e={type:`file`,name:i.name,readonly:i.readonly};r.push(X(i.name,t(e),!i.exists,()=>n(e)))}let i={type:`add`},a=q(`Add package`,`normal-case tracking-normal hover:underline ${t(i)?`text-indigo-700`:`text-indigo-600`}`);a.onclick=()=>n(i),r.push(Y(`Packages`,o===`global`?a:void 0)),G.error&&r.push(x(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-red-600`,G.error));for(let e of G.registry?.packages??[])r.push(...fe(e,t,n));if(o===`global`){if(r.push(Y(`Tools`)),v)r.push(x(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-red-600`,v));else{let e={type:`tools`},i=_.filter(e=>e.enabled).length;r.push(X(`command-line tools`,t(e),!1,()=>n(e),{tags:i?[le()]:[]}))}}z.replaceChildren(...r)}function pe(){H.replaceChildren(x(`div`,`flex min-h-0 flex-1 items-center justify-center p-6`,m(`Select a file to edit, or a package, extension or skill to switch.`)))}function me(e){H.replaceChildren(x(`p`,`px-4 py-3 text-[12.5px] leading-relaxed text-red-600`,e))}async function ge(t,n){let r=++d,i=await D(`/api/config/files/${encodeURIComponent(t)}${J()}`,`failed to load ${t}`,{cache:`no-store`});if(!i.ok){r===d&&me(i.error);return}if(r!==d)return;let{content:a}=i.value,o=a,s=x(`span`,`text-[11.5px] text-neutral-400`,``),c=x(`button`,`btn btn-primary 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=a;let f=async()=>{if(c.disabled)return;let n=u.value;c.disabled=!0,l(s,`saving`,`saving…`);try{let r=await N(`/api/config/files/${encodeURIComponent(t)}${J()}`,{content:n,expected:o},`PUT`);if(!r.ok)return l(s,`failed`,await e(r,`save failed`));let i=await r.json();o=i.content,u.value===n?(u.value=i.content,l(s,`saved`,`saved — applies to new sessions`)):l(s,`idle`,`saved; newer changes are unsaved`)}catch(e){l(s,`failed`,`save failed: ${String(e)}`)}finally{c.disabled=!1}},p=x(`button`,`btn text-[12.5px]`,`Edit`),m=x(`button`,`btn text-[12.5px]`,`View`),h=(...e)=>x(`div`,`ml-auto flex flex-none items-center gap-2`,...e),g=()=>{H.replaceChildren(U(t,s,h(m,c)),u),u.focus()},_=async()=>{let e=await j(t);r===d&&H.replaceChildren(n?U(t,x(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,`read-only`)):U(t,s,h(p)),...n?[x(`p`,`border-b border-neutral-200 px-4 py-2 text-[12.5px] leading-relaxed text-neutral-500`,`Pier manages this file: the default model is set in Settings → Models; other keys are edited on disk, then pier reload.`)]:[],x(`div`,`min-h-0 flex-1 overflow-auto`,V(I(u.value),e)))};p.onclick=g,m.onclick=()=>void _(),c.onclick=()=>void f(),u.onkeydown=e=>{(e.metaKey||e.ctrlKey)&&e.key===`s`&&(e.preventDefault(),f())},u.oninput=()=>{l(s,`idle`,`unsaved changes`)},await _()}function Q(e){if(!y)return null;let t=x(`a`,`text-indigo-600 hover:underline`,e);return t.href=`#/tasks/${encodeURIComponent(y)}`,t}let _e=()=>{let e=x(`a`,`text-indigo-600 hover:underline`,`ubix`);return e.href=`https://github.com/timqi/ubix`,e.target=`_blank`,e.rel=`noreferrer`,e};function ve(e){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 be(e,t={name:``,toml:``}){d++;let i=x(`span`,`text-[11.5px] text-neutral-400`,``);e&&l(i,e.state,e.text);let a=Q(`the update task`),o=e=>{let t=x(`div`,`flex min-w-0 flex-1 flex-col gap-0.5`,x(`span`,`flex items-center gap-2 text-[13px] text-neutral-700`,x(`span`,`font-mono`,e.name),...P(e)?[r(`yours`,`bg-neutral-50 text-neutral-500 ring-neutral-200`)]:[]),x(`span`,`text-[11.5px] leading-snug text-neutral-400`,e.summary||ve(e)),...e.summary?[x(`span`,`font-mono text-[11px] leading-snug ${e.binary.error?`text-red-600`:`text-neutral-400`}`,ve(e))]:[]),i=n(``,``,e.enabled,t=>void Se(e.name,t,e=>be(e))),a=x(`button`,`btn text-[12px] text-neutral-500 hover:text-red-600`,`Remove`);return a.onclick=()=>{a.disabled=!0;let t=Te(e,M);oe(t.body,t.saved).then(e=>be(e))},x(`div`,`flex max-w-2xl items-start gap-3 border-b border-neutral-100 py-2.5 last:border-0`,t,...P(e)?[a]:[],i)},s={...t},c=x(`span`,`font-mono text-[12px] text-neutral-500`,`[tools.<name>]`),u=g(s.name,`claude`,e=>{s.name=e,c.textContent=`[tools.${e.trim()||`<name>`}]`},!0),f=document.createElement(`textarea`);f.className=`${S} h-24 resize-y font-mono leading-snug`,f.spellcheck=!1,f.value=s.toml,f.placeholder=`spec = "github:owner/repo"
|
|
1
|
+
import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,W as b,Y as x,_ as S,b as C,c as w,d as T,dt as E,et as D,f as O,ft as k,g as A,h as j,i as M,it as N,j as P,k as F,lt as ee,m as I,n as L,nt as R,o as z,ot as B,p as V,pt as H,r as te,rt as U,st as W,u as ne,ut as G,v as K,w as q,x as J,y as re,z as ie}from"./index-CzV2cZEH.js";var ae=[[`path`,{d:`m18 15-6-6-6 6`}]],oe=[[`path`,{d:`M15 3h6v6`}],[`path`,{d:`M10 14 21 3`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`}]],se=[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`}],[`path`,{d:`M12 9v4`}],[`path`,{d:`M12 17h.01`}]],Y={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}},ce=()=>`https://api.slack.com/apps?new_app=1&manifest_json=${encodeURIComponent(JSON.stringify(Y))}`;function le(){let e=v(`Create Slack app`,!0);e.append(W(oe)),e.classList.add(`inline-flex`,`items-center`,`gap-1.5`),e.classList.add(`mt-1`,`w-fit`),e.onclick=()=>window.open(ce(),`_blank`,`noreferrer`);let n=u(`btn w-fit text-[12.5px]`,()=>JSON.stringify(Y,null,2));return t(`Creating a Slack app`,[c(`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.",c(`Prefer to paste it yourself? Create the app from a manifest and use this:`,n)])}var X=()=>t(`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>`. `@bot s <question>`, as the first message of a thread, drafts a session — directory, model, reasoning — and Start runs the question in it. Slack's client swallows an unregistered `/command` before it ever reaches an app."]),ue=()=>t(`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.`]),de=()=>t(`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>`. `/s <question>` or `s <question>`, outside any topic, drafts a session — directory, model, reasoning — and Start runs the question in it. A bare @mention with nothing else also opens the settings panel."]),fe=[[`slack`,`Slack`],[`lark`,`Lark`]],Z={dm:`bg-sky-50 text-sky-700 ring-sky-200`,group:`bg-neutral-100 text-neutral-600 ring-neutral-200`},pe=`pier.channelsPlatform`;function me(e){let t=localStorage.getItem(pe),i=fe.some(([e])=>e===t)?t:`slack`,o=null,c=[],l=x(`div`,`ml-auto flex items-center gap-1.5 text-[11.5px]`),u=x(`div`,`pagehead pagehead-hug sticky top-[-8px] z-30`,l),d=x(`div`,`px-4 pb-5 pt-4`);e.append(x(`div`,`min-h-0 flex-1 overflow-y-auto`,u,d));function f(){u.replaceChildren(h(fe.map(([e,t])=>[t,e]),i,e=>{p&&O(),i=e,localStorage.setItem(pe,e),k()}),l)}let p,y=!1,b=null;function S(e){if(l.replaceChildren(),e!==`clean`){if(l.className=`ml-auto flex items-center gap-1.5 text-[11.5px] ${_[e]}`,e===`saving`)l.append(W(G,`spinner`),x(`span`,``,`Saving…`));else if(e===`saved`)l.append(W(H),x(`span`,``,`Saved`)),setTimeout(()=>{l.textContent?.includes(`Saved`)&&S(`clean`)},2e3);else{let e=q(`Retry`,`cursor-pointer underline`);e.onclick=O,l.append(W(se),x(`span`,``,`Save failed`),e)}}}function C(){S(`saving`),clearTimeout(p),p=setTimeout(O,500)}let T=e=>t=>{e(t),C()};async function E(e){y=!0,S(`saving`);try{S((await N(`/api/channels/${e.platform}`,e.config,`PUT`)).ok?`saved`:`failed`)}catch{S(`failed`)}finally{y=!1;let e=b;b=null,e&&E(e)}}function O(){if(clearTimeout(p),p=void 0,!o)return;let e={platform:i,config:o};y?b=e:E(e)}async function k(){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/${i}`,`Failed to load`);if(!e.ok){o=null,f(),d.replaceChildren(m(e.error));return}o=e.value,S(`clean`),I()}function A(e){let t=i===`lark`,r=g(e.token,t?`cli_…`:`xoxb-…`,T(t=>e.token=t),!0),o=g(e.appToken,t?``:`xapp-…`,T(t=>e.appToken=t),!0),s=w(e.cwd,`(pier process cwd)`,T(t=>e.cwd=t));return a(`Connection`,t?`Pier connects over Feishu's WebSocket long connection; no public URL or webhook needed.`:`Pier connects over Socket Mode; no public URL or webhook needed.`,n(`Enabled`,`Start the adapter when Pier boots.`,e.enabled,T(t=>{e.enabled=t,f()})),F(t?`App ID`:`Bot token`,r,{hint:`Stored locally, shown masked once saved.`,help:t?ue():le()}),t?F(`App Secret`,o,{hint:`From Credentials & Basic Info, beside the App ID.`}):F(`App-level token`,o,{hint:`Opens the Socket Mode connection. Needs connections:write.`}),F(`Default working directory`,s.el,{hint:`Where sessions this channel opens start.`}),x(`span`,`flex items-center gap-1.5 text-[13px] text-neutral-400`,x(`span`,``,t?`Every topic is its own session.`:`Every thread is its own session.`),t?de():X()))}function j(e){return a(`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.`,n(`Require mention in groups`,`Ignore group messages that do not @mention or reply to the bot.`,e.requireMention,T(t=>e.requireMention=t)),n(`Require bound user`,`Only users bound with a code below can drive the agent.`,e.requireBind,T(t=>e.requireBind=t)),L(`Model & reasoning`,e,c,T(t=>{e.model=t.model,e.thinking=t.thinking,I()})))}function M(e){let t=x(`span`,`font-mono text-[15px] font-semibold tracking-widest`),n=x(`div`,`hidden items-center gap-2 rounded-lg bg-indigo-50 px-3 py-2 text-[12.5px] text-indigo-800`,t,x(`span`,`text-[11.5px] text-indigo-500`,`DM the bot /bind <code> · expires in 10 min`)),r=v(`Generate bind code`);r.onclick=async()=>{let e=await fetch(`/api/channels/${i}/bind-code`,{method:`POST`});if(!e.ok)return;let{code:r}=await e.json();t.textContent=r,n.classList.replace(`hidden`,`flex`)};let o=x(`div`,`flex flex-col`);e.users.length||o.append(m(`No bound users yet.`));for(let t of e.users){let e=q(`Remove`,`cursor-pointer text-[11.5px] text-neutral-400 opacity-0 transition-opacity hover:text-red-600 group-hover:opacity-100 pointer-coarse:opacity-100`);e.onclick=async()=>{await fetch(`/api/channels/${i}/users/${encodeURIComponent(t.id)}`,{method:`DELETE`}),await k()},o.append(x(`div`,`group flex items-center gap-2.5 border-b border-neutral-100 py-2 last:border-0`,x(`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()),x(`span`,`min-w-0 flex-1 truncate text-[13px] text-neutral-700`,t.name),x(`span`,`flex-none font-mono text-[11.5px] text-neutral-400`,t.id),e))}return a(`Bound users`,`A code is single-use and expires; redeeming it in a DM binds that account.`,o,x(`div`,`flex flex-col gap-2`,r,n))}function P(e,t){let i=x(`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`}`),a=x(`div`,`flex items-center gap-2`,x(`span`,`min-w-0 flex-1 truncate text-[13px] font-medium ${t.enabled?`text-neutral-800`:`text-neutral-400`}`,t.name||t.id),r(t.kind,Z[t.kind]),x(`span`,`flex-none font-mono text-[11px] text-neutral-400`,t.id)),o=n(``,``,t.enabled,T(e=>{t.enabled=e,I()}));o.classList.add(`flex-none`,`items-center`),a.append(o);let s=x(`div`,`mt-3 flex flex-wrap items-center gap-x-6 gap-y-2`);t.kind===`dm`?s.append(x(`span`,`text-[13px] text-neutral-400`,`Direct message · bound users only, mention not applicable`)):s.append(n(`Require mention`,``,t.requireMention,T(e=>t.requireMention=e)),n(`Require bind`,``,t.requireBind,T(e=>t.requireBind=e)));let l=w(t.cwd,``,T(e=>t.cwd=e)),u=x(`div`,`mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2`,F(`Working directory`,l.el),L(`Model & reasoning`,t,c,T(e=>{t.model=e.model,t.thinking=e.thinking,I()})));return i.append(a,s,u),i}function ee(e){let t=x(`div`,`flex flex-col gap-2.5`);return e.chats.length?t.append(...e.chats.map(t=>P(e,t))):t.append(m(`None yet. Chats appear here after the bot sees a message in them.`)),a(i===`slack`?`Channels`:`Chats`,`Discovered from inbound traffic — no platform reliably lists every chat a bot is in.`,t)}function I(){if(!o)return;f();let e=x(`div`,`mx-auto flex max-w-3xl flex-col gap-4`);e.append(A(o),j(o),M(o),ee(o)),d.replaceChildren(e)}return s(e,()=>void k(),()=>{p&&O()})}function he(){let t=x(`div`,`min-h-0 min-w-0 flex-1 overflow-y-auto p-4`),r=x(`div`,`mx-auto flex max-w-3xl min-w-0 flex-col gap-4`),i=x(`p`,`text-[12px] break-words`),a=x(`section`,`flex min-w-0 flex-col gap-3 border-b border-neutral-200 pb-4`),o=x(`section`,`flex min-w-0 flex-col gap-3`);r.append(x(`h2`,`text-[14px] font-semibold text-neutral-700`,`Configuration sync`),i,a,o),t.append(r);let s=null,c=!1,d=!1,f=0,p=``,m=!1,h=e=>e?new Date(e).toLocaleString():`Never`;async function _(){let e=f,t=await D(`/api/config-sync`,`Could not load configuration sync`,{cache:`no-store`});if(!(d||e!==f)){if(!t.ok){l(i,`failed`,t.error);return}s=t.value,m||(p=s.sourceUrl),S()}}async function y(t){if(!c){++f,c=!0,S(),l(i,`saving`,`Working...`);try{let n=await N(`/api/config-sync`,{action:t,...t===`subscribe`?{url:p}:{}});if(!n.ok)throw Error(await e(n,`Configuration sync failed`));let r=await n.json();s=r,m=!1,p=r.sourceUrl,l(i,`saved`,r.result??`Saved`)}catch(e){l(i,`failed`,e instanceof Error?e.message:`Configuration sync failed`),await _()}finally{c=!1,d||S()}}}function b(e,t){let n=v(e);return n.disabled=c,n.onclick=()=>{y(t)},n}function S(){if(!s||d)return;if(a.replaceChildren(x(`h3`,`text-[13px] font-medium text-neutral-700`,`Publish`)),s.publishedPath){let e=`${s.publicUrl||window.location.origin}${s.publishedPath}`,t=g(e,``,()=>{},!0);t.readOnly=!0,t.setAttribute(`aria-label`,`Sharing URL`),a.append(t,x(`div`,`flex flex-wrap items-center gap-2`,u(`btn text-[12px]`,()=>e),b(`Revoke link`,`revoke`)))}else a.append(x(`div`,``,b(`Generate link`,`publish`)));a.append(x(`p`,`text-[12px] text-neutral-500`,`Anyone with the link can read shared prompts, model definitions, the default model and its reasoning effort. API keys, headers and endpoints stay private.`));let e=g(p,`https://example.com/config-sync/...`,e=>{p=e,m=!0},!0);e.type=`url`,e.setAttribute(`aria-label`,`Configuration source URL`),e.disabled=c||s.enabled;let t=n(`Automatic sync`,``,s.enabled,e=>{y(e?`subscribe`:`pause`)});t.querySelector(`input`).disabled=c;let r=x(`div`,`flex flex-wrap items-center gap-3`,t);s.enabled&&r.append(b(`Sync now`,`sync`)),o.replaceChildren(x(`h3`,`text-[13px] font-medium text-neutral-700`,`Source`),F(`Source URL`,e),r);let i=x(`dl`,`grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1 text-[12px]`);for(let[e,t]of[[`Last checked`,h(s.lastChecked)],[`Last applied`,h(s.lastApplied)],[`Next check`,s.enabled?h(s.nextRunAt):`Paused`]])i.append(x(`dt`,`text-neutral-500`,e),x(`dd`,`min-w-0 break-words text-neutral-700`,t));if(o.append(i),s.error&&o.append(x(`p`,`text-[12px] break-words text-red-600`,s.error)),s.needsReload&&o.append(x(`p`,`text-[12px] text-amber-700`,`Reload pending; retry synchronization.`)),s.taskId){let e=x(`a`,`text-[12px] text-indigo-600 hover:underline`,`Sync task history`);e.href=`#/tasks/${encodeURIComponent(s.taskId)}`,o.append(e)}}_();let C=setInterval(()=>{!c&&!m&&_()},15e3);return{el:t,dispose:()=>{d=!0,clearInterval(C)}}}var ge=`text-[11.5px] text-neutral-400`,Q=`bg-neutral-50 text-neutral-500 ring-neutral-200`,_e=`bg-amber-50 text-amber-700 ring-amber-100`,ve=`Pi packages run with full system access: an extension executes arbitrary code, and a skill can instruct the model to run anything. Review the source before installing.`,ye=e=>e===`pier`||e===`local`?e:e.replace(/^(npm|git):/,``).replace(/\.git$/,``).replace(/@[^@/]*$/,``).split(`/`).filter(Boolean).pop()??e,be=e=>e.startsWith(`npm:`)?`npm`:/^(git:|(https?|ssh|git):\/\/)/.test(e)?`git`:`path`,xe=e=>e.kind===`pier`||e.kind===`local`,Se=e=>e.slice(0,e.lastIndexOf(`/`))||`/`;function Ce(t){let i=null,a=``,o=()=>{let e=t.cwd();return e?`?cwd=${encodeURIComponent(e)}`:``},s=e=>!xe(e)&&e.scope===`global`&&t.cwd()===void 0;async function c(){let e=await D(`/api/packages${o()}`,`packages could not be loaded`,{cache:`no-store`});i=e.ok?e.value:null,a=e.ok?``:e.error}let u=(e,t)=>i?.packages.find(n=>n.source===e&&n.scope===t),d=(e,t,n)=>{for(let r of i?.packages.filter(t=>t.source===e)??[]){let e=r.resources.find(e=>e.kind===t&&e.path===n);if(e)return{pkg:r,resource:e}}};async function f(e,n,r){let i=t.cwd(),a=await R(`/api/packages/resource`,{source:e.source,kind:n.kind,path:n.path,enabled:r,...i?{cwd:i}:{}},`could not save`,`PUT`);return a.ok?(e.resources=e.resources.map(e=>e.kind===n.kind&&e.path===n.path?a.value:e),t.changed(),{state:`saved`,text:`Saved — sessions take it on their next message.`}):{state:`failed`,text:a.error}}let p=e=>{t.pane.replaceChildren(x(`p`,`px-4 py-3 text-[12.5px] leading-relaxed text-red-600`,e))},h=(...e)=>x(`div`,`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4`,...e),_=(e,t,n=!0)=>[x(`dt`,`text-[12px] text-neutral-500`,e),x(`dd`,`text-[12px] leading-snug text-neutral-700 ${n?`font-mono break-all`:``}`,t)],v=(e,n)=>{let r=q(`Browse files`,`btn text-[12px]`);return r.onclick=()=>t.browse(e,n),r},S=(e,t,r,i,a)=>{let o=n(r,i,t.enabled,n=>void f(e,t,n).then(a));if(t.locked)for(let e of o.querySelectorAll(`input`))e.disabled=!0;return o};function C(e,n,i){let a=q(n.name,`font-mono text-[13px] text-neutral-700 hover:text-indigo-600 hover:underline`);a.onclick=()=>{let r={type:`resource`,source:e.source,kind:n.kind,path:n.path};t.select(r),E(r.source,r.kind,r.path)};let o=x(`div`,`flex min-w-0 flex-1 flex-col gap-0.5`,x(`span`,`flex flex-wrap items-center gap-2`,a,r(n.kind,Q)),...n.state?[x(`span`,`text-[11.5px] leading-snug text-amber-700`,n.state)]:[]);return x(`div`,`flex max-w-2xl items-start gap-3 border-b border-neutral-100 py-2.5 last:border-0`,o,S(e,n,``,``,i))}function w(e,n,a){let o=t.claim(),d=u(e,n);if(!d)return p(`unknown package: ${e}`);let f=x(`span`,ge,``);a&&l(f,a.state,a.text);let g=i?.busy===d.source;g&&!a&&l(f,`saving`,`${d.installedPath?`updating`:`installing`}…`);let b=r=>{t.live(o)&&w(e,n,r)},S=[..._(`Source`,d.source),..._(`Kind`,d.kind===`pier`?`built in — ships with Pier`:d.kind===`local`?`the agent directory's own files`:d.kind,!1),...d.version?_(`Version`,d.version):[],...d.installedPath===null?xe(d)?[]:_(`Installed at`,`not installed`,!1):_(`Installed at`,x(`span`,`flex flex-wrap items-center gap-2`,x(`span`,`font-mono break-all`,d.installedPath),v(d.installedPath)),!1)],T=[];if(s(d)&&d.kind!==`path`){let r=i?.checkedAt?`checked ${y(Date.parse(i.checkedAt))}`:`not checked yet`,a=q(`Check for updates`,`btn text-[12px]`);a.disabled=g,a.onclick=()=>{a.disabled=!0,l(f,`saving`,`checking…`),R(`/api/packages/check`,{},`update check failed`).then(r=>{r.ok&&(i=r.value),t.changed();let a=u(e,n);b(r.ok?{state:`saved`,text:a?.updateAvailable?`Checked — an update is available.`:`Checked — up to date.`}:{state:`failed`,text:r.error})})},S.push(..._(`Updates`,x(`span`,`flex flex-wrap items-center gap-2`,x(`span`,d.updateAvailable?`text-emerald-700`:``,d.updateAvailable?`update available (${r})`:r),a),!1));let o=q(`Update`,`btn text-[12.5px]`);o.disabled=g,o.onclick=()=>{o.disabled=!0,i&&={...i,busy:d.source},t.changed(),b({state:`saved`,text:`updating…`}),R(`/api/packages/update`,{source:d.source},`update failed`).then(async e=>{await c(),t.changed();let n=e.ok?e.value.packages.find(e=>e.source===d.source):void 0;b(e.ok?{state:`saved`,text:`Updated${n?.version?` to ${n.version}`:``} — sessions take it on their next message.`}:{state:`failed`,text:e.error})})},T.push(o)}if(s(d)){let e=q(`Remove`,`btn text-[12.5px] text-neutral-600 hover:text-red-600`);e.disabled=g,e.onclick=()=>{let n=d.kind===`path`?`settings.json forgets it; the directory stays.`:`Its files are deleted and settings.json forgets it.`;window.confirm(`Remove ${d.source}? ${n}`)&&(e.disabled=!0,l(f,`saving`,`removing…`),R(`/api/packages/remove`,{source:d.source},`remove failed`).then(async e=>{if(!e.ok)return b({state:`failed`,text:e.error});await c(),t.select(null),t.live(o)&&t.pane.replaceChildren(x(`div`,`flex min-h-0 flex-1 items-center justify-center p-6`,m(`Removed ${d.source}.`)))}))},T.push(e)}t.pane.replaceChildren(t.paneBar(ye(d.source),r(d.kind,Q),...d.scope===`project`?[r(`project`,_e)]:[],...T.length?[x(`div`,`ml-auto flex flex-none items-center gap-2`,...T)]:[]),h(x(`dl`,`grid max-w-2xl grid-cols-[auto_1fr] gap-x-4 gap-y-1.5`,...S),d.resources.length?x(`div`,`flex max-w-2xl flex-col`,...d.resources.map(e=>C(d,e,b))):m(d.installedPath?`No extensions or skills.`:`Not installed — nothing to load.`),f))}let T=(e,n)=>n.locked?`Switch it under Tools: the tool's install writes this file and its uninstall removes it.`:e.kind===`pier`?n.kind===`skill`?`Pier's own skill. Off, no session is offered it.`:`Loaded from inside Pier — nothing installed, nothing to update. A session mid-turn keeps the tools it started with.`:`Written to ${t.cwd()?`this project's .pi/settings.json`:`settings.json`} as +path / −path for ${ye(e.source)}; sessions pick it up on their next open.`;async function E(e,n,i,a){let o=t.claim(),s=d(e,n,i);if(!s)return p(`unknown ${n}: ${i}`);let{pkg:c,resource:u}=s,f=x(`span`,ge,``);a&&l(f,a.state,a.text);let m=x(`div`,`min-h-0 flex-1 overflow-auto`),h=i.startsWith(`/`);if(t.pane.replaceChildren(t.paneBar(u.name,r(ye(c.source),Q),r(u.kind,Q),x(`span`,`ml-auto flex flex-wrap items-center gap-2`,x(`span`,`font-mono text-[11px] text-neutral-400 break-all`,u.path),...h?[v(Se(i),b(i))]:[])),x(`div`,`flex flex-none flex-col gap-2 border-b border-neutral-200 px-4 py-3`,S(c,u,`Enabled`,T(c,u),r=>{t.live(o)&&E(e,n,i,r)}),...u.state?[x(`p`,`text-[12px] text-amber-700`,u.state)]:[],f),m),i.startsWith(`<inline:`)){m.append(x(`p`,`px-4 py-3 text-[12.5px] text-neutral-400`,`Loaded from inside Pier — there is no file to show.`));return}let g=await O(i);if(!t.live(o))return;if(!g.ok)return m.append(x(`p`,`px-4 py-3 text-[12.5px] text-red-600`,g.error));let _=await j(i);t.live(o)&&m.append(V(I(g.value),_))}async function O(t){let n=`/api/fs/file?root=${encodeURIComponent(Se(t))}&path=${encodeURIComponent(b(t))}`,r;try{r=await fetch(n,{cache:`no-store`})}catch(e){return{ok:!1,error:`could not read ${t}: ${String(e)}`}}return r.ok?{ok:!0,value:await r.text()}:{ok:!1,error:await e(r,`could not read ${t}`)}}function k(e,n=``){let r=t.claim(),a=x(`span`,ge,``);e&&l(a,e.state,e.text);let o=n,s=g(n,`npm:@scope/name · git:github.com/owner/repo · /path/to/package`,e=>o=e,!0),u=q(`Install`,`btn btn-primary text-[12.5px]`),d=()=>{let e=o.trim();if(!e)return l(a,`failed`,`A package source is required.`);u.disabled=!0,l(a,`saving`,`installing ${e}…`),i&&(i={...i,busy:e,packages:[...i.packages,{source:e,kind:be(e),scope:`global`,version:null,installedPath:null,updateAvailable:!1,resources:[]}]},t.changed()),R(`/api/packages`,{source:e},`install failed`).then(async n=>{if(await c(),t.changed(),!t.live(r))return;if(!n.ok)return k({state:`failed`,text:n.error},e);let{package:i}=n.value;t.select({type:`package`,source:i.source,scope:i.scope}),w(i.source,i.scope,{state:`saved`,text:`Installed ${i.source} — sessions take it on their next message.`})})};u.onclick=d,s.onkeydown=e=>{e.key===`Enter`&&d()},t.pane.replaceChildren(t.paneBar(`Add package`),h(x(`div`,`flex max-w-2xl flex-col gap-3`,F(`Source`,s,{hint:"What `pi install` takes: an npm package, a git URL (both may pin @version), or a directory on this machine."}),x(`p`,`text-[12.5px] leading-relaxed text-amber-800`,ve),x(`div`,`flex items-center gap-3`,u,a)))),s.focus()}return{get registry(){return i},get error(){return a},load:c,openPackage:w,openResource:E,openAdd:k}}async function we(t,n){let r;try{r=await N(`/api/settings`,t,`PUT`)}catch(e){return{outcome:{state:`failed`,text:`Could not save: ${String(e)}`}}}if(!r.ok)return{outcome:{state:`failed`,text:await e(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 Te(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 Ee(t,i,a){let o=`global`,c=null,u=0,d=0,f=``,p=()=>f?`Global (${f})`:`Global`,h=null,_=[],v=``,y=null,C=null,w=()=>{C?.dispose(),C=null},O=()=>{w(),++d,C=he(),H.replaceChildren(C.el)},M=[],P=e=>e.custom===!0,ee=x(`span`,`min-w-0 flex-1 truncate`),L=x(`button`,`${K} flex items-center gap-1.5`,ee,W(k,`h-3.5 w-3.5 text-neutral-500`));L.setAttribute(`aria-haspopup`,`true`),L.onclick=()=>{if(L.getAttribute(`aria-expanded`)===`true`)return ne();T(L,[{label:p(),checked:o===`global`,onSelect:()=>Ee(`global`)},...i().map(e=>({label:e,hint:b(e),checked:o===e,onSelect:()=>Ee(e)}))],`Scope`)};let R=x(`div`,`${A} flex-col items-stretch gap-1.5 px-3 py-2.5`);R.append(x(`span`,`field-label`,`Scope`),L);let z=x(`div`,`min-h-0 flex-1 overflow-y-auto py-1.5`),B=x(`nav`,`${re} w-64 flex-none text-[13px] leading-5 max-md:max-h-48 max-md:w-full`);B.append(R,z);let H=x(`div`,`${re} min-w-0 flex-1`),te=x(`div`,`flex min-h-0 flex-1 gap-3 px-4 pb-4 pt-1 max-md:flex-col`);te.append(B,H),t.append(te);let U=(e,...t)=>x(`div`,`${A} flex-wrap gap-3 px-4 py-2.5`,x(`span`,`font-mono text-[12.5px] text-neutral-500`,e),...t),G=Ce({pane:H,paneBar:U,claim:()=>++d,live:e=>e===d,cwd:()=>o===`global`?void 0:o,changed:()=>Z(h),browse:a,select:e=>{c=e,e?.type===`resource`&&ue.set(e.source,!0),Z(h)}}),J=(e=``)=>`?scope=${encodeURIComponent(o)}${e}`;async function ie(){if(o!==`global`){_=[],v=``;return}let e=await D(`/api/settings`,`could not be loaded`,{cache:`no-store`});if(!e.ok){_=[],v=e.error;return}ae(e.value),v=``}function ae(e){_=e.catalog,M=e.customTools,y=e.toolsTaskId}async function oe(e,t){let{outcome:n,answer:r}=await we(e,t);return r&&(ae(r),Z(h)),n}async function se(){let e=++u;d++;let[t]=await Promise.all([D(`/api/config${J()}`,`failed to load config`,{cache:`no-store`}),ie(),G.load()]);if(e!==u)return;if(!t.ok){Z(null),me(t.error);return}let n=t.value;o===`global`&&n.dir&&(f=n.dir,De()),h=n,Z(n),c?c.type===`sync`&&O():pe()}function Y(e,t){return x(`div`,`flex items-center justify-between gap-2 px-3 pb-1 pt-3 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,x(`span`,``,e),...t?[t]:[])}let ce=e=>x(`span`,`flex-none rounded bg-neutral-100 px-1 text-[10px] font-semibold uppercase tracking-wide text-neutral-500`,e),le=()=>x(`span`,`flex-none rounded bg-emerald-50 px-1 text-[10px] font-semibold uppercase tracking-wide text-emerald-700`,`on`);function X(e,t,n,r,i={}){let a=x(`button`,`config-row flex w-full cursor-pointer items-center gap-1.5 py-1.5 pr-3 text-left transition-colors hover:bg-neutral-100 ${t?`bg-indigo-50 font-medium hover:bg-indigo-50`:``} ${n?`text-neutral-400`:``}`),o=x(`span`,`truncate`,e);if(i.note){let e=x(`span`,`truncate text-[11px] font-normal leading-4 text-amber-700`,i.note);e.title=i.note,a.append(x(`span`,`flex min-w-0 flex-1 flex-col`,o,e))}else a.append(o);return a.append(...i.tags??[]),a.style.paddingLeft=`${i.flush?0:20+(i.depth??0)*14}px`,a.title=e,a.onclick=r,a}let ue=new Map,de=e=>ue.get(e.source)??(e.kind===`pier`||e.kind===`local`);function fe(e,t,n){let r={type:`package`,source:e.source,scope:e.scope},i=[];G.registry?.busy===e.source?i.push(x(`span`,`flex-none text-[11px] text-neutral-400`,e.installedPath?`updating…`:`installing…`)):e.resources.some(e=>e.enabled)&&i.push(le()),e.scope===`project`&&i.push(ce(`project`));let a=e.installedPath===null&&!xe(e),o=de(e),s=x(`button`,`flex w-5 flex-none cursor-pointer items-center justify-center self-stretch text-neutral-500 hover:bg-neutral-100`,W(E,`chev h-3 w-3`));o&&s.classList.add(`chev-open`),s.title=`${o?`Collapse`:`Expand`} ${ye(e.source)}`,s.setAttribute(`aria-label`,s.title),s.setAttribute(`aria-expanded`,String(o)),s.onclick=()=>{ue.set(e.source,!o),Z(h)};let c=X(ye(e.source),t(r),a,()=>n(r),{tags:i,flush:!0}),l=[x(`div`,`flex items-stretch ${t(r)?`bg-indigo-50`:``}`,s,c)];if(!o)return l;let u=e.resources.map(e=>e.name),d=new Set(u.filter((e,t)=>u.indexOf(e)!==t));for(let[r,i]of[[`extensions`,`extension`],[`skills`,`skill`]]){let a=e.resources.filter(e=>e.kind===i);if(!a.length)continue;let o=x(`div`,`py-0.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,r);o.style.paddingLeft=`34px`,l.push(o);for(let r of a){let a={type:`resource`,source:e.source,kind:i,path:r.path};l.push(X(r.name,t(a),!r.enabled,()=>n(a),{depth:2,note:r.state,tags:d.has(r.name)?[ce(i)]:[]}))}}return l}function Z(e){if(!e){z.replaceChildren();return}let t=e=>JSON.stringify(e)===JSON.stringify(c),n=t=>{w(),c=t,Z(e),t.type===`file`?ge(t.name,t.readonly):t.type===`tools`?be():t.type===`sync`?O():t.type===`package`?G.openPackage(t.source,t.scope):t.type===`resource`?G.openResource(t.source,t.kind,t.path):G.openAdd()},r=[];if(o===`global`){let e={type:`sync`};r.push(Y(`Instance`),X(`Configuration sync`,t(e),!1,()=>n(e)))}r.push(Y(`Files`));for(let i of e.files){let e={type:`file`,name:i.name,readonly:i.readonly};r.push(X(i.name,t(e),!i.exists,()=>n(e)))}let i={type:`add`},a=q(`Add package`,`normal-case tracking-normal hover:underline ${t(i)?`text-indigo-700`:`text-indigo-600`}`);a.onclick=()=>n(i),r.push(Y(`Packages`,o===`global`?a:void 0)),G.error&&r.push(x(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-red-600`,G.error));for(let e of G.registry?.packages??[])r.push(...fe(e,t,n));if(o===`global`){if(r.push(Y(`Tools`)),v)r.push(x(`p`,`py-1 pl-5 pr-3 text-[12.5px] text-red-600`,v));else{let e={type:`tools`},i=_.filter(e=>e.enabled).length;r.push(X(`command-line tools`,t(e),!1,()=>n(e),{tags:i?[le()]:[]}))}}z.replaceChildren(...r)}function pe(){H.replaceChildren(x(`div`,`flex min-h-0 flex-1 items-center justify-center p-6`,m(`Select a file to edit, or a package, extension or skill to switch.`)))}function me(e){H.replaceChildren(x(`p`,`px-4 py-3 text-[12.5px] leading-relaxed text-red-600`,e))}async function ge(t,n){let r=++d,i=await D(`/api/config/files/${encodeURIComponent(t)}${J()}`,`failed to load ${t}`,{cache:`no-store`});if(!i.ok){r===d&&me(i.error);return}if(r!==d)return;let{content:a}=i.value,o=a,s=x(`span`,`text-[11.5px] text-neutral-400`,``),c=x(`button`,`btn btn-primary 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=a;let f=async()=>{if(c.disabled)return;let n=u.value;c.disabled=!0,l(s,`saving`,`saving…`);try{let r=await N(`/api/config/files/${encodeURIComponent(t)}${J()}`,{content:n,expected:o},`PUT`);if(!r.ok)return l(s,`failed`,await e(r,`save failed`));let i=await r.json();o=i.content,u.value===n?(u.value=i.content,l(s,`saved`,`saved — applies to new sessions`)):l(s,`idle`,`saved; newer changes are unsaved`)}catch(e){l(s,`failed`,`save failed: ${String(e)}`)}finally{c.disabled=!1}},p=x(`button`,`btn text-[12.5px]`,`Edit`),m=x(`button`,`btn text-[12.5px]`,`View`),h=(...e)=>x(`div`,`ml-auto flex flex-none items-center gap-2`,...e),g=()=>{H.replaceChildren(U(t,s,h(m,c)),u),u.focus()},_=async()=>{let e=await j(t);r===d&&H.replaceChildren(n?U(t,x(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,`read-only`)):U(t,s,h(p)),...n?[x(`p`,`border-b border-neutral-200 px-4 py-2 text-[12.5px] leading-relaxed text-neutral-500`,`Pier manages this file: the default model is set in Settings → Models; other keys are edited on disk, then pier reload.`)]:[],x(`div`,`min-h-0 flex-1 overflow-auto`,V(I(u.value),e)))};p.onclick=g,m.onclick=()=>void _(),c.onclick=()=>void f(),u.onkeydown=e=>{(e.metaKey||e.ctrlKey)&&e.key===`s`&&(e.preventDefault(),f())},u.oninput=()=>{l(s,`idle`,`unsaved changes`)},await _()}function Q(e){if(!y)return null;let t=x(`a`,`text-indigo-600 hover:underline`,e);return t.href=`#/tasks/${encodeURIComponent(y)}`,t}let _e=()=>{let e=x(`a`,`text-indigo-600 hover:underline`,`ubix`);return e.href=`https://github.com/timqi/ubix`,e.target=`_blank`,e.rel=`noreferrer`,e};function ve(e){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 be(e,t={name:``,toml:``}){d++;let i=x(`span`,`text-[11.5px] text-neutral-400`,``);e&&l(i,e.state,e.text);let a=Q(`the update task`),o=e=>{let t=x(`div`,`flex min-w-0 flex-1 flex-col gap-0.5`,x(`span`,`flex items-center gap-2 text-[13px] text-neutral-700`,x(`span`,`font-mono`,e.name),...P(e)?[r(`yours`,`bg-neutral-50 text-neutral-500 ring-neutral-200`)]:[]),x(`span`,`text-[11.5px] leading-snug text-neutral-400`,e.summary||ve(e)),...e.summary?[x(`span`,`font-mono text-[11px] leading-snug ${e.binary.error?`text-red-600`:`text-neutral-400`}`,ve(e))]:[]),i=n(``,``,e.enabled,t=>void Se(e.name,t,e=>be(e))),a=x(`button`,`btn text-[12px] text-neutral-500 hover:text-red-600`,`Remove`);return a.onclick=()=>{a.disabled=!0;let t=Te(e,M);oe(t.body,t.saved).then(e=>be(e))},x(`div`,`flex max-w-2xl items-start gap-3 border-b border-neutral-100 py-2.5 last:border-0`,t,...P(e)?[a]:[],i)},s={...t},c=x(`span`,`font-mono text-[12px] text-neutral-500`,`[tools.<name>]`),u=g(s.name,`claude`,e=>{s.name=e,c.textContent=`[tools.${e.trim()||`<name>`}]`},!0),f=document.createElement(`textarea`);f.className=`${S} h-24 resize-y font-mono leading-snug`,f.spellcheck=!1,f.value=s.toml,f.placeholder=`spec = "github:owner/repo"
|
|
2
2
|
exe = "tool"`,f.oninput=()=>s.toml=f.value;let p=x(`button`,`btn btn-primary text-[12.5px]`,`Add`);p.onclick=()=>{let e={name:s.name.trim(),toml:s.toml.trim()};if(!e.name||!e.toml)return l(i,`failed`,`A custom tool needs a name and a block with a spec line.`);p.disabled=!0,oe({customTools:[...M,e],tool:{name:e.name,on:!0}},`Added ${e.name} — installing now.`).then(e=>be(e,e.state===`failed`?s:void 0))},H.replaceChildren(U(`command-line tools`,x(`span`,`ml-auto text-[11px] uppercase tracking-wide text-neutral-400`,`installed by Pier`)),x(`div`,`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4`,x(`p`,`max-w-2xl text-[12.5px] leading-relaxed text-neutral-500`,`Pier writes no downloader: `,_e(),` does the work — a declarative installer that resolves a spec like `,x(`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.`),v?x(`p`,`max-w-2xl text-[12.5px] text-red-600`,v):x(`div`,`flex max-w-2xl flex-col`,..._.map(o)),x(`div`,`flex max-w-2xl flex-col gap-2 border-t border-neutral-200 pt-4`,x(`span`,`text-[12.5px] font-medium text-neutral-600`,`Add one of your own`),F(`Name`,u),F(`The block Pier writes under the header`,f,{hint:`A line that opens a section of its own is refused, because it could rewrite the rest of the file.`}),x(`div`,`flex items-center gap-3`,c,p)),x(`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.`]),i))}async function Se(e,t,n){n(await oe({tool:{name:e,on:t}},t?`Saved — installing now; watch the run.`:`Saved — uninstalling in the next run.`))}function Ee(e){ne(),e!==o&&(w(),o=e,c=null,De(),se())}function De(){o!==`global`&&!i().includes(o)&&(o=`global`),ee.textContent=o===`global`?p():b(o),L.title=o===`global`?f:o}return s(t,()=>{De(),se()},w)}var De=`medium`,$=e=>`${e.provider}/${e.id}`,Oe=e=>({model:e.defaultModel,thinking:e.defaultThinkingLevel}),ke=`Off — the first message is the title`,Ae=[`hardest reasoning — architecture, gnarly debugging`,`long autonomous implementation runs`,`balanced default — implementation, review`,`cheap & fast — listings, extraction, simple checks`,`cross-vendor second opinion`];function je(){let t=[],n=[],r=!1,i,s={model:null,thinking:null},c=null,u=x(`span`,`text-[11.5px]`,``),d=x(`span`,`text-[11.5px]`,``),f=x(`div`,`flex items-center gap-3`),p=x(`span`,`text-[11.5px]`,``),h=x(`div`,`flex flex-col gap-1.5`),g=v(`Save menu`,!0),_=x(`div`,`flex min-w-0 flex-col gap-2`),y=x(`div`,`flex items-center gap-2`),b=x(`div`,`mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-6`);function S(){r=!0,l(u,`idle`,`unsaved changes`)}function C(e,n,r,i){let a=t.indexOf(e),o=a+n,s=q(``,`icon-btn max-md:h-11 max-md:w-11 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent`);return s.append(W(r)),s.title=i,s.setAttribute(`aria-label`,`${i}: ${$(e)}`),s.disabled=o<0||o>=t.length,s.onclick=()=>{t.splice(o,0,...t.splice(a,1)),c={at:$(e),step:n},S(),M()},s}function w(e){let n=P(e.note??``);n.classList.remove(`w-full`),n.classList.add(`min-w-0`,`flex-1`),n.placeholder=`why this one — pick a preset or write your own`,n.setAttribute(`list`,`model-menu-notes`),n.oninput=()=>{e.note=n.value,S()};let r=o(z.map(e=>[`thinking: ${B(e)}`,e]),e.thinking);r.classList.replace(`w-full`,`w-44`),r.classList.add(`flex-none`),r.onchange=()=>{e.thinking=r.value,S()};let i=v(`Remove`);i.classList.add(`flex-none`),i.onclick=()=>{t=t.filter(t=>t!==e),S(),M()};let a=x(`span`,`w-52 flex-none truncate font-mono text-[12px] text-neutral-700`,$(e));a.title=$(e);let s=C(e,-1,ae,`Move up`),l=C(e,1,k,`Move down`);if(c?.at===$(e)){let[e,t]=c.step===-1?[s,l]:[l,s];c=null,queueMicrotask(()=>(e.disabled?t:e).focus())}return x(`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`,x(`span`,`flex flex-none items-center`,s,l),a,r,n,i)}function T(){let e=n.filter(e=>!t.some(t=>$(t)===$(e))),r=v(`Pin model`);r.prepend(W(ee)),r.classList.add(`inline-flex`,`items-center`,`gap-1.5`,`flex-none`,`whitespace-nowrap`),r.disabled=e.length===0,r.onclick=()=>{let n=De;O(r,te({models:e,current:null,thinkingLevel:n,thinkingLevels:[...z],onThinkingPick:e=>{n=e},onPick:e=>{ne(),t.push({provider:e.provider,id:e.id,thinking:n}),S(),M()}}))},y.replaceChildren(r)}function E(){let t=i,r=t&&!n.some(e=>$(e)===$(t))?[t,...n]:n,a=q(t?t.id:ke,`${K} flex min-w-0 flex-1 items-center ${t?`text-neutral-700`:`text-neutral-400`}`);t&&(a.title=$(t));let o=t=>{ne(),(async()=>{l(d,`saving`,`saving…`);let n=await N(`/api/settings`,{titleModel:t&&{provider:t.provider,id:t.id}},`PUT`);if(!n.ok)return l(d,`failed`,await e(n,`Could not save`)),E();i=(await n.json()).titleModel,l(d,`saved`,i?`Saved — names the next new session after its first reply.`:`Off.`),E()})()};a.onclick=()=>{let e=te({models:r,current:t,thinkingLevel:`medium`,thinkingLevels:[],onThinkingPick:()=>{},onPick:o}),n=q(ke,`w-full cursor-pointer px-3 py-1.5 text-left text-[12.5px] text-neutral-500 hover:bg-neutral-100`);n.onclick=()=>o(null);let i=x(`div`,`flex flex-col`);i.append(e,x(`div`,`border-t border-neutral-200`),n),O(a,i)},f.replaceChildren(a,d)}function A(){h.replaceChildren(L(`Default model`,s,n,e=>void j(e)),p)}async function j(t){l(p,`saving`,`saving…`);let n=await N(`/api/config/defaults`,{defaultModel:t.model,defaultThinkingLevel:t.thinking},`PUT`);if(!n.ok)return l(p,`failed`,await e(n,`Could not save`)),A();s=Oe(await n.json()),l(p,`saved`,s.model||s.thinking?`Saved — the next new session starts on it.`:`Pi default.`),A()}function M(){_.replaceChildren(...t.length?t.map(w):[m(`Nothing pinned — every picker shows the curated catalog as is.`)]),T(),A(),E()}async function I(){l(u,`saving`,`saving…`);let n=t.map(({provider:e,id:t,thinking:n,note:r})=>({provider:e,id:t,thinking:n,...r?.trim()?{note:r.trim()}:{}})),i=await N(`/api/settings`,{modelMenu:n},`PUT`);if(!i.ok)return l(u,`failed`,await e(i,`Could not save`));t=(await i.json()).modelMenu,r=!1,l(u,`saved`,`Saved — agents see it on their next models call.`),M()}g.onclick=()=>void I();function R(){r||(async()=>{let[e,r,a]=await Promise.all([D(`/api/settings`,`Could not load the menu`),D(`/api/models`,`Could not load the model catalog`),D(`/api/config/defaults`,`Could not read the default model`)]);if(!e.ok)return l(u,`failed`,e.error);t=e.value.modelMenu,i=e.value.titleModel,n=r.ok?r.value:[],a.ok?(s=Oe(a.value),p.textContent=``):l(p,`failed`,a.error),u.textContent=``,M()})()}let V=x(`datalist`,``);return V.id=`model-menu-notes`,V.append(...Ae.map(e=>new Option(e))),b.append(a(`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.`,F(`Pinned models`,_,{hint:"The note is what an agent matches a task against — say when to reach for it, not what it is, and keep every note distinct: two pins reading alike are refused as ambiguous. The arrows set the order pickers and `pier task --model ?` list."}),F(`Add`,y,{hint:`The list is the live catalog — only models that exist right now can be pinned.`}),x(`div`,`flex items-center gap-3`,g,u),V),a(`New sessions`,`The model and reasoning effort a session starts on when nothing names one — a channel, chat or task with its own launch choice overrides it. Pi default leaves the pick to Pi. Stored in settings.json; applies to sessions opened from now on.`,h),a(`Session titles`,`A session is titled by its first message unless a model names it: one short request after the first reply, on the model picked here — a small, cheap one is plenty. A failed request is reported in the session and the first message stays the title.`,F(`Title model`,f))),{el:b,load:R}}var Me=e=>Uint8Array.from(atob(e.replace(/-/g,`+`).replace(/_/g,`/`)),e=>e.charCodeAt(0)),Ne=e=>btoa(String.fromCharCode(...new Uint8Array(e))).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``);function Pe(){let t=x(`div`,`flex flex-col gap-2`),n=x(`span`,`text-[11.5px]`,``),r=P();r.placeholder=`Label, e.g. MacBook Touch ID`,r.autocomplete=`off`,r.maxLength=80;let o=v(`Add a passkey`,!0),s=x(`div`,`flex flex-wrap items-center gap-3`,r,o,n),c=x(`p`,`hidden text-[12.5px] leading-snug text-neutral-600`),u=x(`p`,`hidden text-[12px] text-neutral-400`);function d(e){if(u.textContent=e.reason??``,u.classList.toggle(`hidden`,e.enabled),s.classList.toggle(`hidden`,!e.enabled),c.textContent=`Password sign-in is off while a passkey is registered; remove every passkey to turn it back on.`,c.classList.toggle(`hidden`,!e.passkeys.length),!e.passkeys.length){t.replaceChildren(m(`No passkey is registered.`));return}t.replaceChildren(...e.passkeys.map(e=>{let t=v(`Remove`);t.onclick=()=>{t.disabled=!0,(async()=>{let t=await U(`/api/passkeys/${encodeURIComponent(e.id)}`,`DELETE`,`Could not remove it`);t?l(n,`failed`,t):l(n,`saved`,`Removed.`),await p()})()};let r=e.lastUsedAt?`last used ${y(e.lastUsedAt)}`:`never used`,a=e.transports.length?` · ${e.transports.join(`, `)}`:``;return i(e.label,`added ${y(e.createdAt)} · ${r}${a}`,t)}))}async function f(){if(!window.PublicKeyCredential)return l(n,`failed`,`This browser has no passkey support.`);o.disabled=!0,l(n,`saving`,`asking this browser…`);try{let t=await R(`/api/passkeys/register/options`,{},`Could not start`);if(!t.ok)return l(n,`failed`,t.error);let i={...t.value,challenge:Me(t.value.challenge),user:{...t.value.user,id:Me(t.value.user.id)},excludeCredentials:t.value.excludeCredentials.map(e=>({...e,id:Me(e.id),transports:e.transports}))},a=await navigator.credentials.create({publicKey:i});if(!a)return l(n,`failed`,`No passkey was created.`);let o=a.response,s=await N(`/api/passkeys/register/verify`,{id:a.id,type:a.type,label:r.value,response:{clientDataJSON:Ne(o.clientDataJSON),attestationObject:Ne(o.attestationObject),transports:o.getTransports?.()??[]}});if(!s.ok)return l(n,`failed`,await e(s,`Could not register it`));r.value=``,d(await s.json()),l(n,`saved`,`Added. The password is off until every passkey is removed.`)}catch(e){let t=e instanceof DOMException&&e.name===`NotAllowedError`;l(n,`failed`,t?`The prompt was dismissed or timed out.`:`Could not add it: ${String(e)}`)}finally{o.disabled=!1}}o.onclick=()=>void f();async function p(){let e=await D(`/api/passkeys`,`Could not load passkeys`);return e.ok?(d(e.value),e.value.passkeys.length>0):(t.replaceChildren(m(e.error)),!1)}return{el:a(`Passkeys`,`Sign in with Touch ID, Windows Hello, a phone or a security key instead of the password. Bound to the public URL's host.`,t,c,u,s),load:p}}var Fe=(e,t)=>{let n;try{n=new URL(e)}catch{return null}if(n.protocol!==`http:`&&n.protocol!==`https:`)return null;let r=x(`a`,`text-indigo-600 hover:underline`,t);return r.href=n.href,r.target=`_blank`,r.rel=`noreferrer`,r};function Ie(t,n,r,i){let a=document.createElement(`dialog`);a.className=`m-auto w-[min(32rem,92vw)] rounded-lg border border-neutral-200 bg-white p-0 shadow-xl backdrop:bg-black/30`;let o=x(`div`,`flex flex-col gap-2`),s=x(`div`,`flex flex-col gap-2`),c=x(`p`,`text-[12.5px] text-neutral-400`,`Starting…`),l=v(`Cancel`),d=(e,t)=>{c.className=`text-[12.5px] ${_[e]}`,c.textContent=t};a.append(x(`div`,`border-b border-neutral-200 px-4 py-2.5 text-[14px] font-semibold`,n),x(`div`,`flex max-h-[65vh] flex-col gap-3 overflow-y-auto px-4 py-3`,o,s,c),x(`div`,`flex justify-end border-t border-neutral-200 px-4 py-2.5`,l)),document.body.append(a),a.showModal();let f=t.id,p=t.state,m,h,g=new Set,y=!1,b=!1,S=async t=>{if(!b){if(t&&p===`running`){b=!0,l.disabled=!0;try{let t=await N(`/api/providers/flows/${f}/cancel`,{});if(!t.ok&&t.status!==404){d(`failed`,await e(t,`Could not cancel authentication flow`));return}}catch(e){d(`failed`,`Could not cancel authentication flow: ${String(e)}`);return}finally{b=!1,l.disabled=!1}}clearTimeout(m),a.close()}};l.onclick=()=>void S(!0),a.oncancel=e=>{e.preventDefault(),S(!0)},a.onclose=()=>{y=!0,clearTimeout(m),a.remove()};let C=e=>{if(e.type===`auth_url`){let t=x(`div`,`flex flex-col gap-1 text-[12.5px] text-neutral-600`);return e.instructions&&t.append(x(`p`,``,e.instructions)),t.append(Fe(e.url,`Open authorization page`)??x(`span`,`text-red-600`,`Invalid authorization URL`)),t}if(e.type===`device_code`){let t=x(`div`,`flex flex-col gap-2 text-[12.5px] text-neutral-600`);return t.append(x(`div`,`flex items-center gap-2`,x(`code`,`font-mono text-[17px] font-semibold text-neutral-800`,e.userCode),u(`btn text-[11px]`,()=>e.userCode))),t.append(Fe(e.verificationUri,`Open verification page`)??x(`span`,`text-red-600`,`Invalid verification URL`)),t}let t=x(`div`,`text-[12.5px] text-neutral-600`,e.message);if(e.type===`info`)for(let n of e.links??[]){let e=Fe(n.url,n.label??n.url);e&&t.append(` `,e)}return t},w=(t,n)=>{h=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=P(``,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=v(`Continue`,!0);i.type=`submit`;let a=x(`form`,`flex flex-col gap-2`,x(`label`,`text-[12.5px] font-medium text-neutral-700`,n.message),r,x(`div`,`flex justify-end`,i));a.onsubmit=a=>{a.preventDefault(),i.disabled=!0,(async()=>{try{let i=await N(`/api/providers/flows/${t.id}/respond`,{promptId:n.id,value:r.value});if(y)return;if(!i.ok){d(`failed`,await e(i,`Could not submit response`));return}g.add(n.id),h=void 0,s.replaceChildren(),d(`saving`,`Waiting for provider…`)}catch(e){y||d(`failed`,`Could not submit response: ${String(e)}`)}finally{i.disabled=!1}})()},s.replaceChildren(a),r.focus()},T=e=>{p=e.state,o.replaceChildren(...e.events.map(C));let t=e.prompt&&!g.has(e.prompt.id)?e.prompt:void 0;if(t?.id!==h&&(t?w(e,t):(h=void 0,s.replaceChildren())),e.state===`running`){d(`saving`,t?`Waiting for your response.`:`Waiting for provider…`);return}clearTimeout(m),s.replaceChildren(),e.state===`succeeded`?d(`saved`,`${r} configured.`):d(`failed`,e.state===`cancelled`?`Cancelled.`:e.error??`Authentication failed.`),l.textContent=`Close`,l.onclick=()=>void S(!1),e.state===`succeeded`&&i()},E=async()=>{if(!(y||p!==`running`))try{let t=await fetch(`/api/providers/flows/${f}`,{cache:`no-store`});if(y)return;if(!t.ok){d(`failed`,await e(t,`Authentication status unavailable`)),t.status===404?p=`failed`:m=setTimeout(()=>void E(),1e3);return}T(await t.json()),p===`running`&&(m=setTimeout(()=>void E(),500))}catch(e){if(y)return;d(`failed`,`Authentication status unavailable: ${String(e)}`),m=setTimeout(()=>void E(),1e3)}};T(t),p===`running`&&(m=setTimeout(()=>void E(),500))}var Le=[`anthropic`,`openai`,`openai-codex`,`google`,`openrouter`,`deepseek`],Re=[[`OpenAI Chat Completions`,`openai-completions`],[`OpenAI Responses`,`openai-responses`],[`Anthropic Messages`,`anthropic-messages`],[`Google Generative AI`,`google-generative-ai`]],ze=`__custom__`;async function Be(t){let n=v(`Add provider`,!0);n.classList.add(`ml-auto`);let i=x(`div`,`flex flex-none items-center gap-3 rounded-t-3xl ${J} px-4 py-2`,x(`h2`,`text-[13px] font-semibold text-neutral-700`,`Providers`),n),a=x(`div`,`min-h-0 flex-1 overflow-y-auto`);t.replaceChildren(i,a);let s=[],c=``,u=async()=>{a.replaceChildren(x(`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(s=t.ok?t.value:[],c=t.ok?``:t.error,!e.ok){a.replaceChildren(m(e.error));return}let r=e.value;n.onclick=()=>He(r,void 0,u),g(r)}catch(e){a.replaceChildren(m(`Could not load providers: ${String(e)}`))}},d=async t=>{if(window.confirm(`Remove the stored credential for ${t.name}?`))try{let n=await N(`/api/providers/${encodeURIComponent(t.id)}/logout`,{});if(!n.ok){window.alert(await e(n,`Could not remove credential`));return}await u()}catch(e){window.alert(`Could not remove credential: ${String(e)}`)}},f=e=>[...new Set([...(e.models??[]).map(e=>e.id),...s.filter(t=>t.provider===e.id).map(e=>e.id)])],p=(e,t)=>x(`div`,`flex flex-col gap-1`,x(`span`,`text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),x(`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(t,n)=>{try{let r=await N(`/api/providers/${encodeURIComponent(t)}/check`,{model:n});return r.ok?await r.json():await e(r,`Could not test`)}catch(e){return`Could not test: ${String(e)}`}},g=e=>{let t=e.filter(e=>e.configured);if(!t.length){a.replaceChildren(m(`No providers configured.`));return}a.replaceChildren(...t.map(t=>{let n=x(`div`,`min-w-0 flex-1`,x(`div`,`truncate text-[13px] font-medium text-neutral-700`,t.name),x(`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=x(`div`,`flex min-w-32 flex-col items-start gap-1`,r(`configured`,`bg-emerald-50 text-emerald-700 ring-emerald-200`),x(`span`,`max-w-48 truncate text-[11px] text-neutral-500`,i),x(`span`,`max-w-48 truncate text-[11px] text-neutral-400`,a));s.title=a;let m=x(`span`,`text-[11.5px]`,``),g=x(`div`,`hidden flex-col gap-2 px-4 pb-3`,m),_=x(`div`,`flex flex-wrap justify-end gap-1.5`),y=f(t);if(!y.length)l(m,`idle`,c||`No models to test: none are configured here.`),g.classList.replace(`hidden`,`flex`);else{let e=o([[`Model to test…`,``],...y.map(e=>[e,e])],``);e.classList.add(`max-w-52`,`text-[12px]`);let n=v(`Test`);n.disabled=!0,e.onchange=()=>n.disabled=!e.value,n.onclick=()=>{let r=e.value;n.disabled=!0,g.replaceChildren(m),g.classList.replace(`hidden`,`flex`),l(m,`saving`,`asking ${r}…`),h(t.id,r).then(e=>{if(n.disabled=!1,typeof e==`string`)return l(m,`failed`,e);l(m,e.ok?`saved`:`failed`,`${e.model} ${e.ok?`answered`:`did not answer`} in ${e.ms} ms`),g.append(p(`sent`,e.request||`(the request was never made)`),p(e.ok?`answered`:`replied`,e.response))})},_.append(e,n)}if(t.builtin||t.api&&t.models){let n=v(`Edit`);n.onclick=()=>He(e,t,u),_.append(n)}if(t.stored){let e=v(`Remove credential`);e.onclick=()=>void d(t),_.append(e)}return x(`div`,`border-b border-neutral-100`,x(`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]`,n,s,_),g)}))};await u()}function Ve(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`,Le.flatMap(e=>n.filter(t=>t.id===e))),r(`More providers`,n.filter(e=>e.builtin&&!Le.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…`,ze))}function He(t,n,r){let i=document.createElement(`dialog`);i.className=`m-auto w-[min(32rem,92vw)] rounded-lg border border-neutral-200 bg-white p-0 shadow-xl backdrop:bg-black/30`;let a=document.createElement(`select`);a.className=`${S} select`,n||Ve(a,t);let s=P(),c=P(),l=P(),u=document.createElement(`select`);u.className=`${S} select`,u.append(...Re.map(([e,t])=>new Option(e,t)));let d=ie(``,4);d.placeholder=`model-id
|
|
3
3
|
another-model-id`;let f=document.createElement(`input`);f.type=`checkbox`;let p=o([[`Up to High`,`high`],[`Up to Extra high`,`xhigh`],[`Up to Max`,`max`]],`high`);p.classList.replace(`w-full`,`w-48`),f.onchange=()=>{p.disabled=!f.checked};let m=document.createElement(`select`);m.className=`${S} select`;let h=x(`div`,`flex flex-col gap-4`),g=x(`span`,`text-[11.5px] text-red-600`,``),_=v(`Cancel`),y=v(n?`Save`:`Add`,!0);y.type=`submit`;let b=()=>n??t.find(e=>e.id===a.value),C=()=>{let e=b(),t=e?!e.builtin:a.value===ze;s.value=e?.id??``,s.disabled=n!==void 0,c.value=e?.name??``,l.value=e?.endpoint??``,u.value=e?.api??`openai-completions`,d.value=e?.models?.map(e=>e.id).join(`
|
|
4
4
|
`)??``;let r=e?.models?.map(e=>e.reasoning)??[];f.checked=r.length?r.every(Boolean):!e,f.indeterminate=r.some(Boolean)&&!r.every(Boolean);let i=new Set((e?.models??[]).filter(e=>e.reasoning).map(e=>e.effort??`high`)),o=i.size>1;p.replaceChildren(...o?[new Option(`Keep as configured`,``)]:[],new Option(`Up to High`,`high`),new Option(`Up to Extra high`,`xhigh`),new Option(`Up to Max`,`max`)),p.value=o?``:[...i][0]??`high`,p.disabled=!f.checked&&!f.indeterminate;let g=[];e?.configured&&g.push(new Option(`Keep current authentication`,``));let _=e?.methods??[{type:`api_key`,name:`API key`}];for(let t of _.filter(t=>e?.builtin!==!1||t.type===`api_key`))g.push(new Option(t.name,t.type));m.replaceChildren(...g);let v=[];n||v.push(F(`Provider`,a)),t?v.push(F(`Provider ID`,s),F(`Display name`,c),F(`Endpoint`,l),F(`API format`,u),F(`Models`,d),F(`Model capabilities`,x(`div`,`flex flex-wrap items-center gap-3`,x(`label`,`flex items-center gap-2 text-[12.5px] text-neutral-600`,f,x(`span`,``,`Reasoning`)),p),{hint:`Extra high and Max reach the model only if it accepts them; every reasoning model has High.`})):(l.placeholder=`Provider default`,v.push(F(`Endpoint`,l))),v.push(F(`Authentication`,m)),h.replaceChildren(...v)};a.onchange=C,C();let w=x(`form`,`flex flex-col gap-4 px-4 py-3`,h,x(`div`,`flex items-center justify-end gap-2`,g,_,y)),T=!1;_.onclick=()=>{T||i.close()},i.oncancel=e=>{T&&e.preventDefault()},w.onsubmit=t=>{if(t.preventDefault(),T)return;g.textContent=``;let n=b(),o=(n?!n.builtin:a.value===ze)?{kind:`custom`,id:s.value.trim(),...c.value.trim()?{name:c.value.trim()}:{},endpoint:l.value.trim(),api:u.value,models:[...new Set(d.value.split(`
|
|
Binary file
|
|
Binary file
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{C as e,J as t,O as n,T as r,V as i,Y as a,dt as o,et as s,st as c}from"./index-
|
|
1
|
+
import{C as e,J as t,O as n,T as r,V as i,Y as a,dt as o,et as s,st as c}from"./index-CzV2cZEH.js";var l=e=>e===null?`-`:new Date(e).toLocaleString(),u=e=>e.startedAt===null?`-`:t((e.finishedAt??Date.now())-e.startedAt),d=e=>e.state===`succeeded`&&e.matched===!1?`No match`:e.state,f={queued:`bg-neutral-100 text-neutral-600 ring-neutral-200`,running:`bg-sky-50 text-sky-700 ring-sky-200`,succeeded:`bg-emerald-50 text-emerald-700 ring-emerald-200`,failed:`bg-red-50 text-red-700 ring-red-200`,cancelled:`bg-amber-50 text-amber-700 ring-amber-200`,interrupted:`bg-amber-50 text-amber-700 ring-amber-200`,skipped:`bg-neutral-100 text-neutral-600 ring-neutral-200`};function p(t){let n=d(t);return e(n,n===`No match`?f.skipped:f[t.state],t.state===`running`?`animate-pulse bg-sky-500`:void 0)}function m(t){return t.archived?e(`Archived`,`bg-neutral-50 text-neutral-400 ring-neutral-200`):t.trigger.type===`manual`?e(`Manual`,`bg-neutral-100 text-neutral-600 ring-neutral-200`):t.enabled?e(`Enabled`,`bg-emerald-50 text-emerald-700 ring-emerald-200`):e(`Paused`,`bg-amber-50 text-amber-700 ring-amber-200`)}var h=`px-4 pt-4 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,g=`m-4 mt-2 whitespace-pre-wrap break-words rounded-lg border border-black/[0.06] bg-black/[0.025] px-3 py-2 font-mono text-[12px] leading-snug dark:border-neutral-200 dark:bg-neutral-100`,_=e=>e.trigger.type===`manual`?`Manual`:e.trigger.type===`cron`?`${e.trigger.expression} (${e.trigger.timezone})`:`Every ${e.trigger.intervalSeconds}s · ${e.trigger.mode}`,v=e=>e.action.type===`agent`?`Agent · ${e.action.session.mode}`:e.action.type===`bash`?`Bash`:e.action.type===`system`?`System`:`Task`;function y(e,t){let n=a(`div`,`grid max-w-4xl grid-cols-[6rem_minmax(0,1fr)] gap-x-5 gap-y-3.5 p-4 text-[13px] md:grid-cols-[9.375rem_minmax(0,1fr)]`),i=[[`Status`,e.archived?`Archived`:e.trigger.type===`manual`?`Manual`:e.enabled?`Enabled`:`Paused`],[`Trigger`,_(e)],[`Action`,v(e)],[`Timeout`,`${e.timeoutSeconds}s`],[`Next run`,l(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`&&(i.push([`Session policy`,e.action.session.mode]),e.action.session.mode===`reuse`&&i.push([`Session`,e.action.session.sessionId]),`cwd`in e.action.session&&i.push([`Directory`,e.action.session.cwd]),e.action.launch?.model&&i.push([`Model`,`${e.action.launch.model.provider}/${e.action.launch.model.id}`]),e.action.launch?.thinking&&i.push([`Thinking`,e.action.launch.thinking]),i.push([`Prompt`,e.action.prompt])),e.action.type===`bash`&&i.push([`Directory`,e.action.cwd],[`Script`,e.action.script]),e.action.type===`task`&&i.push([`Target task`,e.action.taskId]),e.action.type===`system`&&i.push([`System action`,e.action.name]),e.trigger.type===`watch`&&i.push([`Probe`,e.trigger.script]);for(let[e,t]of i)n.append(a(`span`,`pt-px text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),a(`pre`,`whitespace-pre-wrap break-words font-mono text-[12.5px] leading-snug`,t));if(e.action.type===`agent`&&e.action.session.mode===`reuse`){let{sessionId:i}=e.action.session,o=r(`Open session`);o.onclick=()=>t(i),n.append(a(`span`,``,``),o)}return n}function b(e){return[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 x(e,t,r,i){let o=a(`div`,`divide-y divide-neutral-100`);for(let e of t){let t=a(`button`,`grid w-full cursor-pointer grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 gap-y-1 px-4 py-2.5 text-left text-[12.5px] transition-colors hover:bg-neutral-50 md:grid-cols-[7.5rem_minmax(0,1fr)_7.5rem_6.25rem]`);t.setAttribute(`type`,`button`),t.append(a(`span`,`flex`,p(e)),a(`span`,`truncate text-neutral-500`,l(e.queuedAt)),a(`span`,`text-neutral-500`,e.triggerSource),a(`span`,`text-right font-mono text-[11.5px] text-neutral-400`,u(e))),t.onclick=()=>r(e.id),o.append(t)}t.length||o.append(a(`div`,`p-4`,n(`No runs yet.`))),e.replaceChildren(o),e.scrollTop=i.top,e.onscroll=()=>{i.top=e.scrollTop}}var S=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 C(e,t,n,d,f){let m=String(Number(e.dataset.runRequest??0)+1);e.dataset.runRequest=m,e.onscroll=()=>{f.scrollTop=e.scrollTop};let _=r(`Runs`);_.className=`cursor-pointer text-neutral-500 hover:text-neutral-800 hover:underline`,_.onclick=()=>{f.selectedId=null,f.scrollTop=0,n()};let v=i(_,c(o,`h-3.5 w-3.5 text-neutral-400`),a(`span`,`min-w-0 truncate font-mono text-[12px] text-neutral-500`,t)),C=e.dataset.runId!==t;C&&(e.dataset.runId=t,e.replaceChildren(v,a(`p`,`p-4 text-[13px] text-neutral-500`,`Loading run...`)));let[w,T]=await Promise.all([s(`/api/task-runs/${t}`,`Could not load the run`),s(`/api/task-runs/${t}/messages`,`Could not load the run's messages`)]);if(!e.isConnected||e.dataset.runRequest!==m||f.selectedId!==t)return;if(!w.ok){let n=await s(`/api/task-groups/${t}`,w.error);if(!e.isConnected||e.dataset.runRequest!==m||f.selectedId!==t)return;if(f.drawn=``,!n.ok){e.replaceChildren(v,a(`p`,`p-4 text-[13px] text-red-600`,w.error));return}let{group:r,members:i}=n.value,o=a(`div`,`min-w-0`);e.replaceChildren(v,a(`div`,`border-b border-neutral-100 bg-neutral-50/60 px-4 py-3 text-[12.5px] text-neutral-600`,[`Task group \u00b7 join ${r.join}`,`${String(i.length)} runs`,r.callbackState?`callback ${r.callbackState}`:``].filter(Boolean).join(` · `)),o),x(o,i,d.openRun,{top:0});return}let E=w.value,D=T.ok?T.value:[],O=JSON.stringify([E,T]);if(!C&&f.drawn===O)return;if(f.drawn=O,E.targetSessionId){let e=r(`Open session`);e.classList.add(`ml-auto`),e.onclick=()=>d.openSession(E.targetSessionId),v.append(e)}if(E.state===`queued`||E.state===`running`){let e=r(`Stop run`);e.onclick=()=>{window.confirm(`Stop this run of "${E.context.definition.name}"?`)&&d.mutate(`/api/task-runs/${E.id}/cancel`)},v.append(e)}let k=a(`div`,`min-w-0`),A=b(E);k.append(a(`div`,`flex flex-wrap items-center gap-x-5 gap-y-2 border-b border-neutral-100 bg-neutral-50/60 px-4 py-3 text-[12.5px]`,a(`span`,`flex items-center gap-2`,p(E),a(`span`,`font-medium`,E.context.definition.name)),...A?[a(`span`,`rounded-md bg-amber-50 px-2 py-0.5 text-[12px] text-amber-700 ring-1 ring-amber-200`,A)]:[],a(`span`,`text-neutral-500`,l(E.queuedAt)),a(`span`,`text-neutral-500`,E.triggerSource),a(`span`,`font-mono text-[11.5px] text-neutral-400`,u(E))));let j=a(`div`,`flex flex-wrap items-center gap-2 border-b border-neutral-100 px-4 py-3 text-[12px]`),M=(e,t)=>{let n=r(e);n.classList.add(`max-w-full`,`break-all`,`!whitespace-normal`),n.onclick=t,j.append(n)};if(E.context.definition.kind===`task`&&M(`Task: ${E.context.definition.name}`,()=>d.openTask(E.taskId)),E.parentRunId&&M(`Parent: ${E.parentRunId}`,()=>d.openRun(E.parentRunId)),E.resumedFromRunId&&M(`Resumed from: ${E.resumedFromRunId}`,()=>d.openRun(E.resumedFromRunId)),E.result?.type===`task`){let e=E.result.runId;M(`Child result: ${e}`,()=>d.openRun(e))}E.groupId&&j.append(a(`span`,`break-all font-mono text-[11.5px] text-neutral-500`,`Group: ${E.groupId}`)),k.append(j);for(let e of[E.error,E.skipReason,E.callbackError])e&&k.append(a(`p`,`m-4 whitespace-pre-wrap break-words rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-[12.5px] text-red-700`,e));if(E.result){let e=E.result,t=e.type===`agent`||e.type===`system`?e.text:e.type===`bash`?S(e):e.type===`task`?`Child run: ${e.runId}`:`Watch did not match.`;k.append(a(`h3`,h,`Result`),a(`pre`,g,t||`No output.`))}E.probe&&k.append(a(`h3`,h,`Watch probe: ${E.matched===null?`not evaluated`:E.matched?`matched`:`not matched`}`),a(`pre`,g,S(E.probe)));let N=a(`details`,`border-t border-neutral-200`);if(N.append(a(`summary`,`flex cursor-pointer items-center gap-1.5 px-4 py-3 text-[12px] text-neutral-500 hover:text-neutral-800`,c(o,`chev h-3 w-3`),`Configuration snapshot (revision ${E.taskRevision})`),y(E.context.definition,d.openSession)),k.append(N),T.ok||k.append(a(`p`,`m-4 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-[12.5px] text-red-700`,T.error)),D.length){let e=a(`div`,`mt-2 divide-y divide-neutral-100 border-t border-neutral-100`);for(let t of D){let n=a(`div`,`grid grid-cols-[auto_1fr] gap-3 px-4 py-2 text-[12px] md:grid-cols-[6.25rem_6.25rem_minmax(0,1fr)]`);n.append(a(`span`,`font-medium`,t.kind),a(`span`,`text-neutral-500`,t.state),a(`span`,`col-span-2 whitespace-pre-wrap break-words md:col-span-1`,t.content)),t.error&&n.append(a(`span`,`col-span-2 break-words text-red-600 md:col-span-3`,t.error)),e.append(n)}k.append(a(`div`,`border-t border-neutral-200`,a(`div`,h,`Messages`),e))}let P=a(`details`,`border-t border-neutral-200`);P.open=f.rawOpen,P.ontoggle=()=>{P.isConnected&&(f.rawOpen=P.open)},P.append(a(`summary`,`flex cursor-pointer items-center gap-1.5 px-4 py-3 text-[12px] text-neutral-500 hover:text-neutral-800`,c(o,`chev h-3 w-3`),`Raw record`),a(`pre`,g,JSON.stringify(E,null,2))),k.append(P),e.replaceChildren(v,k),e.scrollTop=f.scrollTop,e.onscroll=()=>{f.scrollTop=e.scrollTop}}export{x as a,u as c,C as i,m as l,l as n,b as o,y as r,p as s,v as t,_ as u};
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{$ as e,C as t,F as n,G as r,O as i,P as a,Q as o,T as s,V as c,Y as l,_ as u,dt as d,et as f,it as p,j as m,k as h,o as g,ot as _,rt as v,s as y,st as b,z as x}from"./index-
|
|
1
|
+
import{$ as e,C as t,F as n,G as r,O as i,P as a,Q as o,T as s,V as c,Y as l,_ as u,dt as d,et as f,it as p,j as m,k as h,o as g,ot as _,rt as v,s as y,st as b,z as x}from"./index-CzV2cZEH.js";import{a as S,c as C,l as w,n as T,r as E,s as D,t as O,u as k}from"./task-runs-DcORJXHU.js";function A(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 j(e,t){let r=document.createElement(`dialog`);r.className=`m-auto w-[38.75rem] max-w-[94vw] rounded-lg border border-neutral-200 p-0 shadow-xl backdrop:bg-black/20`;let i=document.createElement(`form`);i.className=`flex max-h-[88vh] flex-col`;let a=l(`span`,`mr-auto text-[12px] text-red-600`),o=l(`header`,`flex h-11 flex-none items-center border-b border-neutral-200 px-4 font-medium`,t?`Edit task`:`New task`),c=l(`div`,`grid min-h-0 flex-1 grid-cols-2 gap-3 overflow-y-auto p-4`),u=m(t?.name??``);u.required=!0;let d=m(t?.description??``),f=m(String(t?.timeoutSeconds??3600),`number`);f.min=`1`,f.max=`86400`;let p=n([[`Manual`,`manual`],[`Scheduled`,`cron`],[`Watch`,`watch`]],t?.trigger.type??`manual`),v=n([[`Bash`,`bash`],[`Agent`,`agent`],[`Task`,`task`]],t?.action.type??`bash`),b=n([[`No callback`,`none`],[`Invoking session`,`origin`],[`Specific session`,`session`]],t?.callback.type??`none`),S=t?.callback.type===`session`?t.callback.sessionId:null,C=n(A(e.sessions(),S),S??``),w=h(`Callback session`,C);w.classList.toggle(`hidden`,b.value!==`session`),b.onchange=()=>w.classList.toggle(`hidden`,b.value!==`session`),c.append(h(`Name`,u),h(`Description`,d),h(`Trigger`,p),h(`Action`,v),h(`Callback`,b),w,h(`Timeout (seconds)`,f));let T=l(`div`,`col-span-2 grid grid-cols-2 gap-3 border-t border-neutral-200 pt-3`);c.append(T);let E=()=>{T.replaceChildren();let o,s,c,S,w,E;if(p.value===`cron`)o=m(t?.trigger.type===`cron`?t.trigger.expression:`0 9 * * *`),s=m(t?.trigger.type===`cron`?t.trigger.timezone:Intl.DateTimeFormat().resolvedOptions().timeZone),T.append(h(`Cron`,o),h(`Timezone`,s));else if(p.value===`watch`){c=x(t?.trigger.type===`watch`?t.trigger.script:``,4),E=m(t?.trigger.type===`watch`?t.trigger.cwd:e.sessions()[0]?.cwd??``),S=m(String(t?.trigger.type===`watch`?t.trigger.intervalSeconds:60),`number`),w=n([[`Continue after matches`,`repeat`],[`Stop after first match`,`once`]],t?.trigger.type===`watch`?t.trigger.mode:`repeat`);let r=h(`Probe script (0=match, 1=no match)`,c);r.classList.add(`col-span-2`),T.append(r,h(`Probe directory`,E),h(`Interval (seconds)`,S),h(`Mode`,w))}let D,O,k,j,N,P,F,I,L,R;if(v.value===`bash`){O=m(t?.action.type===`bash`?t.action.cwd:e.sessions()[0]?.cwd??``),D=x(t?.action.type===`bash`?t.action.script:``,6);let n=h(`Bash script`,D);n.classList.add(`col-span-2`),T.append(h(`Working directory`,O),l(`span`,``),n)}else if(v.value===`agent`){let r=e.sessions(),i=t?.action.type===`agent`?t.action:null,a=i?.session.mode===`reuse`?i.session.sessionId:``,o=A(r,a||null);k=n([[`Reuse session`,`reuse`],[`Fresh child per run`,`fresh`]],i?.session.mode===`reuse`?`reuse`:`fresh`),j=n(o,a||o[0]?.[1]||``);let s=i&&`cwd`in i.session?i.session.cwd??``:``;N=m(s||r[0]?.cwd||``),P=x(i?.prompt??``,6),F=n([[`Project default`,``],...g.map(e=>[_(e),e])],i?.launch?.thinking??``),I=m(i?.launch?.model?.provider??``),L=m(i?.launch?.model?.id??``);let c=h(`Session`,j),l=h(`Child directory`,N),u=[h(`Thinking`,F),h(`Model provider (optional)`,I),h(`Model id (optional)`,L)],d=()=>{let e=k?.value===`reuse`;c.classList.toggle(`hidden`,!e),l.classList.toggle(`hidden`,e);for(let t of u)t.classList.toggle(`hidden`,e)};k.onchange=d,d();let f=h(`Prompt`,P);f.classList.add(`col-span-2`),T.append(h(`Session policy`,k),c,l,...u,f)}else R=n(e.tasks().filter(e=>e.id!==t?.id&&!e.archived).map(e=>[e.name,e.id]),t?.action.type===`task`?t.action.taskId:``),T.append(h(`Target task`,R));i.onsubmit=n=>{n.preventDefault();let i=p.value===`manual`?{type:`manual`}:p.value===`cron`?{type:`cron`,expression:o.value,timezone:s.value}:{type:`watch`,script:c.value,cwd:E.value,intervalSeconds:Number(S.value),mode:w.value},l=v.value===`agent`&&k.value!==`reuse`?{...y(F.value)?{thinking:F.value}:{},...I.value.trim()&&L.value.trim()?{model:{provider:I.value.trim(),id:L.value.trim()}}:{}}:void 0,m=v.value===`bash`?{type:`bash`,cwd:O.value,script:D.value}:v.value===`agent`?{type:`agent`,prompt:P.value,session:k.value===`reuse`?{mode:`reuse`,sessionId:j.value}:{mode:`fresh`,cwd:N.value},...l?{launch:l}:{}}:{type:`task`,taskId:R.value},h=b.value===`origin`?{type:`origin`}:b.value===`session`?{type:`session`,sessionId:C.value}:{type:`none`},g={name:u.value,description:d.value,trigger:i,action:m,callback:h,timeoutSeconds:Number(f.value)};a.textContent=``,M(t?.id,g,r,a,e.onSaved)}};p.onchange=E,v.onchange=E,E();let D=s(`Cancel`);D.onclick=()=>r.close();let O=s(`Save`,!0);O.type=`submit`;let k=l(`footer`,`flex flex-none justify-end gap-2 border-t border-neutral-200 px-4 py-3`);k.append(a,D,O),i.append(o,c,k),r.append(i),r.addEventListener(`close`,()=>r.remove()),document.body.append(r),r.showModal(),u.focus()}async function M(e,t,n,r,i){let a=await p(e?`/api/tasks/${e}`:`/api/tasks`,t,e?`PATCH`:`POST`);if(!a.ok){r.textContent=(await a.json()).error??`Task save failed`;return}let o=await a.json(),s=`task`in o?o.task:o;n.close(),i(s.id)}function N(m,h,g,_,y,x,A){let M=[],N=[],P=null,F=`active`,I=`all`,L=``,R=`runs`,z={top:0},B=0,V=0,H=``,U=o(async()=>{if(P||!$.visible)return;let e=B,t=`${F}:${I}`,n=await f(`/api/tasks?state=${F}&kind=task`,`Failed to load tasks`);if(!$.visible||e!==B||t!==`${F}:${I}`)return;if(!n.ok)return H=``,K(n.error);let r=JSON.stringify(n.value);t+r!==H&&(H=t+r,M=n.value,I!==`all`&&(M=M.filter(e=>e.trigger.type===I)),X())}),W=o(async()=>{P&&$.visible&&await ae(P)});function G(){return P?W():U()}function K(e){m.querySelector(`[role=alert]`)?.remove();let t=l(`p`,`flex-none p-4 text-[13px] text-red-600`,e);t.setAttribute(`role`,`alert`),m.append(t)}async function q(){let e=P,t=await f(`/api/tasks?state=active`,`Failed to load tasks`);return!t.ok&&$.visible&&P===e&&K(t.error),t.ok?t.value:N}let J={sessions:h,tasks:()=>N,onSaved:e=>{Y(e),R=`definition`,A(e)}},ee=(e,t)=>c(...e,l(`div`,`ml-auto flex flex-wrap items-center gap-2 max-md:w-full`,...t));function Y(e){P=e,B++,R=`runs`,z.top=0}function te(){P=null,B++,X()}function ne(){!$.visible||P!==null||Promise.all([g(),q()]).then(([,e])=>{!$.visible||P!==null||(N=e,j(J))})}function X(){let e=[],t=(t,r,i,a)=>{let o=n(r,i);o.setAttribute(`aria-label`,t),o.dataset.active=String(i!==r[0]?.[1]),o.onchange=()=>{o.dataset.active=String(o.value!==r[0]?.[1]),a(o.value),V=0,G()},e.push(l(`label`,`filter-field`,l(`span`,``,t),o))},r=l(`input`,u);r.type=`search`,r.placeholder=`Search tasks`,r.setAttribute(`aria-label`,`Search tasks`),r.value=L,r.dataset.active=String(!!L),r.oninput=()=>{L=r.value,r.dataset.active=String(!!L),s()},e.push(l(`label`,`filter-field filter-search`,l(`span`,``,`Search`),r)),t(`Status`,[[`Current`,`active`],[`Archived`,`archived`]],F,e=>{F=e}),t(`Trigger`,[[`All triggers`,`all`],[`Manual`,`manual`],[`Scheduled`,`cron`],[`Watching`,`watch`]],I,e=>{I=e});let a=document.createElement(`table`);a.className=`w-full table-fixed text-left text-[12.5px]`,a.innerHTML=`<thead class="sticky top-0 bg-neutral-50 text-[10.5px] uppercase tracking-wide text-neutral-400 shadow-[inset_0_-1px_0_var(--color-neutral-200)]"><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 o=document.createElement(`tbody`),s=()=>{let e=M.filter(e=>`${e.name} ${e.description??``}`.toLowerCase().includes(L.toLowerCase()));o.replaceChildren(...e.map(re)),c.classList.toggle(`hidden`,e.length>0)};a.append(o);let c=l(`div`,`p-4`,i(`No matching tasks.`)),d=l(`div`,`automation-list min-h-0 flex-1 overflow-auto`,a,c);s(),d.onscroll=()=>{V=d.scrollTop},m.replaceChildren(l(`div`,`automation-filters task-filters`,...e),d),d.scrollTop=V}function re(e){let t=document.createElement(`tr`);t.className=`cursor-pointer border-b border-neutral-100 transition-colors hover:bg-neutral-50`,t.onclick=()=>A(e.id);let n=s(e.name);n.className=`min-w-0 cursor-pointer truncate text-left font-medium text-neutral-800`,n.title=e.name,t.append(l(`td`,`py-2.5 pl-4 pr-2`,l(`div`,`flex flex-wrap items-center gap-x-2 gap-y-1`,n,w(e),...ie(e)),l(`div`,`truncate text-[11px] text-neutral-400`,e.description||``),l(`div`,`truncate text-[11px] text-neutral-400 md:hidden`,k(e))));for(let n of[O(e),k(e),T(e.nextRunAt)]){let e=l(`td`,`hidden truncate px-2 py-2.5 text-neutral-600 md:table-cell`,n);e.title=n,t.append(e)}t.append(l(`td`,`px-2 py-2.5`,e.lastRun?l(`div`,`flex`,D(e.lastRun)):l(`div`,`text-neutral-400`,`–`),l(`div`,`mt-0.5 font-mono text-[11px] text-neutral-400`,e.lastRun?C(e.lastRun):``)));let r=s(`Run now`);return r.disabled=e.archived,r.onclick=t=>{t.stopPropagation(),Z(e.id)},t.append(l(`td`,`px-2 py-1 text-right`,r)),t}function ie(e){if(!e.createdBySessionId)return[];let n=t(`agent`,`bg-violet-50 text-violet-700 ring-violet-200`);return n.title=`Created by session ${e.createdBySessionId}`,[n]}async function ae(e){let t=++B,n=m.querySelector(`[data-task-detail]`),[r,i]=await Promise.all([f(`/api/tasks/${e}`,`Failed to load task`),f(`/api/tasks/${e}/runs`,`Failed to load the task's runs`)]);if(!$.visible||t!==B||P!==e)return;if(!r.ok)return K(r.error);if(!i.ok)return K(i.error);let o=r.value,u=i.value,p=s(`Tasks`);p.className=`cursor-pointer text-neutral-500 hover:text-neutral-800 hover:underline`,p.onclick=()=>A();let h=l(`span`,`flex min-w-0 items-center gap-2`,p,b(d,`h-3.5 w-3.5 text-neutral-400`),l(`span`,`truncate font-medium`,o.name),w(o)),v=s(`Run now`,!0);v.disabled=o.archived,v.onclick=()=>void Z(o.id);let y=s(o.enabled?`Pause schedule`:`Resume schedule`);y.disabled=o.archived||o.action.type===`system`||o.trigger.type===`manual`,y.onclick=()=>void Q(`/api/tasks/${o.id}/${o.enabled?`pause`:`resume`}`);let C=s(`Edit`);C.disabled=o.archived||o.action.type===`system`,C.onclick=()=>{!$.visible||P!==o.id||Promise.all([g(),q()]).then(([,e])=>{!$.visible||P!==o.id||(N=e,j(J,o))})};let T=s(`Archive`);T.disabled=o.archived||o.action.type===`system`,T.onclick=()=>void Q(`/api/tasks/${o.id}/archive`);let D=c(),O=l(`div`,`automation-list min-h-0 flex-1 overflow-auto`);O.dataset.taskDetail=e;let k=s(`All runs`);k.onclick=()=>x({taskId:o.id});let M=()=>{D.replaceChildren(a([[`Recent runs (${u.length})`,`runs`],[`Definition`,`definition`]],R,e=>{R=e,M()}),l(`span`,`ml-auto`,k)),R===`runs`?S(O,u,e=>x({},e),z):(O.onscroll=null,O.replaceChildren(E(o,_)))},F=n?.scrollTop??0;m.replaceChildren(ee([h],[v,...o.trigger.type===`manual`?[]:[y],C,T]),D,O),M(),O.scrollTop=F}async function Z(t){try{let n=await p(`/api/tasks/${t}/run`,{sourceSessionId:y()});if(!n.ok)return K(await e(n,`Failed to run task`));x({},(await n.json()).runId)}catch(e){K(`Failed to run task: ${String(e)}`)}}async function Q(e){let t=await v(e,`POST`,`Task update failed`);if(t)return K(t);await G()}let $=r(m,e=>{e&&e!==P&&Y(e),e||te(),m.childElementCount||X(),G()});return Object.assign($,{create:ne,refresh(e){$.visible&&(!P||!e||P===e)&&G()}})}export{N as createTasksView};
|
|
Binary file
|
|
Binary file
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
which style.css pays for with the safe-area inset. -->
|
|
39
39
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
40
40
|
<title>Pier</title>
|
|
41
|
-
<script type="module" crossorigin src="/app/assets/index-
|
|
41
|
+
<script type="module" crossorigin src="/app/assets/index-CzV2cZEH.js"></script>
|
|
42
42
|
<link rel="stylesheet" crossorigin href="/app/assets/index-sQWFDUPu.css">
|
|
43
43
|
</head>
|
|
44
44
|
<!-- The document never scrolls: this is a fixed-viewport workbench, and every
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|