@timqi/pier 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/config.js +57 -59
- package/dist/agent/listing.js +38 -15
- package/dist/agent/packages.js +353 -0
- package/dist/agent/pi.js +28 -13
- package/dist/core/types.js +7 -0
- package/dist/extensions/index.js +1 -20
- package/dist/main.js +19 -14
- package/dist/settings.js +5 -0
- package/dist/tools.js +46 -85
- package/dist/web/config.js +25 -11
- package/dist/web/explorer.js +5 -3
- package/dist/web/instance.js +6 -18
- package/dist/web/packages.js +84 -0
- package/dist/web/public/assets/{activity-DOr8dWeX.js → activity-BSMeRcN2.js} +2 -2
- package/dist/web/public/assets/activity-BSMeRcN2.js.br +0 -0
- package/dist/web/public/assets/activity-BSMeRcN2.js.gz +0 -0
- package/dist/web/public/assets/boards-BCWQMZry.js +1 -0
- package/dist/web/public/assets/boards-BCWQMZry.js.br +0 -0
- package/dist/web/public/assets/boards-BCWQMZry.js.gz +0 -0
- package/dist/web/public/assets/explorer-Cr4XTi4j.js +4 -0
- package/dist/web/public/assets/explorer-Cr4XTi4j.js.br +0 -0
- package/dist/web/public/assets/explorer-Cr4XTi4j.js.gz +0 -0
- package/dist/web/public/assets/index-C7tA0Ufu.js +85 -0
- package/dist/web/public/assets/index-C7tA0Ufu.js.br +0 -0
- package/dist/web/public/assets/index-C7tA0Ufu.js.gz +0 -0
- package/dist/web/public/assets/index-DVIt5Gio.css +2 -0
- package/dist/web/public/assets/index-DVIt5Gio.css.br +0 -0
- package/dist/web/public/assets/index-DVIt5Gio.css.gz +0 -0
- package/dist/web/public/assets/runs-DdERzeac.js +1 -0
- package/dist/web/public/assets/runs-DdERzeac.js.br +0 -0
- package/dist/web/public/assets/runs-DdERzeac.js.gz +0 -0
- package/dist/web/public/assets/settings-CQDAHoMM.js +5 -0
- package/dist/web/public/assets/settings-CQDAHoMM.js.br +0 -0
- package/dist/web/public/assets/settings-CQDAHoMM.js.gz +0 -0
- package/dist/web/public/assets/task-runs-C-dGUDsH.js +3 -0
- package/dist/web/public/assets/task-runs-C-dGUDsH.js.br +0 -0
- package/dist/web/public/assets/task-runs-C-dGUDsH.js.gz +0 -0
- package/dist/web/public/assets/tasks-CY30H1u1.js +4 -0
- package/dist/web/public/assets/tasks-CY30H1u1.js.br +0 -0
- package/dist/web/public/assets/tasks-CY30H1u1.js.gz +0 -0
- package/dist/web/public/index.html +2 -2
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/server.js +3 -1
- package/docs/deploy.md +11 -0
- package/package.json +1 -1
- package/dist/web/public/assets/activity-DOr8dWeX.js.br +0 -0
- package/dist/web/public/assets/activity-DOr8dWeX.js.gz +0 -0
- package/dist/web/public/assets/boards-CneyR23E.js +0 -1
- package/dist/web/public/assets/boards-CneyR23E.js.br +0 -0
- package/dist/web/public/assets/boards-CneyR23E.js.gz +0 -0
- package/dist/web/public/assets/explorer-D0srXT1c.js +0 -4
- package/dist/web/public/assets/explorer-D0srXT1c.js.br +0 -0
- package/dist/web/public/assets/explorer-D0srXT1c.js.gz +0 -0
- package/dist/web/public/assets/index-DbFu15NN.js +0 -85
- package/dist/web/public/assets/index-DbFu15NN.js.br +0 -0
- package/dist/web/public/assets/index-DbFu15NN.js.gz +0 -0
- package/dist/web/public/assets/index-eqQLVS8Q.css +0 -2
- package/dist/web/public/assets/index-eqQLVS8Q.css.br +0 -0
- package/dist/web/public/assets/index-eqQLVS8Q.css.gz +0 -0
- package/dist/web/public/assets/runs-Cv0A-e08.js +0 -1
- package/dist/web/public/assets/runs-Cv0A-e08.js.br +0 -0
- package/dist/web/public/assets/runs-Cv0A-e08.js.gz +0 -0
- package/dist/web/public/assets/settings-VmCjhGBd.js +0 -5
- package/dist/web/public/assets/settings-VmCjhGBd.js.br +0 -0
- package/dist/web/public/assets/settings-VmCjhGBd.js.gz +0 -0
- package/dist/web/public/assets/task-runs-CqpTV644.js +0 -3
- package/dist/web/public/assets/task-runs-CqpTV644.js.br +0 -0
- package/dist/web/public/assets/task-runs-CqpTV644.js.gz +0 -0
- package/dist/web/public/assets/tasks-BffPVgXg.js +0 -4
- package/dist/web/public/assets/tasks-BffPVgXg.js.br +0 -0
- package/dist/web/public/assets/tasks-BffPVgXg.js.gz +0 -0
package/dist/web/instance.js
CHANGED
|
@@ -15,7 +15,7 @@ const withName = (current, { name, on }) => on ? [...new Set([...current, name])
|
|
|
15
15
|
/** A browser bug can fire in a loop, and the journal is shared. */
|
|
16
16
|
const CLIENT_LOG_PER_MINUTE = 60;
|
|
17
17
|
export function registerInstanceRoutes(app, deps) {
|
|
18
|
-
const { settings, updates, updater = null, secrets, catalog, names =
|
|
18
|
+
const { settings, updates, updater = null, secrets, catalog, names = [], onUnlocked, onSettingsChanged, onToolsChanged, validateCustomTools, } = deps;
|
|
19
19
|
const updateLog = logger("update");
|
|
20
20
|
// A busy Pier drains first, which can take minutes, and a response held that
|
|
21
21
|
// long dies at every proxy: past this cap the answer is "draining".
|
|
@@ -108,11 +108,11 @@ export function registerInstanceRoutes(app, deps) {
|
|
|
108
108
|
app.put("/api/settings", async (c) => {
|
|
109
109
|
const body = await c.req.json().catch(() => null);
|
|
110
110
|
const fields = body
|
|
111
|
-
? [body.publicUrl, body.modelMenu, body.titleModel, body.autoUpdate, body.customTools, body.
|
|
111
|
+
? [body.publicUrl, body.modelMenu, body.titleModel, body.autoUpdate, body.customTools, body.tool]
|
|
112
112
|
: [];
|
|
113
113
|
if (!fields.some((v) => v !== undefined)) {
|
|
114
114
|
return c.json({
|
|
115
|
-
error: "publicUrl, modelMenu, titleModel, autoUpdate, customTools
|
|
115
|
+
error: "publicUrl, modelMenu, titleModel, autoUpdate, customTools or tool required",
|
|
116
116
|
}, 400);
|
|
117
117
|
}
|
|
118
118
|
// One transaction: a new custom tool and the switch that turns it on must
|
|
@@ -166,14 +166,6 @@ export function registerInstanceRoutes(app, deps) {
|
|
|
166
166
|
return "expected {name, on}";
|
|
167
167
|
return { name, on: given.on };
|
|
168
168
|
};
|
|
169
|
-
let extensionOne = null;
|
|
170
|
-
if (body?.extension !== undefined) {
|
|
171
|
-
const one = delta(body.extension);
|
|
172
|
-
if (typeof one === "string")
|
|
173
|
-
return refuse(`extension: ${one}`);
|
|
174
|
-
extensionOne = one;
|
|
175
|
-
writes.push(() => settings.setExtensions(withName(settings.get().extensions, one)));
|
|
176
|
-
}
|
|
177
169
|
let toolsChanged = false;
|
|
178
170
|
let toolOne = null;
|
|
179
171
|
if (body?.tool !== undefined) {
|
|
@@ -189,8 +181,7 @@ export function registerInstanceRoutes(app, deps) {
|
|
|
189
181
|
settings.get().customTools.some((tool) => !declared?.some((kept) => kept.name === tool.name));
|
|
190
182
|
const shown = dropping ? await catalog?.() : undefined;
|
|
191
183
|
const binaryOf = (name) => {
|
|
192
|
-
|
|
193
|
-
return entry?.source === "binary" ? entry.binary : null;
|
|
184
|
+
return shown?.entries.find((row) => row.name === name)?.binary ?? null;
|
|
194
185
|
};
|
|
195
186
|
/** Inside the transaction, or two requests both pass and leave an enabled
|
|
196
187
|
* tool nothing declares. A block is the only thing that can uninstall its
|
|
@@ -200,10 +191,7 @@ export function registerInstanceRoutes(app, deps) {
|
|
|
200
191
|
const current = settings.get();
|
|
201
192
|
const after = (declared ?? current.customTools).map((tool) => tool.name);
|
|
202
193
|
const toolsAfter = toolOne ? withName(current.tools, toolOne) : current.tools;
|
|
203
|
-
if (
|
|
204
|
-
throw new Refusal(`extension: this Pier has no extension called ${extensionOne.name}`, 400);
|
|
205
|
-
}
|
|
206
|
-
if (toolOne?.on && !names.tools.includes(toolOne.name) && !after.includes(toolOne.name)) {
|
|
194
|
+
if (toolOne?.on && !names.includes(toolOne.name) && !after.includes(toolOne.name)) {
|
|
207
195
|
throw new Refusal(`tool: this Pier manages no tool called ${toolOne.name}`, 400);
|
|
208
196
|
}
|
|
209
197
|
for (const gone of current.customTools.filter((tool) => !after.includes(tool.name))) {
|
|
@@ -236,7 +224,7 @@ export function registerInstanceRoutes(app, deps) {
|
|
|
236
224
|
// cannot start, and then says why.
|
|
237
225
|
const note = toolsChanged ? await onToolsChanged?.() : null;
|
|
238
226
|
// Read when a session opens; the model menu is read per picker call.
|
|
239
|
-
if (body?.publicUrl !== undefined
|
|
227
|
+
if (body?.publicUrl !== undefined)
|
|
240
228
|
onSettingsChanged?.();
|
|
241
229
|
return c.json({ ...(await instanceSettings()), ...(note ? { toolsSync: note } : {}) });
|
|
242
230
|
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// The package registry (/api/packages*) through the PackageStore seam. A file
|
|
2
|
+
// of its own because the registry is not agent-file editing (config.ts).
|
|
3
|
+
import { PackageError } from "../core/types.js";
|
|
4
|
+
const STATUS = {
|
|
5
|
+
invalid: 400, missing: 404, busy: 409, refused: 409, unreachable: 502,
|
|
6
|
+
};
|
|
7
|
+
export function registerPackageRoutes(app, { factory, packages, onConfigWritten }) {
|
|
8
|
+
// Only cwds Pi already knows are accepted — never an arbitrary path.
|
|
9
|
+
const knownCwd = async (raw) => {
|
|
10
|
+
if (raw === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
return (await factory.list()).some((s) => s.cwd === raw) ? raw : null;
|
|
13
|
+
};
|
|
14
|
+
/** The seam's reasons are the table's status codes; anything else is a 500 (app.onError). */
|
|
15
|
+
const answer = async (c, work) => {
|
|
16
|
+
try {
|
|
17
|
+
return await work();
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
if (!(err instanceof PackageError))
|
|
21
|
+
throw err;
|
|
22
|
+
return c.json({ error: err.message }, STATUS[err.reason]);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const body = async (c) => {
|
|
26
|
+
const parsed = await c.req.json().catch(() => null);
|
|
27
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
28
|
+
};
|
|
29
|
+
const written = () => onConfigWritten?.();
|
|
30
|
+
app.get("/api/packages", (c) => answer(c, async () => {
|
|
31
|
+
c.header("cache-control", "no-store");
|
|
32
|
+
const cwd = await knownCwd(c.req.query("cwd"));
|
|
33
|
+
if (cwd === null)
|
|
34
|
+
return c.json({ error: "unknown cwd" }, 400);
|
|
35
|
+
return c.json(await packages.list(cwd));
|
|
36
|
+
}));
|
|
37
|
+
app.post("/api/packages", (c) => answer(c, async () => {
|
|
38
|
+
const given = await body(c);
|
|
39
|
+
if (typeof given?.source !== "string")
|
|
40
|
+
return c.json({ error: "source required" }, 400);
|
|
41
|
+
const pkg = await packages.install(given.source);
|
|
42
|
+
written();
|
|
43
|
+
return c.json({ package: pkg });
|
|
44
|
+
}));
|
|
45
|
+
app.post("/api/packages/remove", (c) => answer(c, async () => {
|
|
46
|
+
const given = await body(c);
|
|
47
|
+
if (typeof given?.source !== "string")
|
|
48
|
+
return c.json({ error: "source required" }, 400);
|
|
49
|
+
await packages.remove(given.source);
|
|
50
|
+
written();
|
|
51
|
+
return c.json({ ok: true });
|
|
52
|
+
}));
|
|
53
|
+
app.post("/api/packages/update", (c) => answer(c, async () => {
|
|
54
|
+
const given = await body(c);
|
|
55
|
+
if (given?.source !== undefined && typeof given.source !== "string")
|
|
56
|
+
return c.json({ error: "source must be a string" }, 400);
|
|
57
|
+
const updated = await packages.update(given?.source);
|
|
58
|
+
written();
|
|
59
|
+
return c.json({ packages: updated });
|
|
60
|
+
}));
|
|
61
|
+
app.post("/api/packages/check", (c) => answer(c, async () => c.json(await packages.checkUpdates())));
|
|
62
|
+
app.put("/api/packages/resource", (c) => answer(c, async () => {
|
|
63
|
+
const change = parseSwitch(await body(c));
|
|
64
|
+
if (!change)
|
|
65
|
+
return c.json({ error: "expected {source, kind: extension|skill, path, enabled, cwd?}" }, 400);
|
|
66
|
+
if (change.cwd !== undefined && await knownCwd(change.cwd) === null)
|
|
67
|
+
return c.json({ error: "unknown cwd" }, 400);
|
|
68
|
+
const resource = await packages.setEnabled(change);
|
|
69
|
+
written();
|
|
70
|
+
return c.json(resource);
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
function parseSwitch(given) {
|
|
74
|
+
if (!given)
|
|
75
|
+
return null;
|
|
76
|
+
const { source, kind, path, enabled, cwd } = given;
|
|
77
|
+
if (typeof source !== "string" || !source || typeof path !== "string" || !path)
|
|
78
|
+
return null;
|
|
79
|
+
if ((kind !== "extension" && kind !== "skill") || typeof enabled !== "boolean")
|
|
80
|
+
return null;
|
|
81
|
+
if (cwd !== undefined && typeof cwd !== "string")
|
|
82
|
+
return null;
|
|
83
|
+
return { source, kind, path, enabled, ...(cwd !== undefined ? { cwd } : {}) };
|
|
84
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{E as e,G as t,H as n,J as r,K as i,M as a,R as o,S as s,Y as c,Z as l,nt as u}from"./index-C7tA0Ufu.js";var d=(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},f=e=>e===null?`-`:t(Date.now()-e),p={light:{edge:`#a3a3a3`,callback:`#0891b2`,message:`#d97706`,scheduler:{fill:`#f5f3ff`,stroke:`#a78bfa`,text:`#5b21b6`},console:{fill:`#eff6ff`,stroke:`#93c5fd`,text:`#1d4ed8`},task:{fill:`#fffbeb`,stroke:`#fbbf24`,text:`#92400e`},process:{fill:`#f5f5f5`,stroke:`#a3a3a3`,text:`#525252`,dash:`4 3`},streaming:{fill:`#ffffff`,stroke:`#10b981`,text:`#262626`},idle:{fill:`#fafafa`,stroke:`#d4d4d4`,text:`#737373`}},dark:{edge:`#7a7a7a`,callback:`#3fc3dd`,message:`#e0a13a`,scheduler:{fill:`#2b2440`,stroke:`#7d63c9`,text:`#c9b8f5`},console:{fill:`#1f2a3d`,stroke:`#4a7fbf`,text:`#a8c8f0`},task:{fill:`#3a2f1c`,stroke:`#b8862a`,text:`#f0d49a`},process:{fill:`#262626`,stroke:`#5c5c5c`,text:`#a3a3a3`,dash:`4 3`},streaming:{fill:`#22302a`,stroke:`#10b981`,text:`#e5e5e5`},idle:{fill:`#212121`,stroke:`#4a4a4a`,text:`#9a9a9a`}}},m=()=>p[document.documentElement.dataset.theme===`dark`?`dark`:`light`];function h(t,p,h){let g=`sessions`,_=`active`,v={sessions:[],runs:[],messages:[]},y=``,b=c(async()=>{let e=_,n=await l(`/api/activity?scope=${e}`,`Failed to load activity`);if(!n.ok){y=``,t.replaceChildren(i(`p`,`p-4 text-[13px] text-red-600`,n.error));return}if(e!==_)return;let r=JSON.stringify(n.value);if(`${e}:${r}`===y)return;y=`${e}:${r}`;let a=n.value;v={...a,sessions:a.sessions.map(e=>({...e,title:u(e.title)}))},x()});function x(){let e=o(a([[`Sessions`,`sessions`],[`Relationships`,`dependencies`]],g,e=>{g=e,x()}),i(`span`,`ml-auto text-[11.5px] text-neutral-400`,`${v.sessions.length} sessions · ${v.runs.length} runs`),a([[`Current`,`active`],[`Last 24h`,`recent`]],_,e=>{_=e,x(),b()})),n=i(`div`,`automation-list min-h-0 flex-1 overflow-auto`);g===`sessions`?S(n):w(n),t.replaceChildren(e,n)}function S(t){let n=document.createElement(`table`);n.className=`w-full table-fixed text-left text-[12.5px]`,n.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>
|
|
5
|
-
<th class="px-2 py-2 font-semibold">In state</th></tr></thead>`;let
|
|
5
|
+
<th class="px-2 py-2 font-semibold">In state</th></tr></thead>`;let a=document.createElement(`tbody`);for(let e of v.sessions){let t=document.createElement(`tr`);t.className=`cursor-pointer border-b border-neutral-100 transition-colors hover:bg-neutral-50`,t.onclick=()=>p(e.id);let n=i(`button`,`block w-full cursor-pointer truncate text-left font-medium text-neutral-800`,e.title??r(e.cwd));n.setAttribute(`type`,`button`),n.title=`${e.id}\n${e.cwd}`,n.onclick=t=>{t.stopPropagation(),p(e.id)},t.append(i(`td`,`px-4 py-2.5`,n,i(`div`,`truncate font-mono text-[11px] text-neutral-400 md:hidden`,e.cwd||`-`)),i(`td`,`hidden truncate px-2 py-2.5 font-mono text-[11.5px] text-neutral-500 md:table-cell`,e.cwd||`-`),i(`td`,`px-2 py-2.5`,C(e.state)),i(`td`,`px-2 py-2.5 font-mono text-[11.5px] text-neutral-400`,f(e.stateSince))),a.append(t)}n.append(a),t.append(n),v.sessions.length||t.append(i(`div`,`p-4`,e(_===`active`?`No active sessions.`:`No sessions in the last 24 hours.`)))}function C(e){return e===`streaming`?s(e,`bg-emerald-50 text-emerald-700 ring-emerald-200`,`animate-pulse bg-emerald-500`):s(e,`bg-neutral-100 text-neutral-600 ring-neutral-200`,`bg-neutral-300`)}function w(t){let n=new Map,r=[],a=(e,t,r,i)=>{n.has(e)||n.set(e,{id:e,label:t,kind:r,state:i})};for(let e of v.sessions)a(e.id,e.title??e.id.slice(0,10),`session`,e.state);for(let e of v.runs){let t=e.invokedBySessionId??`scheduler`,n=e.targetSessionId??(e.context.definition.action.type===`bash`?`process:${e.id}`:`task:${e.id}`);a(t,t===`scheduler`?`Scheduler`:t.slice(0,10),t===`scheduler`?`scheduler`:`session`),a(n,e.targetSessionId?e.targetSessionId.slice(0,10):e.context.definition.action.type===`bash`?`Bash process`:`Task`,e.targetSessionId?`session`:e.context.definition.action.type===`bash`?`process`:`task`),r.push({from:t,to:n,run:e,kind:`invocation`}),e.callbackSessionId&&(a(e.callbackSessionId,e.callbackSessionId.slice(0,10),`session`),r.push({from:n,to:e.callbackSessionId,run:e,kind:`callback`}))}for(let e of v.messages){if(!e.fromSessionId||!e.toSessionId||e.fromSessionId===e.toSessionId)continue;let t=v.runs.find(t=>t.id===e.runId);if(t){for(let t of[e.fromSessionId,e.toSessionId])a(t,t===`console`?`Console`:t.slice(0,10),t===`console`?`console`:`session`);r.push({from:e.fromSessionId,to:e.toSessionId,run:t,kind:`message`})}}if(!n.size){t.append(i(`div`,`p-4`,e(_===`active`?`No active dependencies.`:`No dependencies in the last 24 hours.`)));return}let o=[...n.values()],s=new Set(r.map(e=>e.to)),c=new Map,l=o.filter(e=>!s.has(e.id)).map(e=>e.id);l.length||l.push(o[0].id);for(let e of l)c.set(e,0);for(;l.length;){let e=l.shift();for(let t of r)t.from!==e||c.has(t.to)||(c.set(t.to,c.get(e)+1),l.push(t.to))}for(let e of o)c.has(e.id)||c.set(e.id,0);let u=new Map;for(let e of o){let t=c.get(e.id);u.set(t,[...u.get(t)??[],e])}let f=Math.max(...u.keys())+1,g=Math.max(...[...u.values()].map(e=>e.length)),y=r.some(e=>e.from!==e.to&&c.get(e.from)===c.get(e.to))?40:0,b=56+f*180+(f-1)*110+y,x=56+g*46+(g-1)*30,S=new Map;for(let[e,t]of u)t.forEach((t,n)=>S.set(t.id,{x:28+e*290+90,y:28+n*76+23}));let C=d(`svg`,{width:String(b),height:String(x),viewBox:`0 0 ${b} ${x}`,class:`block`}),w=d(`defs`),T=m();for(let[e,t]of[[`activity-arrow`,T.edge],[`activity-arrow-cb`,T.callback],[`activity-arrow-msg`,T.message]]){let n=d(`marker`,{id:e,viewBox:`0 0 10 10`,refX:`9`,refY:`5`,markerWidth:`6`,markerHeight:`6`,orient:`auto-start-reverse`});n.append(d(`path`,{d:`M 0 0 L 10 5 L 0 10 z`,fill:t})),w.append(n)}C.append(w);let E=new Set;for(let e of r){let t=`${e.from}→${e.to}:${e.kind}`;if(E.has(t))continue;E.add(t);let n=S.get(e.from),r=S.get(e.to),i=d(`path`,{d:n.x===r.x?`M ${n.x+90} ${n.y} C ${n.x+90+46} ${n.y}, ${r.x+90+46} ${r.y}, ${r.x+90} ${r.y}`:(()=>{let e=r.x>n.x,t=n.x+(e?90:-90),i=r.x+(e?-90:90),a=Math.max(36,Math.abs(i-t)*.45)*(e?1:-1);return`M ${t} ${n.y} C ${t+a} ${n.y}, ${i-a} ${r.y}, ${i} ${r.y}`})(),fill:`none`,stroke:e.kind===`callback`?T.callback:e.kind===`message`?T.message:T.edge,"stroke-width":`1.5`,"marker-end":e.kind===`callback`?`url(#activity-arrow-cb)`:e.kind===`message`?`url(#activity-arrow-msg)`:`url(#activity-arrow)`});e.kind===`callback`&&i.setAttribute(`stroke-dasharray`,`6 5`),e.kind===`message`&&i.setAttribute(`stroke-dasharray`,`2 5`),i.classList.add(`cursor-pointer`),i.onclick=()=>h(e.run.id),C.append(i)}let D=/[\u1100-\u11FF\u2E80-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFF60\uFFE0-\uFFE6]/,O=(e,t)=>{let n=0;for(let r=0;r<e.length;r++)if(n+=D.test(e[r])?2:1,n>t)return`${e.slice(0,r)}…`;return e};for(let e of o){let t=S.get(e.id),n=e.kind===`session`?e.state===`streaming`?T.streaming:T.idle:T[e.kind],r=d(`g`,{transform:`translate(${t.x},${t.y})`});e.kind===`session`&&r.classList.add(`cursor-pointer`),r.onclick=()=>{e.kind===`session`&&p(e.id)};let i=d(`rect`,{x:`-90`,y:`-23`,width:`180`,height:`46`,rx:`8`,fill:n.fill,stroke:n.stroke,"stroke-width":e.kind===`session`&&e.state===`streaming`?`1.5`:`1`});n.dash&&i.setAttribute(`stroke-dasharray`,n.dash),r.append(i);let a=-78;if(e.kind===`session`){let t=d(`circle`,{cx:`-75`,cy:`0`,r:`3.5`,fill:n.stroke});if(e.state===`streaming`){let e=d(`animate`,{attributeName:`opacity`,values:`1;0.3;1`,dur:`1.6s`,repeatCount:`indefinite`});t.append(e)}r.append(t),a=-64}let o=d(`text`,{x:String(a),"text-anchor":`start`,"dominant-baseline":`middle`,"font-size":`11.5`,"font-weight":e.kind===`session`?`500`:`400`,fill:n.text});o.textContent=O(e.label,e.kind===`session`?22:25);let s=d(`title`);s.textContent=e.label===e.id?e.id:`${e.label}\n${e.id}`,r.append(o,s),C.append(r)}let k=e=>i(`span`,`inline-block h-2 w-2 rounded-full ${e}`),A=e=>i(`span`,`inline-block h-0 w-6 border-t-2 ${e}`);t.append(i(`div`,`w-max p-4`,C),i(`div`,`flex flex-wrap gap-x-5 gap-y-1.5 border-t border-neutral-200 bg-neutral-50/60 px-4 py-2 text-[11px] text-neutral-500`,i(`span`,`inline-flex items-center gap-2`,A(`border-solid border-neutral-400`),`task invocation`),i(`span`,`inline-flex items-center gap-2 text-cyan-700`,A(`border-dashed border-cyan-500`),`callback`),i(`span`,`inline-flex items-center gap-2 text-amber-700`,A(`border-dotted border-amber-500`),`supervisor / control`),i(`span`,`inline-flex items-center gap-1.5`,k(`bg-emerald-500`),`streaming`),i(`span`,`inline-flex items-center gap-1.5`,k(`bg-neutral-300`),`idle`)))}let T=n(t,e=>{e===`dependencies`?g=`dependencies`:e===`sessions`&&(g=`sessions`),b()},()=>{t.replaceChildren(),v={sessions:[],runs:[],messages:[]},y=``});return window.addEventListener(`pier:theme`,()=>{T.visible&&x()}),Object.assign(T,{refresh(){T.visible&&b()}})}export{h as createActivityView};
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,C as t,E as n,H as r,K as i,L as a,T as o,U as s,X as c,Z as l,et as u,q as d,tt as f}from"./index-C7tA0Ufu.js";var p=e=>e.public&&e.token?`/p/${e.slug}-${e.token}/`:`/boards/${e.slug}/`;function m(m,h){let g=[],_=``,v=i(`header`,`pagehead sticky top-[-8px] z-30 max-md:hidden`,e(`Boards`)),y=i(`div`,`px-4 pb-5 pt-1`);m.append(i(`div`,`min-h-0 flex-1 overflow-y-auto`,v,y));async function b(e,t){let n=await f(`/api/boards/${e.slug}`,{public:t},`PATCH`);if(n.ok)return e.token=(await n.json().catch(()=>({}))).token??``,w();_=await c(n,`Could not change ${e.slug}`),await T()}async function x(e){_=await u(`/api/boards/${e}`,`DELETE`,`Could not delete ${e}`)??``,await T()}function S(e){let n=i(`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 o=i(`div`,`flex flex-wrap items-center gap-x-2 gap-y-1`,r),c=a(``,``,e.public,t=>{e.public=t,b(e,t)});c.className=`flex flex-none cursor-pointer items-center gap-1.5 text-[11.5px] text-neutral-500`,c.append(i(`span`,``,`Public`));let l=t(`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=s(`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`,o.append(i(`div`,`ml-auto flex flex-none items-center gap-2`,c,u,l)),n.append(o);let f=i(`div`,`flex flex-wrap items-center gap-x-3 gap-y-1 text-[11.5px] text-neutral-500`);f.append(i(`span`,`min-w-0 break-all font-mono text-neutral-400`,e.slug)),e.description&&f.append(i(`span`,`min-w-0 truncate`,e.description)),f.append(i(`span`,`flex-none text-neutral-400`,d(Date.parse(e.updatedAt))));for(let n of e.sessions){let e=t(n.slice(0,8),`flex-none cursor-pointer font-mono text-indigo-600 hover:underline`);e.title=`Open session ${n}`,e.onclick=()=>h(n),f.append(e)}if(e.public&&e.token){let t=i(`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`,f.append(t)}return n.append(f),n}let C=[{title:`Public`,hint:`Readable at /p/<slug>-<token>/ by anyone holding the link.`,wanted:!0},{title:`Private`,hint:`Reachable from the Console only.`,wanted:!1}];function w(){let e=i(`div`,`mx-auto flex w-full max-w-3xl flex-col gap-4`);g.length===0&&e.append(n(`No boards yet. Ask an agent to build one — it writes a folder under ~/.pier/boards.`));for(let{title:t,hint:n,wanted:r}of C){let a=g.filter(e=>e.public===r);a.length!==0&&e.append(o(t,n,i(`div`,`flex flex-col divide-y divide-neutral-200/70`,...a.map(S))))}y.replaceChildren(..._?[i(`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
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{A as e,C as t,E as n,H as r,K as i,Q as a,V as o,W as s,_ as c,a as l,at as u,dt as d,f,h as p,i as m,it as h,l as g,m as ee,p as te,q as _,s as ne,ut as re,v as ie}from"./index-C7tA0Ufu.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
|
+
|
|
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=i(`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=i(`button`,`flex w-full cursor-pointer items-center gap-1.5 px-2 py-1 text-left hover:bg-neutral-100`,h(re,`h-3 w-3 text-indigo-600 ${e.value===t?``:`invisible`}`),i(`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(i(`span`,`min-w-0 truncate text-[11px] text-neutral-400`,e.subject)),e.author&&r.append(i(`span`,`ml-auto flex-none pl-1.5 text-[10.5px] text-neutral-400`,`${e.author} · ${e.at?_(e.at):``}`)),ue(r,()=>le(e)),r.onclick=()=>n(e.value),r}function de(e,t,n,r,a){let{base:o,head:s}=n,c=()=>s&&o===`${s}~1`?s:``,u=c()?`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=i(`div`,`flex w-[38rem] max-w-full flex-col`);function m(){let e=(e,t)=>{let n=i(`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)=>i(`div`,`flex min-w-0 flex-1 flex-col`,i(`div`,`flex-none px-2 pb-0.5 text-[10.5px] font-semibold uppercase tracking-wide text-neutral-400`,e),i(`div`,`min-h-0 flex-1 overflow-y-auto`,...t.map(e=>S(e,n,r)))),d=u===`compare`?i(`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)})):i(`div`,`flex h-72 min-h-0 flex-col overflow-y-auto pb-1`,...t.commits.map(e=>S({value:e.hash,...e},c(),e=>{o=`${e}~1`,s=e,l(),r(o,s)}))),g=i(`div`,`flex-none border-t border-neutral-200`,S({value:a,label:`${a} ↔ Working tree`,subject:`back to the default: the main line's tip vs the files on disk`},o===a&&s===``?a:``,()=>{o=a,s=``,m(),r(o,s)}));g.querySelector(`button > span`).prepend(h(v)),p.replaceChildren(i(`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`)),d,...u===`compare`?[g]:[])}m(),ne(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,n=`indigo`)=>t(e,`${ge} cursor-pointer truncate text-left ${n===`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(l,_,ne,re){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=i(`header`,`pagehead flex-nowrap`),M=i(`div`,`${p} flex-col items-stretch gap-1.5 px-3 py-2.5`),N=i(`div`,`min-h-0 flex-1 overflow-y-auto px-1.5 py-1.5`),ye=i(`aside`,`${ie} w-64 flex-none text-[12.5px] leading-5 max-md:h-1/2 max-md:w-full`,M,N),P=i(`div`,`${p} flex-wrap gap-2 px-4 py-2.5 font-mono text-[11.5px] text-neutral-500`),F=i(`div`,`h-full min-w-0 overflow-auto`),I=i(`div`,`pointer-events-none absolute inset-y-1 right-0.5 z-20 hidden w-2`),be=i(`div`,`relative min-h-0 flex-1`,F,I),xe=i(`section`,`${ie} min-h-0 min-w-0 flex-1`,P,be);l.append(ve,i(`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`)=>i(`p`,`px-3 py-2 text-[12.5px] ${t}`,e),B=e=>i(`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 a(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=[i(`span`,`truncate`,t)];n&&r.push(i(`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:a,summary:o}=s(``,r);o.className+=` rounded-lg px-2 py-1 transition-colors hover:bg-neutral-100`;let c=i(`div`,`pl-3`);a.append(c);let l=!1,u=()=>{l||(l=!0,c.append(z(`…`)),Te(c,e))};return a.ontoggle=()=>{O[a.open?`add`:`delete`](e),a.open&&u()},((b.branch?T:!e.includes(`/`))&&!E||O.has(e))&&(a.open=!0,u()),a}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=i(`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`,i(`span`,`truncate`,t));return n&&r.append(i(`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?[i(`span`,`flex-none font-mono text-[10.5px] font-semibold text-emerald-600`,`+${e}`)]:[],...t?[i(`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 r=w.get(e),a=[i(`span`,`min-w-0 truncate`,e)];r&&(a.push(i(`span`,`flex-none font-semibold ${C[r.status]??``}`,r.status)),a.push(...U(r.add,r.del)));let s=i(`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=o(e),t.textContent=`Download`,s.append(t)}P.replaceChildren(...a,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=i(`div`,`min-w-0`);if(F.classList.remove(`flex`,`flex-col`),W(e,!0),F.replaceChildren(r),fe.test(e)){let e=i(`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 a=await fetch(n);if(!q(t))return;if(!a.ok){let{error:e}=await a.json().catch(()=>({}));r.replaceChildren(z(e??`HTTP ${a.status}`,`text-red-600`));return}if(!(a.headers.get(`content-type`)??``).startsWith(`text/plain`)){r.replaceChildren(z(`Binary file — use Download.`));return}let o=te(await a.text());if(!q(t))return;let s=await ee(e);q(t)&&r.replaceChildren(f(o,s))}function je(e){let t=[],n=0,r=0,i=!1,a=e.split(`
|
|
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=i(`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=i(`span`,`flex-none text-[10.5px] text-neutral-400`),a=i=>{e.length&&(n=(n+i+e.length)%e.length,t[e[n].start].scrollIntoView({block:`center`}),r.textContent=`${n+1}/${e.length}`)},o=()=>e.length>0&&!l.classList.contains(`hidden`),s=(e,t,n,r)=>{let s=i(`button`,`icon-btn flex-none`,h(e));return s.onclick=()=>a(t),g(s,r,n,()=>a(t),o),s};return{el:i(`div`,`flex flex-none items-center gap-1`,r,s(d,-1,`Previous change`,[`p`,`k`]),s(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 a(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 o=await ee(e);if(!q(t))return;let s=f(i,o),c=[...s.children],l=Me(i);G.set(l,c),W(e,n,G.el),F.replaceChildren(s),Pe(l,i.length,c)}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 a=i(`button`,`icon-btn ${n?`bg-indigo-50 text-indigo-700 hover:bg-indigo-100 hover:text-indigo-700`:``}`);return a.append(h(e)),a.title=t,a.setAttribute(`aria-label`,t),a.setAttribute(`aria-pressed`,String(n)),a.onclick=r,a};function X(){let e=Be(se,`Show only files that differ`,T,()=>{T=!T,X(),H()}),n=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(i(`div`,`flex items-center gap-1.5`,i(`span`,`min-w-0 flex-1 text-[11px] leading-snug text-neutral-400`,`Not a git repository — nothing to compare.`),n));return}let r=t(ze(),`${c} font-mono`);if(Y()){let e=b.commits.find(e=>e.hash===Y());ue(r,()=>e?le(e):``)}else r.title=`Choose what to diff`;r.onclick=async()=>{await We(),de(r,b,{base:x,head:S},(e,t)=>{x=e,S=t,Z()},$())};let[a,o]=[0,0];for(let e of w.values())a+=e.add,o+=e.del;M.replaceChildren(r,i(`div`,`flex items-center gap-1.5 pl-0.5`,i(`span`,`text-[11px] text-neutral-400`,`${w.size} changed file${w.size===1?``:`s`}`),...U(a,o),i(`span`,`ml-auto`),e,n))}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 a(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 t=_e(``,`neutral`);t.className+=` max-w-72`,t.append(i(`span`,`truncate max-md:hidden`,v||`Choose a folder…`),i(`span`,`truncate md:hidden`,v?o(v):`Choose a folder…`)),t.title=v?`${v} — switch folder`:`Choose a folder`,t.onclick=()=>m(t,b.worktrees.map(e=>({path:e.path,...e.branch?{hint:e.branch}:{}})),v||void 0,ne);let n=i(`button`,`icon-btn ml-auto`,h(u));n.type=`button`,n.title=`Close Files`,n.setAttribute(`aria-label`,`Close Files`),n.onclick=re;let r=b.branch?[i(`span`,`${ge} bg-neutral-100 text-neutral-600`,h(ce),i(`span`,`truncate`,b.branch))]:[];ve.replaceChildren(e(`Files`),t,...r,n)}async function We(){if(v)try{b=await a(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 a(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 r(l,(e,t)=>{let n=_(),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
|