@agimon-ai/po-template-advanced 0.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1272 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _agimon_ai_po_core_web = require("@agimon-ai/po-core/web");
3
+ let _agimon_ai_po_web_dashboard = require("@agimon-ai/po-web-dashboard");
4
+ let _agimon_ai_po_web_dashboard_views = require("@agimon-ai/po-web-dashboard/views");
5
+ let _tanstack_react_store = require("@tanstack/react-store");
6
+ let react = require("react");
7
+ let _agimon_ai_po_web_components = require("@agimon-ai/po-web-components");
8
+ let react_jsx_runtime = require("react/jsx-runtime");
9
+ let _tanstack_react_router = require("@tanstack/react-router");
10
+ //#region src/extensions/(frontend)/template/_components/AdvancedFolderBrowser.tsx
11
+ function folderName$1(path) {
12
+ return path.slice(path.lastIndexOf("/") + 1) || path;
13
+ }
14
+ /** Walks the server's folders inline: up, into a child, or pick the current folder. */
15
+ function AdvancedFolderBrowser({ start, listDirectory, onSelect }) {
16
+ const [target, setTarget] = (0, react.useState)(start);
17
+ const [listing, setListing] = (0, react.useState)(null);
18
+ const [error, setError] = (0, react.useState)("");
19
+ (0, react.useEffect)(() => {
20
+ let stale = false;
21
+ listDirectory(target).then((result) => {
22
+ if (stale) return;
23
+ if ("error" in result) setError(result.error);
24
+ else {
25
+ setError("");
26
+ setListing(result);
27
+ }
28
+ });
29
+ return () => {
30
+ stale = true;
31
+ };
32
+ }, [target, listDirectory]);
33
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
34
+ "data-testid": "folder-browser",
35
+ className: "flex flex-col gap-1 rounded border border-doom-border bg-doom-deep p-1",
36
+ children: [
37
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
38
+ className: "flex items-center gap-1 px-1",
39
+ children: [
40
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
41
+ variant: "ghost",
42
+ size: "icon",
43
+ "data-testid": "folder-browser-up",
44
+ title: "parent folder",
45
+ "aria-label": "parent folder",
46
+ disabled: listing?.parent === void 0,
47
+ onClick: () => listing?.parent !== void 0 && setTarget(listing.parent),
48
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.ChevronUpIcon, { className: "h-3 w-3" })
49
+ }),
50
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
51
+ className: "min-w-0 flex-1 truncate text-sm text-doom-dim",
52
+ title: listing?.path,
53
+ children: listing?.path ?? "loading…"
54
+ }),
55
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
56
+ variant: "outline",
57
+ size: "xs",
58
+ "data-testid": "folder-browser-select",
59
+ disabled: listing === null,
60
+ onClick: () => listing !== null && onSelect(listing.path),
61
+ children: "use this folder"
62
+ })
63
+ ]
64
+ }),
65
+ error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
66
+ className: "px-2 py-1 text-sm text-doom-red",
67
+ children: error
68
+ }) : null,
69
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
70
+ role: "listbox",
71
+ "aria-label": "folders",
72
+ className: "max-h-40 overflow-y-auto",
73
+ children: [listing !== null && listing.directories.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
74
+ className: "px-2 py-1 text-sm text-doom-dim",
75
+ children: "no folders here"
76
+ }) : null, listing?.directories.map((directory) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.OptionRow, {
77
+ density: "compact",
78
+ "data-testid": "folder-browser-entry",
79
+ onClick: () => setTarget(directory),
80
+ className: "w-full px-2.5 py-1 ",
81
+ children: folderName$1(directory)
82
+ }, directory))]
83
+ })
84
+ ]
85
+ });
86
+ }
87
+ //#endregion
88
+ //#region src/extensions/(frontend)/template/_components/AdvancedAddWorkspaceDialog.tsx
89
+ const SUGGESTION_DEBOUNCE_MS = 120;
90
+ const NO_HIGHLIGHT = -1;
91
+ const TRAILING_SEPARATORS = /\/+$/u;
92
+ function folderName(path) {
93
+ const trimmed = path.trim().replace(TRAILING_SEPARATORS, "");
94
+ return trimmed.slice(trimmed.lastIndexOf("/") + 1);
95
+ }
96
+ /** Adds a workspace by name, by folder, or both; a name alone gets a new default folder. */
97
+ function AdvancedAddWorkspaceDialog({ suggestedPaths, actions }) {
98
+ const draft = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.workspaceAdmissionStore, (state) => state);
99
+ const { name, nameEdited, pending: busy, error } = draft;
100
+ const path = draft.path ?? suggestedPaths[0] ?? "";
101
+ const setName = (name) => (0, _agimon_ai_po_web_dashboard.updateWorkspaceAdmission)({ name });
102
+ const setNameEdited = (nameEdited) => (0, _agimon_ai_po_web_dashboard.updateWorkspaceAdmission)({ nameEdited });
103
+ const setPath = (path) => (0, _agimon_ai_po_web_dashboard.updateWorkspaceAdmission)({ path });
104
+ const [browsing, setBrowsing] = (0, react.useState)(false);
105
+ const [suggestions, setSuggestions] = (0, react.useState)([]);
106
+ const [highlight, setHighlight] = (0, react.useState)(NO_HIGHLIGHT);
107
+ const pathInput = (0, react.useRef)(null);
108
+ const shownName = nameEdited ? name : folderName(path);
109
+ (0, react.useEffect)(() => {
110
+ const typed = path.trim();
111
+ if (typed === "") return;
112
+ let stale = false;
113
+ const timer = setTimeout(async () => {
114
+ const found = await actions.searchDirectories(typed);
115
+ if (stale) return;
116
+ setSuggestions(found.filter((directory) => directory !== typed));
117
+ setHighlight(NO_HIGHLIGHT);
118
+ }, SUGGESTION_DEBOUNCE_MS);
119
+ return () => {
120
+ stale = true;
121
+ clearTimeout(timer);
122
+ };
123
+ }, [path, actions]);
124
+ const changePath = (next) => {
125
+ setPath(next);
126
+ if (next.trim() === "") setSuggestions([]);
127
+ };
128
+ const pick = (directory) => {
129
+ changePath(`${directory}/`);
130
+ pathInput.current?.focus();
131
+ };
132
+ const trimmedPath = path.trim().replace(TRAILING_SEPARATORS, "") || (path.trim() === "" ? "" : "/");
133
+ const canSubmit = !busy && (trimmedPath !== "" || shownName.trim() !== "");
134
+ const submit = async () => {
135
+ if (!canSubmit) return;
136
+ await actions.addWorkspace({
137
+ name: shownName.trim(),
138
+ ...trimmedPath === "" ? {} : { path: trimmedPath }
139
+ });
140
+ };
141
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Dialog, {
142
+ open: true,
143
+ onOpenChange: (next) => !next && !busy && actions.closeAddWorkspace(),
144
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogContent, {
145
+ width: "md",
146
+ "data-testid": "add-workspace-dialog",
147
+ "aria-describedby": void 0,
148
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogTitle, { children: "add workspace" }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogBody, { children: [
149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
150
+ htmlFor: "add-workspace-name",
151
+ className: "flex flex-col gap-1",
152
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
153
+ className: "text-base font-medium text-doom-dim",
154
+ children: "name"
155
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Input, {
156
+ id: "add-workspace-name",
157
+ "data-testid": "add-workspace-name",
158
+ value: shownName,
159
+ autoFocus: true,
160
+ onChange: (event) => {
161
+ setNameEdited(true);
162
+ setName(event.target.value);
163
+ },
164
+ onKeyDown: (event) => {
165
+ if (event.key === "Enter") submit();
166
+ },
167
+ placeholder: "my-project"
168
+ })]
169
+ }),
170
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
171
+ htmlFor: "add-workspace-root",
172
+ className: "flex flex-col gap-1",
173
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
174
+ className: "text-base font-medium text-doom-dim",
175
+ children: ["folder ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
176
+ className: "text-doom-dim",
177
+ children: "(optional; type a path or browse)"
178
+ })]
179
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
180
+ className: "flex items-center gap-1.5",
181
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Input, {
182
+ id: "add-workspace-root",
183
+ ref: pathInput,
184
+ "data-testid": "add-workspace-root",
185
+ value: path,
186
+ onChange: (event) => changePath(event.target.value),
187
+ onKeyDown: (event) => {
188
+ if (event.key === "ArrowDown" && suggestions.length > 0) {
189
+ event.preventDefault();
190
+ setHighlight((current) => (current + 1) % suggestions.length);
191
+ } else if (event.key === "ArrowUp" && suggestions.length > 0) {
192
+ event.preventDefault();
193
+ setHighlight((current) => current <= 0 ? suggestions.length - 1 : current - 1);
194
+ } else if (event.key === "Enter") {
195
+ const chosen = highlight === NO_HIGHLIGHT ? void 0 : suggestions[highlight];
196
+ if (chosen === void 0) submit();
197
+ else pick(chosen);
198
+ }
199
+ },
200
+ placeholder: "~/workspace/my-project",
201
+ className: "min-w-0 flex-1"
202
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
203
+ variant: browsing ? "subtle" : "outline",
204
+ size: "md",
205
+ "data-testid": "add-workspace-browse",
206
+ "aria-pressed": browsing,
207
+ onClick: () => setBrowsing((open) => !open),
208
+ children: "browse"
209
+ })]
210
+ })]
211
+ }),
212
+ browsing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedFolderBrowser, {
213
+ ...trimmedPath.startsWith("/") ? { start: trimmedPath } : {},
214
+ listDirectory: actions.listDirectory,
215
+ onSelect: (selected) => {
216
+ changePath(selected);
217
+ setBrowsing(false);
218
+ }
219
+ }) : suggestions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
220
+ role: "listbox",
221
+ "aria-label": "matching directories",
222
+ "data-testid": "add-workspace-suggestions",
223
+ className: "max-h-40 overflow-y-auto rounded border border-doom-border bg-doom-deep p-1",
224
+ children: suggestions.map((directory, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.OptionRow, {
225
+ density: "compact",
226
+ active: index === highlight,
227
+ "data-testid": "add-workspace-suggestion",
228
+ onMouseDown: (event) => event.preventDefault(),
229
+ onMouseEnter: () => setHighlight(index),
230
+ onClick: () => pick(directory),
231
+ className: "w-full px-2.5 py-1 ",
232
+ children: directory
233
+ }, directory))
234
+ }) : null,
235
+ suggestedPaths.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
236
+ className: "flex flex-wrap gap-1",
237
+ children: suggestedPaths.slice(0, 4).map((suggested) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
238
+ variant: "outline",
239
+ size: "xs",
240
+ onClick: () => changePath(suggested),
241
+ children: suggested
242
+ }, suggested))
243
+ }) : null,
244
+ trimmedPath === "" && shownName.trim() !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
245
+ "data-testid": "add-workspace-default-hint",
246
+ className: "text-sm text-doom-dim",
247
+ children: ["creates ~/.po/workspace/", shownName.trim()]
248
+ }) : null,
249
+ error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
250
+ className: "max-h-28 overflow-y-auto rounded border border-doom-edge-red bg-doom-tint-red/40 px-2.5 py-2 text-sm whitespace-pre-wrap text-doom-red",
251
+ children: error
252
+ }) : null,
253
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
254
+ variant: "outline",
255
+ onClick: () => actions.closeAddWorkspace(),
256
+ disabled: busy,
257
+ children: "cancel"
258
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
259
+ variant: "primary",
260
+ "data-testid": "add-workspace-confirm",
261
+ onClick: () => void submit(),
262
+ disabled: !canSubmit,
263
+ children: busy ? "adding…" : "add workspace"
264
+ })] })
265
+ ] })]
266
+ })
267
+ });
268
+ }
269
+ //#endregion
270
+ //#region src/extensions/(frontend)/template/_components/AdvancedPendingSetup.tsx
271
+ /** A pending reservation has no runtime and must not inherit live-session actions. */
272
+ function AdvancedPendingSetup({ sessionId, setup, actions }) {
273
+ const key = JSON.stringify([
274
+ "rail/setup",
275
+ sessionId,
276
+ setup.id
277
+ ]);
278
+ const [busy, setBusy, busyState] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/busy`, false);
279
+ const [error, setError] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/error`, "");
280
+ const remove = async () => {
281
+ if (busyState.state) return;
282
+ setBusy(true);
283
+ setError("");
284
+ const result = await actions.removePendingSetup(sessionId, setup.id);
285
+ setBusy(false);
286
+ if (result !== void 0) setError(result.error);
287
+ };
288
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
289
+ "data-testid": `pending-session-${setup.id}`,
290
+ className: "ml-4 rounded-md border border-doom-border-soft bg-doom-panel p-3",
291
+ children: [
292
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
293
+ className: "flex items-center justify-between gap-2",
294
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
295
+ className: "truncate text-base font-semibold text-doom-hi",
296
+ children: setup.name
297
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuTrigger, {
298
+ asChild: true,
299
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
300
+ variant: "ghost",
301
+ size: "icon",
302
+ title: "session setup actions",
303
+ disabled: busy,
304
+ "data-testid": `pending-session-menu-${setup.id}`,
305
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.KebabIcon, { className: "h-3 w-3" })
306
+ })
307
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuContent, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
308
+ variant: "destructive",
309
+ onSelect: () => void remove(),
310
+ children: "remove setup"
311
+ }) })] })]
312
+ }),
313
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
314
+ className: setup.failed ? "text-sm text-doom-red" : "text-sm text-doom-dim",
315
+ children: setup.status
316
+ }),
317
+ setup.recovery ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
318
+ role: setup.failed ? "alert" : void 0,
319
+ className: "text-sm text-doom-dim",
320
+ children: setup.recovery
321
+ }) : null,
322
+ error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
323
+ role: "alert",
324
+ className: "text-sm text-doom-red",
325
+ children: error
326
+ }) : null
327
+ ]
328
+ });
329
+ }
330
+ //#endregion
331
+ //#region src/extensions/(frontend)/template/_components/AdvancedSessionCard.tsx
332
+ function AdvancedSessionCard({ session, actions }) {
333
+ const key = `rail/session/${session.id}`;
334
+ const [mode, setMode] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/mode`, "view");
335
+ const [draft, setDraft] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/draft`, "");
336
+ const [removeError, setRemoveError] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/error`, "");
337
+ const [, setRemoving, removingState] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/removing`, false);
338
+ const modeRef = (0, react.useRef)(mode);
339
+ const enterMode = (next) => {
340
+ modeRef.current = next;
341
+ setMode(next);
342
+ };
343
+ const { active } = session;
344
+ const error = removeError || session.error;
345
+ const cardClass = active ? "rounded-lg border border-doom-edge-green bg-doom-tint-green px-3 py-3 hover:bg-doom-tint-green" : "rounded-lg border border-transparent px-3 py-3 hover:bg-doom-panel";
346
+ const commitRename = () => {
347
+ actions.renameSession(session.id, draft);
348
+ enterMode("view");
349
+ };
350
+ const remove = async () => {
351
+ if (removingState.state) return;
352
+ setRemoving(true);
353
+ enterMode("view");
354
+ setRemoveError("");
355
+ const result = await actions.removeSession(session.id);
356
+ setRemoving(false);
357
+ if (result !== void 0) setRemoveError(result.error);
358
+ };
359
+ const failed = session.status.startsWith("failed") || session.status.includes(" failed");
360
+ const running = session.status.startsWith("running");
361
+ const status = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
362
+ className: `flex min-w-0 items-start gap-1.5 text-sm leading-snug ${failed ? "text-doom-red" : running ? "text-doom-yellow" : active ? "text-doom-text" : "text-doom-dim"}`,
363
+ children: [session.awaitingInput ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.AlertIcon, {
364
+ "data-testid": "session-awaiting-input",
365
+ "aria-label": "Waiting for your input",
366
+ className: "mt-0.5 size-3 shrink-0 text-doom-magenta"
367
+ }) : running ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.LoaderIcon, {
368
+ "aria-hidden": true,
369
+ className: "mt-0.5 size-3 shrink-0 animate-spin"
370
+ }) : failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.AlertIcon, {
371
+ "aria-hidden": true,
372
+ className: "mt-0.5 size-3 shrink-0"
373
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
374
+ "data-testid": "session-status",
375
+ className: active ? "line-clamp-2" : "truncate",
376
+ children: session.status
377
+ })]
378
+ });
379
+ const heading = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
380
+ className: "flex min-w-0 items-start gap-2",
381
+ children: [
382
+ session.nested && session.provenance === "workflow-session" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.ActivityIcon, {
383
+ "aria-label": "workflow session",
384
+ className: `mt-1 size-3 shrink-0 ${active ? "text-doom-green" : "text-doom-faint"}`
385
+ }) : session.nested && session.provenance ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.ForkIcon, {
386
+ "aria-label": session.provenance === "worktree" ? "automatic per-conversation worktree" : session.provenance,
387
+ className: `mt-1 size-3 shrink-0 ${active ? "text-doom-green" : "text-doom-faint"}`
388
+ }) : null,
389
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
390
+ className: "min-w-0 flex-1 text-base font-semibold break-words text-doom-hi",
391
+ children: session.name || "Untitled"
392
+ }),
393
+ session.ordinal <= 9 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
394
+ title: `press ${String(session.ordinal)} to focus`,
395
+ className: "grid size-5 shrink-0 place-items-center rounded-full bg-doom-panel text-2xs text-doom-dim transition-opacity group-focus-within:opacity-0 group-hover:opacity-0",
396
+ children: session.ordinal
397
+ }) : null
398
+ ]
399
+ });
400
+ const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
401
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
402
+ className: "flex w-full min-w-0 items-start gap-2.5",
403
+ children: [session.profile ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.Avatar, {
404
+ "data-testid": "session-avatar",
405
+ "aria-label": session.profile.label,
406
+ title: session.profile.label,
407
+ className: "size-8 shrink-0 rounded-full",
408
+ children: [session.profile.avatarUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.AvatarImage, {
409
+ src: session.profile.avatarUrl,
410
+ alt: ""
411
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.AvatarFallback, {
412
+ className: "bg-doom-tint-green text-xs font-semibold text-doom-green",
413
+ children: session.profile.initials
414
+ })]
415
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
416
+ className: "flex min-w-0 flex-1 flex-col gap-1",
417
+ children: [heading, status]
418
+ })]
419
+ }),
420
+ session.git ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
421
+ "data-testid": "session-branch",
422
+ className: `flex min-w-0 items-center gap-1.5 text-sm text-doom-dim ${session.profile ? "pl-10.5" : ""}`,
423
+ children: [
424
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.BranchIcon, { className: `size-3.5 shrink-0 ${active ? "text-doom-green" : ""}` }),
425
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
426
+ className: "truncate font-mono",
427
+ children: session.git.branch
428
+ }),
429
+ session.git.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
430
+ className: "shrink-0 text-doom-yellow",
431
+ children: "modified"
432
+ }) : null
433
+ ]
434
+ }) : null,
435
+ error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
436
+ "data-testid": "session-error",
437
+ className: "line-clamp-3 text-sm break-words text-doom-red",
438
+ children: error
439
+ }) : null
440
+ ] });
441
+ const menuOpen = mode === "menu";
442
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
443
+ className: (0, _agimon_ai_po_web_components.cn)("group relative", session.nested && "pl-5"),
444
+ "data-testid": `session-card-${session.id}`,
445
+ "data-active": active,
446
+ "data-nested": session.nested,
447
+ children: [
448
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
449
+ variant: "ghost",
450
+ size: "card",
451
+ "data-testid": `session-open-${session.id}`,
452
+ onClick: () => actions.openSession(session.id),
453
+ className: cardClass,
454
+ children: body
455
+ }),
456
+ mode === "view" || menuOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
457
+ className: `absolute top-2 right-2 transition-opacity ${menuOpen ? "opacity-100" : "opacity-0 group-focus-within:opacity-100 group-hover:opacity-100"}`,
458
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DropdownMenu, {
459
+ open: menuOpen,
460
+ onOpenChange: (next) => {
461
+ const current = modeRef.current;
462
+ enterMode(next ? "menu" : current === "menu" ? "view" : current);
463
+ },
464
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuTrigger, {
465
+ asChild: true,
466
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
467
+ variant: "ghost",
468
+ size: "icon",
469
+ "data-testid": `session-menu-${session.id}`,
470
+ title: "session actions",
471
+ className: active ? "text-doom-dim hover:bg-doom-tint-green hover:text-doom-hi data-[state=open]:bg-doom-tint-green data-[state=open]:text-doom-hi" : "text-doom-faint hover:bg-doom-deep hover:text-doom-hi data-[state=open]:bg-doom-deep data-[state=open]:text-doom-hi",
472
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.KebabIcon, { className: "h-3 w-3" })
473
+ })
474
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DropdownMenuContent, {
475
+ "data-testid": `session-menu-list-${session.id}`,
476
+ onCloseAutoFocus: (event) => {
477
+ if (modeRef.current !== "view") event.preventDefault();
478
+ },
479
+ children: [
480
+ actions.renderSessionMenuItems(session.id),
481
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
482
+ "data-testid": `session-rename-${session.id}`,
483
+ onSelect: () => {
484
+ setDraft(session.name);
485
+ enterMode("rename");
486
+ },
487
+ children: "rename"
488
+ }),
489
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
490
+ "data-testid": `session-resume-${session.id}`,
491
+ onSelect: () => actions.resumeSession(session.id),
492
+ children: "resume"
493
+ }),
494
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
495
+ "data-testid": `session-restart-${session.id}`,
496
+ disabled: session.restarting || session.restartBlocked === true,
497
+ onSelect: () => actions.restartSession(session.id),
498
+ children: "restart"
499
+ }),
500
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
501
+ variant: "destructive",
502
+ "data-testid": `session-stop-${session.id}`,
503
+ onSelect: () => enterMode("confirm"),
504
+ children: "remove"
505
+ })
506
+ ]
507
+ })]
508
+ })
509
+ }) : null,
510
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Dialog, {
511
+ open: mode === "rename",
512
+ onOpenChange: (next) => !next && enterMode("view"),
513
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogContent, {
514
+ width: "sm",
515
+ "data-testid": `session-rename-dialog-${session.id}`,
516
+ "aria-describedby": void 0,
517
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogTitle, { children: "rename session" }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogBody, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
518
+ className: "flex flex-col gap-3",
519
+ onSubmit: (event) => {
520
+ event.preventDefault();
521
+ commitRename();
522
+ },
523
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Input, {
524
+ "data-testid": `session-name-input-${session.id}`,
525
+ "aria-label": "session name",
526
+ value: draft,
527
+ autoFocus: true,
528
+ onChange: (event) => setDraft(event.target.value)
529
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
530
+ type: "button",
531
+ variant: "outline",
532
+ size: "md",
533
+ "data-testid": `session-rename-cancel-${session.id}`,
534
+ onClick: () => enterMode("view"),
535
+ children: "cancel"
536
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
537
+ type: "submit",
538
+ variant: "primary",
539
+ size: "md",
540
+ "data-testid": `session-rename-confirm-${session.id}`,
541
+ disabled: draft.trim() === "",
542
+ children: "rename"
543
+ })] })]
544
+ }) })]
545
+ })
546
+ }),
547
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Dialog, {
548
+ open: mode === "confirm",
549
+ onOpenChange: (next) => !next && enterMode("view"),
550
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogContent, {
551
+ width: "sm",
552
+ "data-testid": `session-stop-dialog-${session.id}`,
553
+ "aria-describedby": void 0,
554
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogTitle, { children: "remove session" }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogBody, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogDescription, { children: [
555
+ "this stops ",
556
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
557
+ className: "font-semibold text-doom-hi",
558
+ children: session.name || "untitled"
559
+ }),
560
+ " and removes it from the rail. anything it is running ends now, but its saved history remains available to resume."
561
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
562
+ variant: "outline",
563
+ size: "md",
564
+ "data-testid": `session-stop-cancel-${session.id}`,
565
+ autoFocus: true,
566
+ onClick: () => enterMode("view"),
567
+ children: "cancel"
568
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
569
+ variant: "danger",
570
+ size: "md",
571
+ "data-testid": `session-stop-confirm-${session.id}`,
572
+ onClick: () => void remove(),
573
+ children: "remove"
574
+ })] })] })]
575
+ })
576
+ })
577
+ ]
578
+ }), session.pendingSetups.map((setup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedPendingSetup, {
579
+ sessionId: session.id,
580
+ setup,
581
+ actions
582
+ }, `setup:${setup.id}`))] });
583
+ }
584
+ //#endregion
585
+ //#region src/extensions/(frontend)/template/_components/AdvancedWorkspaceGroup.tsx
586
+ /** A folder heading over its sessions; only a hover tint marks the row. */
587
+ function AdvancedWorkspaceGroup({ workspace, actions }) {
588
+ const key = `rail/workspace/${workspace.id}`;
589
+ const [removeOpen, setRemoveOpen] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/open`, false);
590
+ const [removeError, setRemoveError] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/error`, "");
591
+ const [removing, setRemoving, removingState] = (0, _agimon_ai_po_web_dashboard.useDashboardState)(`${key}/removing`, false);
592
+ const { id, name, root, available, legacy } = workspace;
593
+ const unregister = async () => {
594
+ if (removingState.state) return;
595
+ setRemoving(true);
596
+ setRemoveError("");
597
+ const result = await actions.deleteWorkspace(id);
598
+ setRemoving(false);
599
+ if (result !== void 0) setRemoveError(result.error);
600
+ else setRemoveOpen(false);
601
+ };
602
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
603
+ "data-testid": `workspace-group-${id}`,
604
+ "data-available": available,
605
+ className: "flex flex-col gap-1.5",
606
+ children: [
607
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
608
+ className: "flex min-w-0 items-start gap-2.5 rounded-md px-2 py-1 transition-colors hover:bg-doom-panel/60",
609
+ children: [
610
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.FolderIcon, {
611
+ "aria-hidden": true,
612
+ className: "mt-0.5 size-4 shrink-0 text-doom-dim"
613
+ }),
614
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
615
+ className: "flex min-w-0 flex-1 flex-col",
616
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
617
+ className: "truncate text-base font-semibold text-doom-hi",
618
+ children: name
619
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
620
+ className: "truncate font-mono text-sm text-doom-dim",
621
+ title: root,
622
+ children: root
623
+ })]
624
+ }),
625
+ legacy ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
626
+ variant: "ghost",
627
+ size: "icon",
628
+ "data-testid": `workspace-new-session-${id}`,
629
+ title: "New session",
630
+ "aria-label": `New session in ${name}`,
631
+ disabled: !available,
632
+ onClick: () => actions.createSession(id),
633
+ className: "text-doom-faint hover:text-doom-hi",
634
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.PlusIcon, { className: "size-3.5" })
635
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuTrigger, {
636
+ asChild: true,
637
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
638
+ variant: "ghost",
639
+ size: "icon",
640
+ "data-testid": `workspace-menu-${id}`,
641
+ title: "Workspace actions",
642
+ "aria-label": `${name} actions`,
643
+ className: "text-doom-faint hover:text-doom-hi",
644
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.KebabIcon, { className: "size-3.5" })
645
+ })
646
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DropdownMenuContent, { children: [
647
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
648
+ disabled: !available,
649
+ onSelect: () => actions.resumeInWorkspace(id),
650
+ children: "resume session"
651
+ }),
652
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
653
+ disabled: !available,
654
+ onSelect: () => actions.openWorkspaceSettings(id),
655
+ children: "workspace settings"
656
+ }),
657
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DropdownMenuItem, {
658
+ variant: "destructive",
659
+ "data-testid": `workspace-delete-${id}`,
660
+ onSelect: () => {
661
+ setRemoveError("");
662
+ setRemoveOpen(true);
663
+ },
664
+ children: "delete workspace"
665
+ })
666
+ ] })] })] })
667
+ ]
668
+ }),
669
+ !available ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
670
+ className: "px-9 text-sm text-doom-red",
671
+ children: "Workspace unavailable"
672
+ }) : null,
673
+ workspace.sessions.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
674
+ className: "flex flex-col gap-1",
675
+ children: workspace.sessions.map((session) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedSessionCard, {
676
+ session,
677
+ actions
678
+ }, session.id))
679
+ }) : available ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
680
+ className: "px-9 pb-1 text-sm text-doom-dim",
681
+ children: "No sessions yet. Start or resume one."
682
+ }) : null,
683
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Dialog, {
684
+ open: removeOpen,
685
+ onOpenChange: (next) => !next && !removing && setRemoveOpen(false),
686
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogContent, {
687
+ width: "sm",
688
+ "data-testid": `workspace-delete-dialog-${id}`,
689
+ "aria-describedby": void 0,
690
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.DialogTitle, { children: "delete workspace" }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogBody, { children: [
691
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogDescription, { children: [
692
+ "this unregisters ",
693
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
694
+ className: "font-semibold text-doom-hi",
695
+ children: name
696
+ }),
697
+ " from Po only. files at",
698
+ " ",
699
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: root }),
700
+ " stay on disk. its sessions must be removed first."
701
+ ] }),
702
+ removeError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
703
+ "data-testid": `workspace-delete-error-${id}`,
704
+ className: "text-sm text-doom-red",
705
+ children: removeError
706
+ }) : null,
707
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.DialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
708
+ variant: "outline",
709
+ size: "md",
710
+ "data-testid": `workspace-delete-cancel-${id}`,
711
+ disabled: removing,
712
+ autoFocus: true,
713
+ onClick: () => setRemoveOpen(false),
714
+ children: "cancel"
715
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
716
+ variant: "danger",
717
+ size: "md",
718
+ "data-testid": `workspace-delete-confirm-${id}`,
719
+ disabled: removing,
720
+ onClick: () => void unregister(),
721
+ children: removing ? "deleting…" : "delete"
722
+ })] })
723
+ ] })]
724
+ })
725
+ })
726
+ ]
727
+ });
728
+ }
729
+ //#endregion
730
+ //#region src/extensions/(frontend)/template/_components/AdvancedRail.tsx
731
+ /** The persistent session rail: workspaces with their sessions, remote access, and settings. */
732
+ function AdvancedRail({ rail, onClose }) {
733
+ const { remote, actions } = rail;
734
+ const live = remote.status === "on" || remote.status === "starting";
735
+ const remoteDetail = remote.status === "on" ? `Remote access on, ${String(remote.deviceCount)} device${remote.deviceCount === 1 ? "" : "s"} paired` : void 0;
736
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
737
+ className: "flex min-h-full flex-col",
738
+ children: [
739
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
740
+ "data-po-session-rail-header": true,
741
+ className: "flex min-h-16 items-center justify-between gap-2 px-5 py-3",
742
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
743
+ className: "flex items-center gap-2.5",
744
+ "aria-label": "Po",
745
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
746
+ src: "/favicon.svg",
747
+ alt: "",
748
+ "aria-hidden": "true",
749
+ className: "size-9 rounded-lg"
750
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
751
+ "aria-hidden": "true",
752
+ className: "text-2xl font-semibold text-doom-hi",
753
+ children: "Po"
754
+ })]
755
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
756
+ className: "flex items-center gap-1",
757
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.Button, {
758
+ variant: remote.status === "failed" ? "danger-outline" : "outline",
759
+ size: "md",
760
+ "data-testid": "remote-access-open",
761
+ title: remoteDetail ?? "Remote access",
762
+ "aria-label": remoteDetail ?? `Remote access is ${remote.status}`,
763
+ onClick: actions.openRemoteAccess,
764
+ className: `gap-1.5 rounded-md ${remote.status === "failed" ? "" : "bg-doom-panel"}`,
765
+ children: [live ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Dot, {
766
+ tone: "yellow",
767
+ pulse: true,
768
+ "data-testid": "remote-access-live"
769
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.ShieldIcon, { className: "size-4" }), "Remote access"]
770
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
771
+ variant: "ghost",
772
+ size: "icon",
773
+ "data-testid": "mobile-sessions-close",
774
+ title: "Hide sessions",
775
+ "aria-label": "Hide sessions",
776
+ onClick: onClose,
777
+ className: "text-doom-dim md:hidden",
778
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.CloseIcon, { className: "size-3.5" })
779
+ })]
780
+ })]
781
+ }),
782
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
783
+ className: "flex items-center justify-between px-5 pt-4 pb-2",
784
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
785
+ className: "text-lg font-semibold text-doom-hi",
786
+ children: "Workspaces"
787
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
788
+ variant: "ghost",
789
+ size: "icon",
790
+ "data-testid": "add-workspace-open",
791
+ title: "Add workspace",
792
+ "aria-label": "Add workspace",
793
+ onClick: actions.openAddWorkspace,
794
+ className: "text-doom-faint hover:text-doom-hi",
795
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.PlusIcon, { className: "size-3.5" })
796
+ })]
797
+ }),
798
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
799
+ className: "flex flex-col gap-4 px-3 pb-3",
800
+ children: [rail.workspaces.map((workspace) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedWorkspaceGroup, {
801
+ workspace,
802
+ actions
803
+ }, workspace.id)), rail.workspaces.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
804
+ className: "flex flex-col gap-3 rounded-lg border border-dashed border-doom-border px-4 py-5",
805
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
806
+ className: "text-sm text-doom-dim",
807
+ children: "Add a folder to start working with Po."
808
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.Button, {
809
+ variant: "outline",
810
+ size: "md",
811
+ "data-testid": "add-workspace-empty",
812
+ onClick: actions.openAddWorkspace,
813
+ className: "justify-start gap-2 bg-doom-panel",
814
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.PlusIcon, { className: "size-3.5" }), "Add workspace"]
815
+ })]
816
+ }) : null]
817
+ }),
818
+ rail.pluginContent,
819
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "flex-1" }),
820
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
821
+ className: "sticky bottom-0 mt-auto shrink-0 bg-doom-rail",
822
+ children: [remote.status === "off" ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
823
+ "data-testid": "remote-banner",
824
+ className: `flex flex-col gap-1.5 border-t border-doom-border-soft px-4 py-2 text-sm ${remote.status === "failed" ? "bg-doom-tint-red text-doom-red" : "bg-doom-tint-yellow text-doom-yellow"}`,
825
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("output", {
826
+ className: "flex min-w-0 items-center gap-2",
827
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Dot, { tone: remote.status === "failed" ? "red" : "yellow" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
828
+ className: "truncate",
829
+ children: remote.status === "failed" ? `Remote access failed: ${remote.error ?? "the tunnel stopped"}` : `Remote access is ${remote.status === "starting" ? "starting" : "on"}${remote.host === void 0 ? "" : ` · ${remote.host}`} · ${String(remote.deviceCount)} device${remote.deviceCount === 1 ? "" : "s"} paired`
830
+ })]
831
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
832
+ className: "flex items-center justify-end gap-1",
833
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
834
+ variant: "ghost",
835
+ size: "sm",
836
+ "data-testid": "remote-banner-open",
837
+ onClick: actions.openRemoteAccess,
838
+ children: "Manage"
839
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
840
+ variant: "ghost",
841
+ size: "sm",
842
+ "data-testid": "remote-banner-off",
843
+ onClick: actions.turnRemoteAccessOff,
844
+ children: "Turn off"
845
+ })]
846
+ })]
847
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
848
+ className: "flex flex-col gap-1 border-t border-doom-border-soft px-3 py-3",
849
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_components.Button, {
850
+ variant: "ghost",
851
+ size: "lg",
852
+ "data-testid": "settings-open",
853
+ onClick: actions.openSettings,
854
+ className: "justify-start gap-2.5 px-2 text-doom-text",
855
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.GearIcon, { className: "size-5 text-doom-dim" }), "Settings"]
856
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
857
+ className: "px-2 text-sm text-doom-dim max-sm:hidden",
858
+ children: [
859
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Kbd, {
860
+ className: "bg-doom-panel",
861
+ children: "ctrl+k"
862
+ }),
863
+ " commands · ",
864
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Kbd, {
865
+ className: "bg-doom-panel",
866
+ children: "ctrl+t"
867
+ }),
868
+ " new session"
869
+ ]
870
+ })]
871
+ })]
872
+ })
873
+ ]
874
+ });
875
+ }
876
+ //#endregion
877
+ //#region src/extensions/(frontend)/template/_components/AdvancedLayout.tsx
878
+ /** This application's full cockpit frame, with each view mounted once. */
879
+ function AdvancedLayout({ view, slots, rail, navigationOpen, desktopActivityOpen, mobileActivityOpen, onNavigationOpenChange, onDesktopActivityOpenChange, onMobileActivityOpenChange }) {
880
+ const { scrollRef } = rail;
881
+ const conversation = view === "conversation" || view === "welcome";
882
+ const activityDockClass = mobileActivityOpen ? desktopActivityOpen ? "fixed inset-y-0 right-0 z-40 flex lg:static lg:z-auto" : "fixed inset-y-0 right-0 z-40 flex lg:hidden" : desktopActivityOpen ? "hidden lg:flex" : "hidden";
883
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
884
+ className: "relative flex h-full min-w-0 overflow-hidden",
885
+ children: [
886
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
887
+ ref: scrollRef,
888
+ "data-testid": "session-rail-panel",
889
+ className: `fixed inset-y-0 left-0 z-40 flex w-[min(320px,calc(100vw-48px))] shrink-0 flex-col overflow-y-auto border-r border-doom-border-soft bg-doom-rail transition-transform md:visible md:static md:z-auto md:w-[320px] md:translate-x-0 ${navigationOpen ? "visible translate-x-0" : "invisible -translate-x-full"}`,
890
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedRail, {
891
+ rail,
892
+ onClose: () => onNavigationOpenChange(false)
893
+ })
894
+ }),
895
+ navigationOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
896
+ variant: "ghost",
897
+ "data-testid": "mobile-drawer-backdrop",
898
+ "aria-label": "Hide sessions",
899
+ className: "fixed inset-0 z-30 h-auto w-auto rounded-none bg-black/55 p-0 hover:bg-black/55 md:hidden",
900
+ onClick: () => onNavigationOpenChange(false)
901
+ }) : null,
902
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
903
+ className: "flex min-w-0 flex-1 flex-col overflow-hidden",
904
+ children: [
905
+ slots.notices,
906
+ slots.header({
907
+ navigationToggle: "mobile",
908
+ activityToggle: "mobile"
909
+ }),
910
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
911
+ "data-testid": "template-content",
912
+ className: conversation ? "mx-auto flex min-h-0 w-full max-w-[960px] flex-1 flex-col overflow-hidden px-2 sm:px-4" : "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
913
+ children: [
914
+ slots.content,
915
+ slots.composer,
916
+ slots.controls
917
+ ]
918
+ })
919
+ ]
920
+ }),
921
+ slots.activity == null ? null : desktopActivityOpen || mobileActivityOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
922
+ className: activityDockClass,
923
+ children: slots.activity
924
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
925
+ variant: "ghost",
926
+ "data-testid": "activity-show",
927
+ title: "Show activity",
928
+ onClick: () => onDesktopActivityOpenChange(true),
929
+ className: "hidden h-auto shrink-0 rounded-none border-l border-doom-border-soft bg-doom-rail px-2 py-3 font-semibold text-doom-dim hover:bg-doom-panel hover:text-doom-hi lg:flex",
930
+ style: { writingMode: "vertical-rl" },
931
+ children: "Activity"
932
+ }),
933
+ mobileActivityOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
934
+ variant: "ghost",
935
+ "data-testid": "mobile-activity-backdrop",
936
+ "aria-label": "Hide activity",
937
+ className: "fixed inset-0 z-30 h-auto w-auto rounded-none bg-black/55 p-0 hover:bg-black/55 lg:hidden",
938
+ onClick: () => onMobileActivityOpenChange(false)
939
+ }) : null,
940
+ rail.addWorkspace ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedAddWorkspaceDialog, {
941
+ suggestedPaths: rail.addWorkspace.suggestedPaths,
942
+ actions: rail.actions
943
+ }) : null
944
+ ]
945
+ });
946
+ }
947
+ //#endregion
948
+ //#region src/extensions/(frontend)/template/_components/AdvancedConversation.tsx
949
+ function AdvancedConversation() {
950
+ (0, _agimon_ai_po_web_dashboard.useWebPluginRegistry)();
951
+ const dockOpen = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.uiStore, (state) => state.dockOpen);
952
+ const [railOpen, setRailOpen] = (0, react.useState)(false);
953
+ const [mobileActivityOpen, setMobileActivityOpen] = (0, react.useState)(false);
954
+ const { sessionId, tabId } = (0, _agimon_ai_po_web_dashboard.useDashboardRoute)();
955
+ const slotProps = (0, _agimon_ai_po_web_dashboard.usePluginSlotProps)(sessionId ?? null);
956
+ const sessionWorkspaceId = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.sessionsStore, (state) => sessionId === void 0 ? void 0 : state.byId[sessionId]?.summary.workspaceId);
957
+ const selectedWorkspaceId = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.workspacesStore, (state) => state.selectedId);
958
+ const mcp = (0, _agimon_ai_po_web_dashboard.useSessionMcp)(sessionId === void 0 ? selectedWorkspaceId ?? void 0 : sessionWorkspaceId, sessionId);
959
+ const mcpView = tabId === "mcp";
960
+ const mcpEnabled = mcp.snapshot?.enabled === true || mcpView;
961
+ const transferLabel = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.sessionsStore, (state) => {
962
+ if (state.transferringToId === null) return null;
963
+ return state.byId[state.transferringToId]?.summary.name ?? "destination session";
964
+ });
965
+ const noSessions = (0, _agimon_ai_po_web_dashboard.useNoSessions)();
966
+ const activeMeta = (0, _agimon_ai_po_web_dashboard.useActiveSessionMeta)();
967
+ const dormantMeta = activeMeta?.summary.dormant === true ? activeMeta : null;
968
+ const dialogId = (0, _agimon_ai_po_web_dashboard.useActiveSession)((state) => state.dialog?.id ?? null);
969
+ const storedTransientTab = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.transientTabsStore, (state) => (0, _agimon_ai_po_web_dashboard.findTransientTab)(state, sessionId, tabId));
970
+ const transientTab = storedTransientTab === void 0 ? void 0 : (0, _agimon_ai_po_web_dashboard.pluginActivityGroups)().map((group) => group.transientTab?.()).find((candidate) => candidate?.id === storedTransientTab.id) ?? storedTransientTab;
971
+ const tab = (tabId === void 0 ? void 0 : (0, _agimon_ai_po_web_dashboard.webTabs)().find((entry) => entry.id === tabId)) ?? transientTab;
972
+ const composerContext = tab === transientTab ? transientTab?.composerContext : void 0;
973
+ const routeKey = `${sessionId ?? ""}\u0000${tabId ?? ""}`;
974
+ const [lastRouteKey, setLastRouteKey] = (0, react.useState)(routeKey);
975
+ if (lastRouteKey !== routeKey) {
976
+ setLastRouteKey(routeKey);
977
+ setRailOpen(false);
978
+ setMobileActivityOpen(false);
979
+ }
980
+ const [lastDialogId, setLastDialogId] = (0, react.useState)(dialogId);
981
+ if (lastDialogId !== dialogId) {
982
+ setLastDialogId(dialogId);
983
+ if (dialogId !== null) {
984
+ setMobileActivityOpen(false);
985
+ setRailOpen(false);
986
+ }
987
+ }
988
+ const rail = (0, _agimon_ai_po_web_dashboard_views.useSessionRail)({ onDismiss: () => setRailOpen(false) });
989
+ const closeActivity = () => {
990
+ if (mobileActivityOpen) setMobileActivityOpen(false);
991
+ else (0, _agimon_ai_po_web_dashboard.setDockOpen)(false);
992
+ };
993
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
994
+ "data-testid": "cockpit",
995
+ className: "h-full min-w-0 overflow-hidden",
996
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedLayout, {
997
+ view: mcpView || tab ? "panel" : noSessions ? "welcome" : "conversation",
998
+ navigationOpen: railOpen,
999
+ desktopActivityOpen: dockOpen,
1000
+ mobileActivityOpen,
1001
+ onNavigationOpenChange: setRailOpen,
1002
+ onDesktopActivityOpenChange: _agimon_ai_po_web_dashboard.setDockOpen,
1003
+ onMobileActivityOpenChange: setMobileActivityOpen,
1004
+ rail,
1005
+ slots: {
1006
+ header: (options) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.TopBar, {
1007
+ ...options,
1008
+ view: mcpView ? "mcp" : tab?.id ?? "conversation",
1009
+ mcpEnabled,
1010
+ onShowSessions: () => {
1011
+ setMobileActivityOpen(false);
1012
+ setRailOpen(true);
1013
+ },
1014
+ onShowActivity: () => {
1015
+ setRailOpen(false);
1016
+ setMobileActivityOpen(true);
1017
+ }
1018
+ }),
1019
+ notices: transferLabel === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("output", {
1020
+ "data-testid": "voice-transfer-transition",
1021
+ className: "border-b border-doom-cyan/30 bg-doom-cyan/10 px-4 py-2 text-center text-base font-medium text-doom-cyan",
1022
+ children: [
1023
+ "Transferring voice to ",
1024
+ transferLabel,
1025
+ "..."
1026
+ ]
1027
+ }),
1028
+ content: mcpView ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SessionMcp, { state: mcp }, sessionId) : tab ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(tab.panel, { ...slotProps }) : noSessions ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.WelcomePanel, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.Timeline, {}),
1029
+ composer: mcpView ? null : tab ? tab.retainComposer === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.Composer, { composerContext }) : null : noSessions ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.Composer, {}),
1030
+ controls: !mcpView && !tab && !noSessions && dormantMeta === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SelectionBar, {}) : null,
1031
+ activity: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.ActivityDock, {
1032
+ mcp,
1033
+ onClose: closeActivity,
1034
+ onOpenContent: () => setMobileActivityOpen(false)
1035
+ })
1036
+ }
1037
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SessionRailDialogs, {})]
1038
+ });
1039
+ }
1040
+ //#endregion
1041
+ //#region src/extensions/(frontend)/template/_components/AdvancedSettings.tsx
1042
+ /** Settings have their own page frame, independent of session navigation. */
1043
+ function AdvancedSettings() {
1044
+ (0, _agimon_ai_po_web_dashboard.useWebPluginRegistry)();
1045
+ const { section, workspaceId } = (0, _agimon_ai_po_web_dashboard.useDashboardRoute)();
1046
+ const navigate = (0, _tanstack_react_router.useNavigate)();
1047
+ const activeId = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.sessionsStore, (state) => state.activeId);
1048
+ const [loadError, setLoadError] = (0, react.useState)();
1049
+ const [repositoryReady, setRepositoryReady] = (0, react.useState)(false);
1050
+ const [templateTarget, setTemplateTarget] = (0, _agimon_ai_po_web_dashboard.useDashboardState)("settings/template-target", "global");
1051
+ const current = (0, _agimon_ai_po_web_dashboard.settingsSection)(section);
1052
+ const workspace = current?.workspace ?? (section?.startsWith("repository-") ? "repository" : "general");
1053
+ (0, react.useEffect)(() => {
1054
+ if (current) return;
1055
+ if (workspace === "repository" && !repositoryReady) return;
1056
+ let cancelled = false;
1057
+ (0, _agimon_ai_po_web_dashboard.refreshWebPluginCompositions)().then(() => {
1058
+ if (cancelled || (0, _agimon_ai_po_web_dashboard.settingsSection)(section)) return;
1059
+ navigate({
1060
+ to: "/settings/$section",
1061
+ params: { section: _agimon_ai_po_web_dashboard.DEFAULT_SETTINGS_SECTION },
1062
+ search: { workspace: workspaceId },
1063
+ replace: true
1064
+ });
1065
+ }).catch((error) => {
1066
+ if (!cancelled) setLoadError(error instanceof Error ? error.message : String(error));
1067
+ });
1068
+ return () => {
1069
+ cancelled = true;
1070
+ };
1071
+ }, [
1072
+ current,
1073
+ section,
1074
+ navigate,
1075
+ workspace,
1076
+ workspaceId,
1077
+ repositoryReady
1078
+ ]);
1079
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1080
+ "data-testid": "settings",
1081
+ className: "flex h-full min-h-0 min-w-0 flex-col overflow-hidden bg-doom-bg",
1082
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
1083
+ className: "grid shrink-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-x-2 gap-y-2 border-b border-doom-border px-3 py-2 sm:h-14 sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] sm:px-6 sm:py-0",
1084
+ children: [
1085
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
1086
+ className: "order-1 min-w-0 truncate text-xl font-semibold text-doom-hi sm:order-none",
1087
+ children: "Settings"
1088
+ }),
1089
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
1090
+ className: "order-3 col-span-2 flex w-full items-center gap-1 rounded-lg bg-doom-panel p-1 sm:order-none sm:col-span-1 sm:w-auto",
1091
+ "aria-label": "settings workspace",
1092
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.NavTab, {
1093
+ asChild: true,
1094
+ active: workspace === "general",
1095
+ className: "min-h-8 flex-1 justify-center rounded-md px-4 focus-visible:ring-2 focus-visible:ring-doom-green sm:flex-none",
1096
+ "aria-current": workspace === "general" ? "true" : void 0,
1097
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tanstack_react_router.Link, {
1098
+ to: "/settings/$section",
1099
+ params: { section: _agimon_ai_po_web_dashboard.DEFAULT_SETTINGS_SECTION },
1100
+ search: { workspace: workspaceId },
1101
+ "data-testid": "settings-workspace-general",
1102
+ children: "General"
1103
+ })
1104
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.NavTab, {
1105
+ asChild: true,
1106
+ active: workspace === "repository",
1107
+ className: "min-h-8 flex-1 justify-center rounded-md px-4 focus-visible:ring-2 focus-visible:ring-doom-green sm:flex-none",
1108
+ "aria-current": workspace === "repository" ? "true" : void 0,
1109
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tanstack_react_router.Link, {
1110
+ to: "/settings/$section",
1111
+ params: { section: _agimon_ai_po_web_dashboard.DEFAULT_REPOSITORY_SETTINGS_SECTION },
1112
+ search: { workspace: workspaceId },
1113
+ "data-testid": "settings-workspace-repository",
1114
+ children: "Workspaces"
1115
+ })
1116
+ })]
1117
+ }),
1118
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_components.Button, {
1119
+ asChild: true,
1120
+ variant: "ghost",
1121
+ size: "sm",
1122
+ className: "order-2 sm:order-none sm:justify-self-end",
1123
+ children: activeId !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_tanstack_react_router.Link, {
1124
+ to: "/session/$sessionId",
1125
+ params: { sessionId: activeId },
1126
+ "data-testid": "settings-close",
1127
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1128
+ className: "sm:hidden",
1129
+ children: "Back"
1130
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1131
+ className: "hidden sm:inline",
1132
+ children: "Back to session"
1133
+ })]
1134
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tanstack_react_router.Link, {
1135
+ to: "/",
1136
+ "data-testid": "settings-close",
1137
+ children: "Back"
1138
+ })
1139
+ })
1140
+ ]
1141
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
1142
+ className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
1143
+ children: workspace === "repository" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.RepositoryWorkspace, {
1144
+ current: current ?? {
1145
+ id: section ?? "",
1146
+ label: "",
1147
+ detail: "",
1148
+ workspace: "repository"
1149
+ },
1150
+ initialRepositoryId: workspaceId,
1151
+ onRepositoryChange: (nextWorkspaceId) => {
1152
+ navigate({
1153
+ to: "/settings/$section",
1154
+ params: { section: current?.id ?? section ?? _agimon_ai_po_web_dashboard.DEFAULT_REPOSITORY_SETTINGS_SECTION },
1155
+ search: { workspace: nextWorkspaceId },
1156
+ replace: true
1157
+ });
1158
+ },
1159
+ onReady: setRepositoryReady
1160
+ }, workspaceId ?? "remembered-workspace") : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1161
+ className: "flex min-h-0 flex-1 flex-col lg:flex-row",
1162
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SettingsMenu, {
1163
+ active: current?.id,
1164
+ workspace: "general",
1165
+ repositoryId: workspaceId
1166
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
1167
+ "data-testid": "settings-content",
1168
+ className: "min-w-0 flex-1 overflow-y-auto px-4 py-6 sm:px-6 sm:py-8 lg:px-8 lg:py-10",
1169
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1170
+ className: "mx-auto flex w-full max-w-[720px] flex-col gap-8",
1171
+ children: [
1172
+ !current && loadError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1173
+ role: "alert",
1174
+ children: loadError
1175
+ }) : null,
1176
+ current?.id === "providers" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.ProviderSettings, {}) : null,
1177
+ current?.id === "appearance" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.AppearanceSettings, {
1178
+ templateTarget,
1179
+ onTemplateTargetChange: setTemplateTarget
1180
+ }) : null,
1181
+ current?.id === "notifications" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.NotificationSettings, {}) : null,
1182
+ current?.id === "images" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.ImageSettings, {}) : null,
1183
+ current?.id === "remote" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.RemoteControlSettings, {}) : null,
1184
+ current?.id === "plugins" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.PluginSettings, {}) : null,
1185
+ current?.contribution === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.ContributedSettings, {
1186
+ section: current.contribution,
1187
+ scope: "global"
1188
+ }),
1189
+ current?.panel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SettingsPanelHost, { panel: current.panel })
1190
+ ]
1191
+ })
1192
+ })]
1193
+ })
1194
+ })]
1195
+ });
1196
+ }
1197
+ //#endregion
1198
+ //#region src/extensions/(frontend)/template/_components/AdvancedDashboard.tsx
1199
+ const renderers = {
1200
+ thread: (id, threadId, options) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.ThreadView, {
1201
+ sessionId: id,
1202
+ threadId,
1203
+ options
1204
+ }),
1205
+ activity: (id, open) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SessionActivity, {
1206
+ sessionId: id,
1207
+ onOpenConversation: open
1208
+ }),
1209
+ transcript: (id, options) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.SessionTranscriptView, {
1210
+ sessionId: id,
1211
+ options,
1212
+ watch: _agimon_ai_po_web_dashboard.watchDashboardTranscript
1213
+ })
1214
+ };
1215
+ function AdvancedDashboard() {
1216
+ const route = (0, _agimon_ai_po_web_dashboard.useDashboardRoute)();
1217
+ const sessionId = (0, _tanstack_react_store.useStore)(_agimon_ai_po_web_dashboard.sessionsStore, (state) => state.activeId);
1218
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_agimon_ai_po_web_dashboard.DashboardRendererProvider, {
1219
+ value: renderers,
1220
+ children: [
1221
+ route.kind === "settings" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedSettings, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdvancedConversation, {}),
1222
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.DialogOverlay, {}),
1223
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.RefusedCard, {}),
1224
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.CommandPalette, {}),
1225
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.PluginSurface, {
1226
+ slot: _agimon_ai_po_web_dashboard.HOST_SLOTS.overlay,
1227
+ sessionId
1228
+ }),
1229
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.RemoteAccessDialog, {}),
1230
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_agimon_ai_po_web_dashboard_views.PairingApprovalDialog, {})
1231
+ ]
1232
+ });
1233
+ }
1234
+ //#endregion
1235
+ //#region src/extensions/(frontend)/template/_lib/definition.ts
1236
+ const advancedTemplate = {
1237
+ label: "Advanced",
1238
+ description: "The full cockpit with persistent session navigation and an activity dock.",
1239
+ contractVersion: 2,
1240
+ app: AdvancedDashboard
1241
+ };
1242
+ //#endregion
1243
+ //#region src/extensions/(frontend)/template/po-template-advanced.web.ts
1244
+ var po_template_advanced_web_default$2 = (0, _agimon_ai_po_core_web.defineWebTemplate)(advancedTemplate);
1245
+ //#endregion
1246
+ //#region src/extensions/workspaces/(frontend)/template/po-template-advanced.web.ts
1247
+ var po_template_advanced_web_default$1 = (0, _agimon_ai_po_core_web.defineWebTemplate)(advancedTemplate);
1248
+ //#endregion
1249
+ //#region src/extensions/workspaces/sessions/(frontend)/template/po-template-advanced.web.ts
1250
+ var po_template_advanced_web_default = (0, _agimon_ai_po_core_web.defineWebTemplate)(advancedTemplate);
1251
+ //#endregion
1252
+ //#region generated/web.ts
1253
+ const via = (identity, value) => value === void 0 ? void 0 : {
1254
+ ...identity,
1255
+ ...value
1256
+ };
1257
+ const webPlugin = (0, _agimon_ai_po_core_web.defineWebPlugin)({
1258
+ id: "template-advanced",
1259
+ global: { get templates() {
1260
+ return [via({ id: "po-template-advanced" }, po_template_advanced_web_default$2)];
1261
+ } },
1262
+ workspace: { get templates() {
1263
+ return [via({ id: "po-template-advanced" }, po_template_advanced_web_default$1)];
1264
+ } },
1265
+ session: { get templates() {
1266
+ return [via({ id: "po-template-advanced" }, po_template_advanced_web_default)];
1267
+ } }
1268
+ });
1269
+ //#endregion
1270
+ exports.webPlugin = webPlugin;
1271
+
1272
+ //# sourceMappingURL=webClient.cjs.map