@agimon-ai/doompi-template-elegant 0.0.1-alpha.22 → 0.0.1-alpha.23
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/extensions/web.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineWebPlugin, defineWebTemplate } from "@agimon-ai/doompi-core/web";
|
|
2
|
-
import { AlertIcon, Avatar, AvatarFallback, AvatarImage, BranchIcon, Button, ChevronUpIcon, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Dot, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, ForkIcon, GearIcon, Input, KebabIcon, OptionRow, PlusIcon, ShieldIcon, cn } from "@agimon-ai/doompi-web-components";
|
|
2
|
+
import { ActivityIcon, AlertIcon, Avatar, AvatarFallback, AvatarImage, BranchIcon, Button, ChevronUpIcon, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Dot, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, ForkIcon, GearIcon, Input, KebabIcon, OptionRow, PlusIcon, ShieldIcon, cn } from "@agimon-ai/doompi-web-components";
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/extensions/(frontend)/template/_components/ElegantFolderBrowser.tsx
|
|
@@ -365,7 +365,10 @@ function ElegantSessionCard({ session, actions }) {
|
|
|
365
365
|
/* @__PURE__ */ jsxs("div", {
|
|
366
366
|
className: "flex items-center gap-1.5",
|
|
367
367
|
children: [
|
|
368
|
-
session.nested && session.provenance ? /* @__PURE__ */ jsx(
|
|
368
|
+
session.nested && session.provenance === "workflow-session" ? /* @__PURE__ */ jsx(ActivityIcon, {
|
|
369
|
+
"aria-label": "workflow session",
|
|
370
|
+
className: `h-[11px] w-[11px] shrink-0 ${active ? "text-doom-on-selected" : "text-doom-faint"}`
|
|
371
|
+
}) : session.nested && session.provenance ? /* @__PURE__ */ jsx(ForkIcon, {
|
|
369
372
|
"aria-label": session.provenance === "worktree" ? "automatic per-conversation worktree" : session.provenance,
|
|
370
373
|
className: `h-[11px] w-[11px] shrink-0 ${active ? "text-doom-on-selected" : "text-doom-faint"}`
|
|
371
374
|
}) : null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.mjs","names":["folderName","templateDoompiTemplateElegant","templateDoompiTemplateElegant2","templateDoompiTemplateElegant3"],"sources":["../../src/extensions/(frontend)/template/_components/ElegantFolderBrowser.tsx","../../src/extensions/(frontend)/template/_components/ElegantAddWorkspaceDialog.tsx","../../src/extensions/(frontend)/template/_components/ElegantPendingSetup.tsx","../../src/extensions/(frontend)/template/_components/ElegantSessionCard.tsx","../../src/extensions/(frontend)/template/_components/ElegantWorkspaceGroup.tsx","../../src/extensions/(frontend)/template/_components/ElegantRail.tsx","../../src/extensions/(frontend)/template/_components/ElegantLayout.tsx","../../src/extensions/(frontend)/template/_lib/definition.ts","../../src/extensions/(frontend)/template/doompi-template-elegant.web.ts","../../src/extensions/workspaces/(frontend)/template/doompi-template-elegant.web.ts","../../src/extensions/workspaces/sessions/(frontend)/template/doompi-template-elegant.web.ts","../../generated/web.ts"],"sourcesContent":["import type { WebTemplateRailActions, WebTemplateRailDirectoryListing } from '@agimon-ai/doompi-core/web';\nimport { Button, ChevronUpIcon, OptionRow } from '@agimon-ai/doompi-web-components';\nimport { useEffect, useState } from 'react';\n\nfunction folderName(path: string): string {\n return path.slice(path.lastIndexOf('/') + 1) || path;\n}\n\n/** Walks the server's folders inline: up, into a child, or pick the current folder. */\nexport function ElegantFolderBrowser({\n start,\n listDirectory,\n onSelect,\n}: {\n /** Folder to open first; home when absent. */\n start?: string;\n listDirectory: WebTemplateRailActions['listDirectory'];\n onSelect: (path: string) => void;\n}) {\n const [target, setTarget] = useState(start);\n const [listing, setListing] = useState<WebTemplateRailDirectoryListing | null>(null);\n const [error, setError] = useState('');\n\n useEffect(() => {\n let stale = false;\n void listDirectory(target).then((result) => {\n if (stale) return;\n if ('error' in result) setError(result.error);\n else {\n setError('');\n setListing(result);\n }\n });\n return () => {\n stale = true;\n };\n }, [target, listDirectory]);\n\n return (\n <div\n data-testid=\"folder-browser\"\n className=\"flex flex-col gap-1 rounded-lg border border-doom-border-soft bg-doom-panel/40 p-1.5\"\n >\n <div className=\"flex items-center gap-1 px-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"folder-browser-up\"\n title=\"parent folder\"\n aria-label=\"parent folder\"\n disabled={listing?.parent === undefined}\n onClick={() => listing?.parent !== undefined && setTarget(listing.parent)}\n >\n <ChevronUpIcon className=\"h-3 w-3\" />\n </Button>\n <span className=\"min-w-0 flex-1 truncate text-xs text-doom-dim\" title={listing?.path}>\n {listing?.path ?? 'loading…'}\n </span>\n <Button\n variant=\"outline\"\n size=\"xs\"\n data-testid=\"folder-browser-select\"\n disabled={listing === null}\n onClick={() => listing !== null && onSelect(listing.path)}\n >\n use this folder\n </Button>\n </div>\n {error ? <p className=\"px-2 py-1 text-xs text-doom-red\">{error}</p> : null}\n <div role=\"listbox\" aria-label=\"folders\" className=\"max-h-40 overflow-y-auto\">\n {listing !== null && listing.directories.length === 0 ? (\n <p className=\"px-2 py-1 text-2xs text-doom-faint\">no folders here</p>\n ) : null}\n {listing?.directories.map((directory) => (\n <OptionRow\n key={directory}\n density=\"compact\"\n data-testid=\"folder-browser-entry\"\n onClick={() => setTarget(directory)}\n className=\"w-full px-2.5 py-1 text-sm\"\n >\n {folderName(directory)}\n </OptionRow>\n ))}\n </div>\n </div>\n );\n}\n","import type { WebTemplateRailActions } from '@agimon-ai/doompi-core/web';\nimport {\n Button,\n Dialog,\n DialogBody,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n OptionRow,\n} from '@agimon-ai/doompi-web-components';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { ElegantFolderBrowser } from './ElegantFolderBrowser';\n\nconst SUGGESTION_DEBOUNCE_MS = 120;\nconst NO_HIGHLIGHT = -1;\nconst TRAILING_SEPARATORS = /\\/+$/u;\n\nfunction folderName(path: string): string {\n const trimmed = path.trim().replace(TRAILING_SEPARATORS, '');\n return trimmed.slice(trimmed.lastIndexOf('/') + 1);\n}\n\n/** Adds a workspace by name, by folder, or both; a name alone gets a new default folder. */\nexport function ElegantAddWorkspaceDialog({\n suggestedPaths,\n actions,\n}: {\n suggestedPaths: readonly string[];\n actions: WebTemplateRailActions;\n}) {\n const [name, setName] = useState('');\n // The name follows the folder until the user types their own.\n const [nameEdited, setNameEdited] = useState(false);\n const [path, setPath] = useState(suggestedPaths[0] ?? '');\n const [browsing, setBrowsing] = useState(false);\n const [suggestions, setSuggestions] = useState<readonly string[]>([]);\n const [highlight, setHighlight] = useState(NO_HIGHLIGHT);\n const [error, setError] = useState('');\n const [busy, setBusy] = useState(false);\n const pathInput = useRef<HTMLInputElement>(null);\n const shownName = nameEdited ? name : folderName(path);\n\n useEffect(() => {\n const typed = path.trim();\n if (typed === '') return;\n let stale = false;\n const timer = setTimeout(async () => {\n const found = await actions.searchDirectories(typed);\n if (stale) return;\n setSuggestions(found.filter((directory) => directory !== typed));\n setHighlight(NO_HIGHLIGHT);\n }, SUGGESTION_DEBOUNCE_MS);\n return () => {\n stale = true;\n clearTimeout(timer);\n };\n }, [path, actions]);\n\n const changePath = (next: string): void => {\n setPath(next);\n if (next.trim() === '') setSuggestions([]);\n };\n const pick = (directory: string): void => {\n changePath(`${directory}/`);\n pathInput.current?.focus();\n };\n const trimmedPath = path.trim().replace(TRAILING_SEPARATORS, '') || (path.trim() === '' ? '' : '/');\n const canSubmit = !busy && (trimmedPath !== '' || shownName.trim() !== '');\n const submit = async (): Promise<void> => {\n if (!canSubmit) return;\n setBusy(true);\n setError('');\n const result = await actions.addWorkspace({\n name: shownName.trim(),\n ...(trimmedPath === '' ? {} : { path: trimmedPath }),\n });\n setBusy(false);\n if (result !== undefined) setError(result.error);\n };\n\n return (\n <Dialog open onOpenChange={(next) => !next && !busy && actions.closeAddWorkspace()}>\n <DialogContent width=\"md\" data-testid=\"add-workspace-dialog\" aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>add workspace</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <label htmlFor=\"add-workspace-name\" className=\"flex flex-col gap-1\">\n <span className=\"text-xs text-doom-faint\">name</span>\n <Input\n id=\"add-workspace-name\"\n data-testid=\"add-workspace-name\"\n value={shownName}\n autoFocus\n onChange={(event) => {\n setNameEdited(true);\n setName(event.target.value);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') void submit();\n }}\n placeholder=\"my-project\"\n />\n </label>\n <label htmlFor=\"add-workspace-root\" className=\"flex flex-col gap-1\">\n <span className=\"text-xs text-doom-faint\">\n folder <span className=\"text-doom-faint\">(optional; type a path or browse)</span>\n </span>\n <span className=\"flex items-center gap-1.5\">\n <Input\n id=\"add-workspace-root\"\n ref={pathInput}\n data-testid=\"add-workspace-root\"\n value={path}\n onChange={(event) => changePath(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' && suggestions.length > 0) {\n event.preventDefault();\n setHighlight((current) => (current + 1) % suggestions.length);\n } else if (event.key === 'ArrowUp' && suggestions.length > 0) {\n event.preventDefault();\n setHighlight((current) => (current <= 0 ? suggestions.length - 1 : current - 1));\n } else if (event.key === 'Enter') {\n const chosen = highlight === NO_HIGHLIGHT ? undefined : suggestions[highlight];\n if (chosen === undefined) void submit();\n else pick(chosen);\n }\n }}\n placeholder=\"~/workspace/my-project\"\n className=\"min-w-0 flex-1\"\n />\n <Button\n variant={browsing ? 'subtle' : 'outline'}\n size=\"md\"\n data-testid=\"add-workspace-browse\"\n aria-pressed={browsing}\n onClick={() => setBrowsing((open) => !open)}\n >\n browse\n </Button>\n </span>\n </label>\n {browsing ? (\n <ElegantFolderBrowser\n {...(trimmedPath.startsWith('/') ? { start: trimmedPath } : {})}\n listDirectory={actions.listDirectory}\n onSelect={(selected) => {\n changePath(selected);\n setBrowsing(false);\n }}\n />\n ) : suggestions.length > 0 ? (\n <div\n role=\"listbox\"\n aria-label=\"matching directories\"\n data-testid=\"add-workspace-suggestions\"\n className=\"max-h-40 overflow-y-auto rounded-lg border border-doom-border-soft bg-doom-panel/40 p-1.5\"\n >\n {suggestions.map((directory, index) => (\n <OptionRow\n key={directory}\n density=\"compact\"\n active={index === highlight}\n data-testid=\"add-workspace-suggestion\"\n onMouseDown={(event) => event.preventDefault()}\n onMouseEnter={() => setHighlight(index)}\n onClick={() => pick(directory)}\n className=\"w-full px-2.5 py-1 text-sm\"\n >\n {directory}\n </OptionRow>\n ))}\n </div>\n ) : null}\n {suggestedPaths.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {suggestedPaths.slice(0, 4).map((suggested) => (\n <Button key={suggested} variant=\"outline\" size=\"xs\" onClick={() => changePath(suggested)}>\n {suggested}\n </Button>\n ))}\n </div>\n ) : null}\n {trimmedPath === '' && shownName.trim() !== '' ? (\n <p data-testid=\"add-workspace-default-hint\" className=\"text-xs text-doom-faint\">\n creates ~/.pi/.doom/workspace/{shownName.trim()}\n </p>\n ) : null}\n {error ? (\n <pre className=\"max-h-28 overflow-y-auto rounded border border-doom-edge-red bg-doom-tint-red/40 px-2.5 py-2 text-xs whitespace-pre-wrap text-doom-red\">\n {error}\n </pre>\n ) : null}\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => actions.closeAddWorkspace()} disabled={busy}>\n cancel\n </Button>\n <Button\n variant=\"primary\"\n data-testid=\"add-workspace-confirm\"\n onClick={() => void submit()}\n disabled={!canSubmit}\n >\n {busy ? 'adding…' : 'add workspace'}\n </Button>\n </DialogFooter>\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailPendingSetup } from '@agimon-ai/doompi-core/web';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n KebabIcon,\n} from '@agimon-ai/doompi-web-components';\nimport { useState } from 'react';\n\n/** A setup-only reservation: no runtime, so it offers removal and nothing else. */\nexport function ElegantPendingSetup({\n sessionId,\n setup,\n actions,\n}: {\n sessionId: string;\n setup: WebTemplateRailPendingSetup;\n actions: WebTemplateRailActions;\n}) {\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState('');\n const remove = async (): Promise<void> => {\n if (busy) return;\n setBusy(true);\n setError('');\n const result = await actions.removePendingSetup(sessionId, setup.id);\n setBusy(false);\n if (result !== undefined) setError(result.error);\n };\n return (\n <div\n data-testid={`pending-session-${setup.id}`}\n className=\"ml-9 flex flex-col gap-0.5 rounded-lg border border-dashed border-doom-border-soft px-3 py-2\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-xs font-bold text-doom-hi\">{setup.name}</span>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"session setup actions\"\n disabled={busy}\n data-testid={`pending-session-menu-${setup.id}`}\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem variant=\"destructive\" onSelect={() => void remove()}>\n remove setup\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <p className={setup.failed ? 'text-2xs text-doom-red' : 'text-2xs text-doom-faint'}>{setup.status}</p>\n {setup.recovery ? (\n <p role={setup.failed ? 'alert' : undefined} className=\"text-2xs text-doom-faint\">\n {setup.recovery}\n </p>\n ) : null}\n {error ? (\n <p role=\"alert\" className=\"text-2xs text-doom-red\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailSession } from '@agimon-ai/doompi-core/web';\nimport {\n AlertIcon,\n Avatar,\n AvatarFallback,\n AvatarImage,\n BranchIcon,\n Button,\n cn,\n Dialog,\n DialogBody,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n ForkIcon,\n Input,\n KebabIcon,\n} from '@agimon-ai/doompi-web-components';\nimport { useRef, useState } from 'react';\n\nimport { ElegantPendingSetup } from './ElegantPendingSetup';\n\ntype CardMode = 'view' | 'menu' | 'rename' | 'confirm';\n\n/** A soft tile led by the persona avatar, with the branch as a quiet caption. */\nexport function ElegantSessionCard({\n session,\n actions,\n}: {\n session: WebTemplateRailSession;\n actions: WebTemplateRailActions;\n}) {\n const [mode, setMode] = useState<CardMode>('view');\n const [draft, setDraft] = useState('');\n const [removeError, setRemoveError] = useState('');\n // Written by the event that changes the mode, so the menu's close-focus handler\n // sees the new mode before React re-renders the card.\n const modeRef = useRef(mode);\n const enterMode = (next: CardMode): void => {\n modeRef.current = next;\n setMode(next);\n };\n const { active } = session;\n const error = removeError || session.error;\n const tileClass = active\n ? 'rounded-lg bg-doom-selected hover:bg-doom-selected'\n : 'rounded-lg bg-doom-panel/40 hover:bg-doom-panel';\n const commitRename = (): void => {\n actions.renameSession(session.id, draft);\n enterMode('view');\n };\n const remove = async (): Promise<void> => {\n enterMode('view');\n setRemoveError('');\n const result = await actions.removeSession(session.id);\n if (result !== undefined) setRemoveError(result.error);\n };\n\n const body = (\n <div className=\"flex items-start gap-2.5\">\n <Avatar\n data-testid={session.profile ? 'session-avatar' : undefined}\n aria-label={session.profile?.label ?? 'DoomPi'}\n title={session.profile?.label}\n className=\"mt-0.5 h-7 w-7 shrink-0 border border-doom-border-soft bg-doom-deep\"\n >\n {session.profile?.avatarUrl ? <AvatarImage src={session.profile.avatarUrl} alt=\"\" /> : null}\n <AvatarFallback className=\"text-2xs text-doom-magenta\">{session.profile?.initials ?? 'DP'}</AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <div className=\"flex items-center gap-1.5\">\n {session.nested && session.provenance ? (\n <ForkIcon\n aria-label={\n session.provenance === 'worktree' ? 'automatic per-conversation worktree' : session.provenance\n }\n className={`h-[11px] w-[11px] shrink-0 ${active ? 'text-doom-on-selected' : 'text-doom-faint'}`}\n />\n ) : null}\n <span\n className={`min-w-0 flex-1 truncate text-sm font-bold ${active ? 'text-doom-on-selected' : 'text-doom-hi'}`}\n >\n {session.name || 'untitled'}\n </span>\n {session.ordinal <= 9 ? (\n <span\n title={`press ${String(session.ordinal)} to focus`}\n className={`shrink-0 text-2xs transition-opacity group-focus-within:opacity-0 group-hover:opacity-0 ${\n active ? 'text-doom-on-selected/70' : 'text-doom-faint'\n }`}\n >\n {session.ordinal}\n </span>\n ) : null}\n </div>\n <span className=\"flex items-start gap-1\">\n {session.awaitingInput ? (\n <AlertIcon\n data-testid=\"session-awaiting-input\"\n aria-label=\"waiting for your input\"\n className=\"mt-[2px] h-[11px] w-[11px] shrink-0 text-doom-red\"\n />\n ) : null}\n <span\n data-testid=\"session-status\"\n className={`truncate text-xs ${session.awaitingInput ? 'text-doom-red' : active ? 'text-doom-on-selected/80' : 'text-doom-dim'}`}\n >\n {session.status}\n </span>\n </span>\n {session.git ? (\n <span\n data-testid=\"session-branch\"\n className={`flex items-center gap-1.5 text-2xs ${active ? 'text-doom-on-selected/70' : 'text-doom-faint'}`}\n >\n <BranchIcon className=\"h-[9px] w-[9px] shrink-0\" />\n <span className=\"truncate\">\n {session.git.branch}\n {session.git.dirty ? '*' : ''}\n </span>\n </span>\n ) : null}\n {error ? (\n <span data-testid=\"session-error\" className=\"line-clamp-3 text-xs break-words text-doom-red\">\n {error}\n </span>\n ) : null}\n </div>\n </div>\n );\n\n const menuOpen = mode === 'menu';\n return (\n <>\n <div\n className={cn('group relative', session.nested && 'pl-4')}\n data-testid={`session-card-${session.id}`}\n data-active={active}\n data-nested={session.nested}\n >\n <Button\n variant=\"ghost\"\n size=\"card\"\n data-testid={`session-open-${session.id}`}\n onClick={() => actions.openSession(session.id)}\n className={tileClass}\n >\n {body}\n </Button>\n {mode === 'view' || menuOpen ? (\n <div\n className={`absolute top-2 right-2 transition-opacity ${\n menuOpen ? 'opacity-100' : 'opacity-0 group-focus-within:opacity-100 group-hover:opacity-100'\n }`}\n >\n <DropdownMenu\n open={menuOpen}\n onOpenChange={(next) => {\n const current = modeRef.current;\n enterMode(next ? 'menu' : current === 'menu' ? 'view' : current);\n }}\n >\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`session-menu-${session.id}`}\n title=\"session actions\"\n className={active ? 'text-doom-on-selected/80' : 'text-doom-faint hover:text-doom-hi'}\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n data-testid={`session-menu-list-${session.id}`}\n onCloseAutoFocus={(event) => {\n if (modeRef.current !== 'view') event.preventDefault();\n }}\n >\n {actions.renderSessionMenuItems(session.id)}\n <DropdownMenuItem\n data-testid={`session-rename-${session.id}`}\n onSelect={() => {\n setDraft(session.name);\n enterMode('rename');\n }}\n >\n rename\n </DropdownMenuItem>\n <DropdownMenuItem\n data-testid={`session-resume-${session.id}`}\n onSelect={() => actions.resumeSession(session.id)}\n >\n resume\n </DropdownMenuItem>\n <DropdownMenuItem\n data-testid={`session-restart-${session.id}`}\n disabled={session.restarting}\n onSelect={() => actions.restartSession(session.id)}\n >\n restart\n </DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n data-testid={`session-stop-${session.id}`}\n onSelect={() => enterMode('confirm')}\n >\n remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ) : null}\n <Dialog open={mode === 'rename'} onOpenChange={(next) => !next && enterMode('view')}>\n <DialogContent width=\"sm\" data-testid={`session-rename-dialog-${session.id}`} aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>rename session</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <form\n className=\"flex flex-col gap-3\"\n onSubmit={(event) => {\n event.preventDefault();\n commitRename();\n }}\n >\n <Input\n data-testid={`session-name-input-${session.id}`}\n aria-label=\"session name\"\n value={draft}\n autoFocus\n onChange={(event) => setDraft(event.target.value)}\n />\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"md\"\n data-testid={`session-rename-cancel-${session.id}`}\n onClick={() => enterMode('view')}\n >\n cancel\n </Button>\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"md\"\n data-testid={`session-rename-confirm-${session.id}`}\n disabled={draft.trim() === ''}\n >\n rename\n </Button>\n </DialogFooter>\n </form>\n </DialogBody>\n </DialogContent>\n </Dialog>\n <Dialog open={mode === 'confirm'} onOpenChange={(next) => !next && enterMode('view')}>\n <DialogContent width=\"sm\" data-testid={`session-stop-dialog-${session.id}`} aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>remove session</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <DialogDescription>\n this stops <span className=\"font-bold text-doom-hi\">{session.name || 'untitled'}</span> and removes it\n from the list. anything it is running ends now, but its saved history remains available to resume.\n </DialogDescription>\n <DialogFooter>\n <Button\n variant=\"outline\"\n size=\"md\"\n data-testid={`session-stop-cancel-${session.id}`}\n autoFocus\n onClick={() => enterMode('view')}\n >\n cancel\n </Button>\n <Button\n variant=\"danger\"\n size=\"md\"\n data-testid={`session-stop-confirm-${session.id}`}\n onClick={() => void remove()}\n >\n remove\n </Button>\n </DialogFooter>\n </DialogBody>\n </DialogContent>\n </Dialog>\n </div>\n {session.pendingSetups.map((setup) => (\n <ElegantPendingSetup key={`setup:${setup.id}`} sessionId={session.id} setup={setup} actions={actions} />\n ))}\n </>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailWorkspace } from '@agimon-ai/doompi-core/web';\nimport {\n Button,\n Dialog,\n DialogBody,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n KebabIcon,\n PlusIcon,\n} from '@agimon-ai/doompi-web-components';\nimport { useState } from 'react';\n\nimport { ElegantSessionCard } from './ElegantSessionCard';\n\n/** A small-caps workspace label; its path lives in the tooltip and its actions appear on hover. */\nexport function ElegantWorkspaceGroup({\n workspace,\n actions,\n}: {\n workspace: WebTemplateRailWorkspace;\n actions: WebTemplateRailActions;\n}) {\n const [removeOpen, setRemoveOpen] = useState(false);\n const [removeError, setRemoveError] = useState('');\n const [removing, setRemoving] = useState(false);\n const { id, name, root, available, legacy } = workspace;\n const unregister = async (): Promise<void> => {\n setRemoving(true);\n setRemoveError('');\n const result = await actions.deleteWorkspace(id);\n setRemoving(false);\n if (result !== undefined) setRemoveError(result.error);\n else setRemoveOpen(false);\n };\n return (\n <section data-testid={`workspace-group-${id}`} data-available={available} className=\"flex flex-col gap-1.5 pt-4\">\n <div className=\"group/workspace flex min-w-0 items-center gap-1 px-1\">\n <p\n className=\"min-w-0 flex-1 truncate text-2xs font-bold tracking-widest text-doom-faint uppercase\"\n title={root}\n >\n {name}\n </p>\n {legacy ? null : (\n <span className=\"flex items-center gap-0.5 opacity-0 transition-opacity group-focus-within/workspace:opacity-100 group-hover/workspace:opacity-100\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`workspace-new-session-${id}`}\n title=\"new session\"\n aria-label={`new session in ${name}`}\n disabled={!available}\n onClick={() => actions.createSession(id)}\n className=\"text-doom-faint hover:text-doom-hi\"\n >\n <PlusIcon className=\"h-3 w-3\" />\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`workspace-menu-${id}`}\n title=\"workspace actions\"\n aria-label={`${name} actions`}\n className=\"text-doom-faint hover:text-doom-hi\"\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem disabled={!available} onSelect={() => actions.resumeInWorkspace(id)}>\n resume session\n </DropdownMenuItem>\n <DropdownMenuItem disabled={!available} onSelect={() => actions.openWorkspaceSettings(id)}>\n workspace settings\n </DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n data-testid={`workspace-delete-${id}`}\n onSelect={() => {\n setRemoveError('');\n setRemoveOpen(true);\n }}\n >\n delete workspace\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </span>\n )}\n </div>\n {!available ? <p className=\"px-1 text-2xs text-doom-red\">workspace unavailable</p> : null}\n {workspace.sessions.length > 0 ? (\n <div className=\"flex flex-col gap-1.5\">\n {workspace.sessions.map((session) => (\n <ElegantSessionCard key={session.id} session={session} actions={actions} />\n ))}\n </div>\n ) : available ? (\n <p className=\"px-1 text-2xs text-doom-faint\">no sessions yet</p>\n ) : null}\n <Dialog open={removeOpen} onOpenChange={(next) => !next && !removing && setRemoveOpen(false)}>\n <DialogContent width=\"sm\" data-testid={`workspace-delete-dialog-${id}`} aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>delete workspace</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <DialogDescription>\n this unregisters <span className=\"font-bold text-doom-hi\">{name}</span> from DoomPi only. files at{' '}\n <code>{root}</code> stay on disk. its sessions must be removed first.\n </DialogDescription>\n {removeError ? (\n <p data-testid={`workspace-delete-error-${id}`} className=\"text-xs text-doom-red\">\n {removeError}\n </p>\n ) : null}\n <DialogFooter>\n <Button\n variant=\"outline\"\n size=\"md\"\n data-testid={`workspace-delete-cancel-${id}`}\n disabled={removing}\n autoFocus\n onClick={() => setRemoveOpen(false)}\n >\n cancel\n </Button>\n <Button\n variant=\"danger\"\n size=\"md\"\n data-testid={`workspace-delete-confirm-${id}`}\n disabled={removing}\n onClick={() => void unregister()}\n >\n {removing ? 'deleting…' : 'delete'}\n </Button>\n </DialogFooter>\n </DialogBody>\n </DialogContent>\n </Dialog>\n </section>\n );\n}\n","import type { WebTemplateRail } from '@agimon-ai/doompi-core/web';\nimport { Button, Dot, GearIcon, PlusIcon, ShieldIcon } from '@agimon-ai/doompi-web-components';\n\nimport { ElegantWorkspaceGroup } from './ElegantWorkspaceGroup';\n\n/** The drawer's session list: quiet labels, soft tiles, and a low-key footer. */\nexport function ElegantRail({ rail }: { rail: WebTemplateRail }) {\n const { remote, actions } = rail;\n const live = remote.status === 'on' || remote.status === 'starting';\n return (\n <div className=\"flex h-full flex-col gap-2 px-3 pb-3\">\n <div className=\"flex items-center justify-between gap-2 pt-1\">\n <Button\n variant=\"subtle\"\n size=\"sm\"\n data-testid=\"add-workspace-open\"\n aria-label=\"add workspace\"\n onClick={actions.openAddWorkspace}\n className=\"gap-1.5\"\n >\n <PlusIcon className=\"h-3 w-3\" />\n workspace\n </Button>\n <Button\n variant={live ? 'primary' : remote.status === 'failed' ? 'danger-outline' : 'ghost'}\n size=\"sm\"\n data-testid=\"remote-access-open\"\n aria-label={`remote access is ${remote.status}`}\n onClick={actions.openRemoteAccess}\n className=\"gap-1.5\"\n >\n {live ? <Dot tone=\"yellow\" pulse data-testid=\"remote-access-live\" /> : <ShieldIcon className=\"h-3 w-3\" />}\n remote\n </Button>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {rail.workspaces.map((workspace) => (\n <ElegantWorkspaceGroup key={workspace.id} workspace={workspace} actions={actions} />\n ))}\n {rail.workspaces.length === 0 ? (\n <Button\n variant=\"outline\"\n size=\"lg\"\n data-testid=\"add-workspace-empty\"\n onClick={actions.openAddWorkspace}\n className=\"mt-4 w-full justify-start px-3 text-sm\"\n >\n <PlusIcon className=\"h-3 w-3\" />\n add your first workspace\n </Button>\n ) : null}\n {rail.pluginContent}\n </div>\n\n {remote.status === 'off' ? null : (\n <div\n data-testid=\"remote-banner\"\n className={`flex items-center gap-2 rounded-lg px-3 py-2 text-xs ${\n remote.status === 'failed' ? 'bg-doom-tint-red text-doom-red' : 'bg-doom-tint-yellow text-doom-yellow'\n }`}\n >\n <Dot tone={remote.status === 'failed' ? 'red' : 'yellow'} />\n <span className=\"min-w-0 flex-1 truncate\">\n {remote.status === 'failed'\n ? `remote access failed: ${remote.error ?? 'the tunnel stopped'}`\n : `remote ${remote.status === 'starting' ? 'starting' : 'on'}${\n remote.host === undefined ? '' : ` · ${remote.host}`\n } · ${String(remote.deviceCount)} device${remote.deviceCount === 1 ? '' : 's'}`}\n </span>\n <Button variant=\"ghost\" size=\"xs\" data-testid=\"remote-banner-open\" onClick={actions.openRemoteAccess}>\n manage\n </Button>\n <Button variant=\"ghost\" size=\"xs\" data-testid=\"remote-banner-off\" onClick={actions.turnRemoteAccessOff}>\n off\n </Button>\n </div>\n )}\n <div className=\"flex items-center justify-between border-t border-doom-border-soft pt-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"settings-open\"\n aria-label=\"settings\"\n onClick={actions.openSettings}\n className=\"gap-1.5 text-doom-faint\"\n >\n <GearIcon className=\"h-3 w-3\" />\n settings\n </Button>\n <span className=\"text-2xs text-doom-faint max-sm:hidden\">ctrl+t new session</span>\n </div>\n </div>\n );\n}\n","import type { WebTemplateProps } from '@agimon-ai/doompi-core/web';\nimport { Drawer } from '@agimon-ai/doompi-web-components';\n\nimport { ElegantAddWorkspaceDialog } from './ElegantAddWorkspaceDialog';\nimport { ElegantRail } from './ElegantRail';\n\n/** A conversation-first frame, with the same host capabilities available on demand. */\nexport function ElegantLayout({\n view,\n slots,\n rail,\n navigationOpen,\n mobileActivityOpen,\n onNavigationOpenChange,\n onMobileActivityOpenChange,\n}: WebTemplateProps) {\n const conversation = view === 'conversation' || view === 'welcome';\n return (\n <div className=\"relative flex h-full min-w-0 flex-col overflow-hidden bg-doom-bg\">\n <Drawer\n open={navigationOpen}\n onOpenChange={onNavigationOpenChange}\n side=\"left\"\n title=\"Sessions\"\n data-testid=\"session-rail-panel\"\n backdropTestId=\"mobile-drawer-backdrop\"\n >\n <ElegantRail rail={rail} />\n </Drawer>\n {slots.notices}\n {slots.header({ navigationToggle: 'always', activityToggle: 'always' })}\n <main className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\">\n <div\n data-testid=\"template-content\"\n className={\n conversation\n ? 'mx-auto flex min-h-0 w-full max-w-[960px] flex-1 flex-col overflow-hidden px-2 sm:px-6'\n : 'flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden'\n }\n >\n {slots.content}\n {slots.composer == null ? null : (\n <div className=\"mx-2 mb-3 shrink-0 overflow-hidden rounded-lg border border-doom-border bg-doom-panel sm:mx-4 sm:mb-5\">\n {slots.composer}\n </div>\n )}\n {slots.controls == null ? null : (\n <details className=\"shrink-0 px-3 pb-3 text-sm text-doom-dim\">\n <summary\n data-testid=\"template-controls-toggle\"\n className=\"cursor-pointer rounded-sm px-1 py-1 focus-visible:outline focus-visible:outline-doom-blue\"\n >\n Session controls\n </summary>\n {slots.controls}\n </details>\n )}\n </div>\n </main>\n {slots.activity == null ? null : (\n <Drawer\n open={mobileActivityOpen}\n onOpenChange={onMobileActivityOpenChange}\n side=\"right\"\n title=\"Activity\"\n showHeader={false}\n backdropTestId=\"mobile-activity-backdrop\"\n className=\"w-auto max-w-[calc(100vw-48px)]\"\n >\n {slots.activity}\n </Drawer>\n )}\n {rail.addWorkspace ? (\n <ElegantAddWorkspaceDialog suggestedPaths={rail.addWorkspace.suggestedPaths} actions={rail.actions} />\n ) : null}\n </div>\n );\n}\n","import type { WebTemplateFile } from '@agimon-ai/doompi-core/web';\n\nimport { ElegantLayout } from '../_components/ElegantLayout';\n\nexport const elegantTemplate = {\n label: 'Elegant',\n description: 'A focused conversation with collapsible navigation, session controls, and activity.',\n contractVersion: 1,\n layout: ElegantLayout,\n} satisfies WebTemplateFile;\n","import { defineWebTemplate } from '@agimon-ai/doompi-core/web';\n\nimport { elegantTemplate } from './_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","import { defineWebTemplate } from '@agimon-ai/doompi-core/web';\n\nimport { elegantTemplate } from '../../../(frontend)/template/_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","import { defineWebTemplate } from '@agimon-ai/doompi-core/web';\n\nimport { elegantTemplate } from '../../../../(frontend)/template/_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/doompi-core/web';\n\nimport templateDoompiTemplateElegant from '../src/extensions/(frontend)/template/doompi-template-elegant.web';\nimport templateDoompiTemplateElegant2 from '../src/extensions/workspaces/(frontend)/template/doompi-template-elegant.web';\nimport templateDoompiTemplateElegant3 from '../src/extensions/workspaces/sessions/(frontend)/template/doompi-template-elegant.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'template-elegant',\n global: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'doompi-template-elegant' }, templateDoompiTemplateElegant)]; },\n },\n workspace: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'doompi-template-elegant' }, templateDoompiTemplateElegant2)]; },\n },\n session: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'doompi-template-elegant' }, templateDoompiTemplateElegant3)]; },\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"web.mjs","names":["folderName","templateDoompiTemplateElegant","templateDoompiTemplateElegant2","templateDoompiTemplateElegant3"],"sources":["../../src/extensions/(frontend)/template/_components/ElegantFolderBrowser.tsx","../../src/extensions/(frontend)/template/_components/ElegantAddWorkspaceDialog.tsx","../../src/extensions/(frontend)/template/_components/ElegantPendingSetup.tsx","../../src/extensions/(frontend)/template/_components/ElegantSessionCard.tsx","../../src/extensions/(frontend)/template/_components/ElegantWorkspaceGroup.tsx","../../src/extensions/(frontend)/template/_components/ElegantRail.tsx","../../src/extensions/(frontend)/template/_components/ElegantLayout.tsx","../../src/extensions/(frontend)/template/_lib/definition.ts","../../src/extensions/(frontend)/template/doompi-template-elegant.web.ts","../../src/extensions/workspaces/(frontend)/template/doompi-template-elegant.web.ts","../../src/extensions/workspaces/sessions/(frontend)/template/doompi-template-elegant.web.ts","../../generated/web.ts"],"sourcesContent":["import type { WebTemplateRailActions, WebTemplateRailDirectoryListing } from '@agimon-ai/doompi-core/web';\nimport { Button, ChevronUpIcon, OptionRow } from '@agimon-ai/doompi-web-components';\nimport { useEffect, useState } from 'react';\n\nfunction folderName(path: string): string {\n return path.slice(path.lastIndexOf('/') + 1) || path;\n}\n\n/** Walks the server's folders inline: up, into a child, or pick the current folder. */\nexport function ElegantFolderBrowser({\n start,\n listDirectory,\n onSelect,\n}: {\n /** Folder to open first; home when absent. */\n start?: string;\n listDirectory: WebTemplateRailActions['listDirectory'];\n onSelect: (path: string) => void;\n}) {\n const [target, setTarget] = useState(start);\n const [listing, setListing] = useState<WebTemplateRailDirectoryListing | null>(null);\n const [error, setError] = useState('');\n\n useEffect(() => {\n let stale = false;\n void listDirectory(target).then((result) => {\n if (stale) return;\n if ('error' in result) setError(result.error);\n else {\n setError('');\n setListing(result);\n }\n });\n return () => {\n stale = true;\n };\n }, [target, listDirectory]);\n\n return (\n <div\n data-testid=\"folder-browser\"\n className=\"flex flex-col gap-1 rounded-lg border border-doom-border-soft bg-doom-panel/40 p-1.5\"\n >\n <div className=\"flex items-center gap-1 px-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"folder-browser-up\"\n title=\"parent folder\"\n aria-label=\"parent folder\"\n disabled={listing?.parent === undefined}\n onClick={() => listing?.parent !== undefined && setTarget(listing.parent)}\n >\n <ChevronUpIcon className=\"h-3 w-3\" />\n </Button>\n <span className=\"min-w-0 flex-1 truncate text-xs text-doom-dim\" title={listing?.path}>\n {listing?.path ?? 'loading…'}\n </span>\n <Button\n variant=\"outline\"\n size=\"xs\"\n data-testid=\"folder-browser-select\"\n disabled={listing === null}\n onClick={() => listing !== null && onSelect(listing.path)}\n >\n use this folder\n </Button>\n </div>\n {error ? <p className=\"px-2 py-1 text-xs text-doom-red\">{error}</p> : null}\n <div role=\"listbox\" aria-label=\"folders\" className=\"max-h-40 overflow-y-auto\">\n {listing !== null && listing.directories.length === 0 ? (\n <p className=\"px-2 py-1 text-2xs text-doom-faint\">no folders here</p>\n ) : null}\n {listing?.directories.map((directory) => (\n <OptionRow\n key={directory}\n density=\"compact\"\n data-testid=\"folder-browser-entry\"\n onClick={() => setTarget(directory)}\n className=\"w-full px-2.5 py-1 text-sm\"\n >\n {folderName(directory)}\n </OptionRow>\n ))}\n </div>\n </div>\n );\n}\n","import type { WebTemplateRailActions } from '@agimon-ai/doompi-core/web';\nimport {\n Button,\n Dialog,\n DialogBody,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n OptionRow,\n} from '@agimon-ai/doompi-web-components';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { ElegantFolderBrowser } from './ElegantFolderBrowser';\n\nconst SUGGESTION_DEBOUNCE_MS = 120;\nconst NO_HIGHLIGHT = -1;\nconst TRAILING_SEPARATORS = /\\/+$/u;\n\nfunction folderName(path: string): string {\n const trimmed = path.trim().replace(TRAILING_SEPARATORS, '');\n return trimmed.slice(trimmed.lastIndexOf('/') + 1);\n}\n\n/** Adds a workspace by name, by folder, or both; a name alone gets a new default folder. */\nexport function ElegantAddWorkspaceDialog({\n suggestedPaths,\n actions,\n}: {\n suggestedPaths: readonly string[];\n actions: WebTemplateRailActions;\n}) {\n const [name, setName] = useState('');\n // The name follows the folder until the user types their own.\n const [nameEdited, setNameEdited] = useState(false);\n const [path, setPath] = useState(suggestedPaths[0] ?? '');\n const [browsing, setBrowsing] = useState(false);\n const [suggestions, setSuggestions] = useState<readonly string[]>([]);\n const [highlight, setHighlight] = useState(NO_HIGHLIGHT);\n const [error, setError] = useState('');\n const [busy, setBusy] = useState(false);\n const pathInput = useRef<HTMLInputElement>(null);\n const shownName = nameEdited ? name : folderName(path);\n\n useEffect(() => {\n const typed = path.trim();\n if (typed === '') return;\n let stale = false;\n const timer = setTimeout(async () => {\n const found = await actions.searchDirectories(typed);\n if (stale) return;\n setSuggestions(found.filter((directory) => directory !== typed));\n setHighlight(NO_HIGHLIGHT);\n }, SUGGESTION_DEBOUNCE_MS);\n return () => {\n stale = true;\n clearTimeout(timer);\n };\n }, [path, actions]);\n\n const changePath = (next: string): void => {\n setPath(next);\n if (next.trim() === '') setSuggestions([]);\n };\n const pick = (directory: string): void => {\n changePath(`${directory}/`);\n pathInput.current?.focus();\n };\n const trimmedPath = path.trim().replace(TRAILING_SEPARATORS, '') || (path.trim() === '' ? '' : '/');\n const canSubmit = !busy && (trimmedPath !== '' || shownName.trim() !== '');\n const submit = async (): Promise<void> => {\n if (!canSubmit) return;\n setBusy(true);\n setError('');\n const result = await actions.addWorkspace({\n name: shownName.trim(),\n ...(trimmedPath === '' ? {} : { path: trimmedPath }),\n });\n setBusy(false);\n if (result !== undefined) setError(result.error);\n };\n\n return (\n <Dialog open onOpenChange={(next) => !next && !busy && actions.closeAddWorkspace()}>\n <DialogContent width=\"md\" data-testid=\"add-workspace-dialog\" aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>add workspace</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <label htmlFor=\"add-workspace-name\" className=\"flex flex-col gap-1\">\n <span className=\"text-xs text-doom-faint\">name</span>\n <Input\n id=\"add-workspace-name\"\n data-testid=\"add-workspace-name\"\n value={shownName}\n autoFocus\n onChange={(event) => {\n setNameEdited(true);\n setName(event.target.value);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') void submit();\n }}\n placeholder=\"my-project\"\n />\n </label>\n <label htmlFor=\"add-workspace-root\" className=\"flex flex-col gap-1\">\n <span className=\"text-xs text-doom-faint\">\n folder <span className=\"text-doom-faint\">(optional; type a path or browse)</span>\n </span>\n <span className=\"flex items-center gap-1.5\">\n <Input\n id=\"add-workspace-root\"\n ref={pathInput}\n data-testid=\"add-workspace-root\"\n value={path}\n onChange={(event) => changePath(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' && suggestions.length > 0) {\n event.preventDefault();\n setHighlight((current) => (current + 1) % suggestions.length);\n } else if (event.key === 'ArrowUp' && suggestions.length > 0) {\n event.preventDefault();\n setHighlight((current) => (current <= 0 ? suggestions.length - 1 : current - 1));\n } else if (event.key === 'Enter') {\n const chosen = highlight === NO_HIGHLIGHT ? undefined : suggestions[highlight];\n if (chosen === undefined) void submit();\n else pick(chosen);\n }\n }}\n placeholder=\"~/workspace/my-project\"\n className=\"min-w-0 flex-1\"\n />\n <Button\n variant={browsing ? 'subtle' : 'outline'}\n size=\"md\"\n data-testid=\"add-workspace-browse\"\n aria-pressed={browsing}\n onClick={() => setBrowsing((open) => !open)}\n >\n browse\n </Button>\n </span>\n </label>\n {browsing ? (\n <ElegantFolderBrowser\n {...(trimmedPath.startsWith('/') ? { start: trimmedPath } : {})}\n listDirectory={actions.listDirectory}\n onSelect={(selected) => {\n changePath(selected);\n setBrowsing(false);\n }}\n />\n ) : suggestions.length > 0 ? (\n <div\n role=\"listbox\"\n aria-label=\"matching directories\"\n data-testid=\"add-workspace-suggestions\"\n className=\"max-h-40 overflow-y-auto rounded-lg border border-doom-border-soft bg-doom-panel/40 p-1.5\"\n >\n {suggestions.map((directory, index) => (\n <OptionRow\n key={directory}\n density=\"compact\"\n active={index === highlight}\n data-testid=\"add-workspace-suggestion\"\n onMouseDown={(event) => event.preventDefault()}\n onMouseEnter={() => setHighlight(index)}\n onClick={() => pick(directory)}\n className=\"w-full px-2.5 py-1 text-sm\"\n >\n {directory}\n </OptionRow>\n ))}\n </div>\n ) : null}\n {suggestedPaths.length > 0 ? (\n <div className=\"flex flex-wrap gap-1\">\n {suggestedPaths.slice(0, 4).map((suggested) => (\n <Button key={suggested} variant=\"outline\" size=\"xs\" onClick={() => changePath(suggested)}>\n {suggested}\n </Button>\n ))}\n </div>\n ) : null}\n {trimmedPath === '' && shownName.trim() !== '' ? (\n <p data-testid=\"add-workspace-default-hint\" className=\"text-xs text-doom-faint\">\n creates ~/.pi/.doom/workspace/{shownName.trim()}\n </p>\n ) : null}\n {error ? (\n <pre className=\"max-h-28 overflow-y-auto rounded border border-doom-edge-red bg-doom-tint-red/40 px-2.5 py-2 text-xs whitespace-pre-wrap text-doom-red\">\n {error}\n </pre>\n ) : null}\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => actions.closeAddWorkspace()} disabled={busy}>\n cancel\n </Button>\n <Button\n variant=\"primary\"\n data-testid=\"add-workspace-confirm\"\n onClick={() => void submit()}\n disabled={!canSubmit}\n >\n {busy ? 'adding…' : 'add workspace'}\n </Button>\n </DialogFooter>\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailPendingSetup } from '@agimon-ai/doompi-core/web';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n KebabIcon,\n} from '@agimon-ai/doompi-web-components';\nimport { useState } from 'react';\n\n/** A setup-only reservation: no runtime, so it offers removal and nothing else. */\nexport function ElegantPendingSetup({\n sessionId,\n setup,\n actions,\n}: {\n sessionId: string;\n setup: WebTemplateRailPendingSetup;\n actions: WebTemplateRailActions;\n}) {\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState('');\n const remove = async (): Promise<void> => {\n if (busy) return;\n setBusy(true);\n setError('');\n const result = await actions.removePendingSetup(sessionId, setup.id);\n setBusy(false);\n if (result !== undefined) setError(result.error);\n };\n return (\n <div\n data-testid={`pending-session-${setup.id}`}\n className=\"ml-9 flex flex-col gap-0.5 rounded-lg border border-dashed border-doom-border-soft px-3 py-2\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-xs font-bold text-doom-hi\">{setup.name}</span>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"session setup actions\"\n disabled={busy}\n data-testid={`pending-session-menu-${setup.id}`}\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem variant=\"destructive\" onSelect={() => void remove()}>\n remove setup\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <p className={setup.failed ? 'text-2xs text-doom-red' : 'text-2xs text-doom-faint'}>{setup.status}</p>\n {setup.recovery ? (\n <p role={setup.failed ? 'alert' : undefined} className=\"text-2xs text-doom-faint\">\n {setup.recovery}\n </p>\n ) : null}\n {error ? (\n <p role=\"alert\" className=\"text-2xs text-doom-red\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailSession } from '@agimon-ai/doompi-core/web';\nimport {\n AlertIcon,\n Avatar,\n AvatarFallback,\n AvatarImage,\n BranchIcon,\n Button,\n cn,\n Dialog,\n DialogBody,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n ForkIcon,\n ActivityIcon,\n Input,\n KebabIcon,\n} from '@agimon-ai/doompi-web-components';\nimport { useRef, useState } from 'react';\n\nimport { ElegantPendingSetup } from './ElegantPendingSetup';\n\ntype CardMode = 'view' | 'menu' | 'rename' | 'confirm';\n\n/** A soft tile led by the persona avatar, with the branch as a quiet caption. */\nexport function ElegantSessionCard({\n session,\n actions,\n}: {\n session: WebTemplateRailSession;\n actions: WebTemplateRailActions;\n}) {\n const [mode, setMode] = useState<CardMode>('view');\n const [draft, setDraft] = useState('');\n const [removeError, setRemoveError] = useState('');\n // Written by the event that changes the mode, so the menu's close-focus handler\n // sees the new mode before React re-renders the card.\n const modeRef = useRef(mode);\n const enterMode = (next: CardMode): void => {\n modeRef.current = next;\n setMode(next);\n };\n const { active } = session;\n const error = removeError || session.error;\n const tileClass = active\n ? 'rounded-lg bg-doom-selected hover:bg-doom-selected'\n : 'rounded-lg bg-doom-panel/40 hover:bg-doom-panel';\n const commitRename = (): void => {\n actions.renameSession(session.id, draft);\n enterMode('view');\n };\n const remove = async (): Promise<void> => {\n enterMode('view');\n setRemoveError('');\n const result = await actions.removeSession(session.id);\n if (result !== undefined) setRemoveError(result.error);\n };\n\n const body = (\n <div className=\"flex items-start gap-2.5\">\n <Avatar\n data-testid={session.profile ? 'session-avatar' : undefined}\n aria-label={session.profile?.label ?? 'DoomPi'}\n title={session.profile?.label}\n className=\"mt-0.5 h-7 w-7 shrink-0 border border-doom-border-soft bg-doom-deep\"\n >\n {session.profile?.avatarUrl ? <AvatarImage src={session.profile.avatarUrl} alt=\"\" /> : null}\n <AvatarFallback className=\"text-2xs text-doom-magenta\">{session.profile?.initials ?? 'DP'}</AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <div className=\"flex items-center gap-1.5\">\n {session.nested && session.provenance === 'workflow-session' ? (\n <ActivityIcon\n aria-label=\"workflow session\"\n className={`h-[11px] w-[11px] shrink-0 ${active ? 'text-doom-on-selected' : 'text-doom-faint'}`}\n />\n ) : session.nested && session.provenance ? (\n <ForkIcon\n aria-label={\n session.provenance === 'worktree' ? 'automatic per-conversation worktree' : session.provenance\n }\n className={`h-[11px] w-[11px] shrink-0 ${active ? 'text-doom-on-selected' : 'text-doom-faint'}`}\n />\n ) : null}\n <span\n className={`min-w-0 flex-1 truncate text-sm font-bold ${active ? 'text-doom-on-selected' : 'text-doom-hi'}`}\n >\n {session.name || 'untitled'}\n </span>\n {session.ordinal <= 9 ? (\n <span\n title={`press ${String(session.ordinal)} to focus`}\n className={`shrink-0 text-2xs transition-opacity group-focus-within:opacity-0 group-hover:opacity-0 ${\n active ? 'text-doom-on-selected/70' : 'text-doom-faint'\n }`}\n >\n {session.ordinal}\n </span>\n ) : null}\n </div>\n <span className=\"flex items-start gap-1\">\n {session.awaitingInput ? (\n <AlertIcon\n data-testid=\"session-awaiting-input\"\n aria-label=\"waiting for your input\"\n className=\"mt-[2px] h-[11px] w-[11px] shrink-0 text-doom-red\"\n />\n ) : null}\n <span\n data-testid=\"session-status\"\n className={`truncate text-xs ${session.awaitingInput ? 'text-doom-red' : active ? 'text-doom-on-selected/80' : 'text-doom-dim'}`}\n >\n {session.status}\n </span>\n </span>\n {session.git ? (\n <span\n data-testid=\"session-branch\"\n className={`flex items-center gap-1.5 text-2xs ${active ? 'text-doom-on-selected/70' : 'text-doom-faint'}`}\n >\n <BranchIcon className=\"h-[9px] w-[9px] shrink-0\" />\n <span className=\"truncate\">\n {session.git.branch}\n {session.git.dirty ? '*' : ''}\n </span>\n </span>\n ) : null}\n {error ? (\n <span data-testid=\"session-error\" className=\"line-clamp-3 text-xs break-words text-doom-red\">\n {error}\n </span>\n ) : null}\n </div>\n </div>\n );\n\n const menuOpen = mode === 'menu';\n return (\n <>\n <div\n className={cn('group relative', session.nested && 'pl-4')}\n data-testid={`session-card-${session.id}`}\n data-active={active}\n data-nested={session.nested}\n >\n <Button\n variant=\"ghost\"\n size=\"card\"\n data-testid={`session-open-${session.id}`}\n onClick={() => actions.openSession(session.id)}\n className={tileClass}\n >\n {body}\n </Button>\n {mode === 'view' || menuOpen ? (\n <div\n className={`absolute top-2 right-2 transition-opacity ${\n menuOpen ? 'opacity-100' : 'opacity-0 group-focus-within:opacity-100 group-hover:opacity-100'\n }`}\n >\n <DropdownMenu\n open={menuOpen}\n onOpenChange={(next) => {\n const current = modeRef.current;\n enterMode(next ? 'menu' : current === 'menu' ? 'view' : current);\n }}\n >\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`session-menu-${session.id}`}\n title=\"session actions\"\n className={active ? 'text-doom-on-selected/80' : 'text-doom-faint hover:text-doom-hi'}\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n data-testid={`session-menu-list-${session.id}`}\n onCloseAutoFocus={(event) => {\n if (modeRef.current !== 'view') event.preventDefault();\n }}\n >\n {actions.renderSessionMenuItems(session.id)}\n <DropdownMenuItem\n data-testid={`session-rename-${session.id}`}\n onSelect={() => {\n setDraft(session.name);\n enterMode('rename');\n }}\n >\n rename\n </DropdownMenuItem>\n <DropdownMenuItem\n data-testid={`session-resume-${session.id}`}\n onSelect={() => actions.resumeSession(session.id)}\n >\n resume\n </DropdownMenuItem>\n <DropdownMenuItem\n data-testid={`session-restart-${session.id}`}\n disabled={session.restarting}\n onSelect={() => actions.restartSession(session.id)}\n >\n restart\n </DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n data-testid={`session-stop-${session.id}`}\n onSelect={() => enterMode('confirm')}\n >\n remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ) : null}\n <Dialog open={mode === 'rename'} onOpenChange={(next) => !next && enterMode('view')}>\n <DialogContent width=\"sm\" data-testid={`session-rename-dialog-${session.id}`} aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>rename session</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <form\n className=\"flex flex-col gap-3\"\n onSubmit={(event) => {\n event.preventDefault();\n commitRename();\n }}\n >\n <Input\n data-testid={`session-name-input-${session.id}`}\n aria-label=\"session name\"\n value={draft}\n autoFocus\n onChange={(event) => setDraft(event.target.value)}\n />\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"md\"\n data-testid={`session-rename-cancel-${session.id}`}\n onClick={() => enterMode('view')}\n >\n cancel\n </Button>\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"md\"\n data-testid={`session-rename-confirm-${session.id}`}\n disabled={draft.trim() === ''}\n >\n rename\n </Button>\n </DialogFooter>\n </form>\n </DialogBody>\n </DialogContent>\n </Dialog>\n <Dialog open={mode === 'confirm'} onOpenChange={(next) => !next && enterMode('view')}>\n <DialogContent width=\"sm\" data-testid={`session-stop-dialog-${session.id}`} aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>remove session</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <DialogDescription>\n this stops <span className=\"font-bold text-doom-hi\">{session.name || 'untitled'}</span> and removes it\n from the list. anything it is running ends now, but its saved history remains available to resume.\n </DialogDescription>\n <DialogFooter>\n <Button\n variant=\"outline\"\n size=\"md\"\n data-testid={`session-stop-cancel-${session.id}`}\n autoFocus\n onClick={() => enterMode('view')}\n >\n cancel\n </Button>\n <Button\n variant=\"danger\"\n size=\"md\"\n data-testid={`session-stop-confirm-${session.id}`}\n onClick={() => void remove()}\n >\n remove\n </Button>\n </DialogFooter>\n </DialogBody>\n </DialogContent>\n </Dialog>\n </div>\n {session.pendingSetups.map((setup) => (\n <ElegantPendingSetup key={`setup:${setup.id}`} sessionId={session.id} setup={setup} actions={actions} />\n ))}\n </>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailWorkspace } from '@agimon-ai/doompi-core/web';\nimport {\n Button,\n Dialog,\n DialogBody,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n KebabIcon,\n PlusIcon,\n} from '@agimon-ai/doompi-web-components';\nimport { useState } from 'react';\n\nimport { ElegantSessionCard } from './ElegantSessionCard';\n\n/** A small-caps workspace label; its path lives in the tooltip and its actions appear on hover. */\nexport function ElegantWorkspaceGroup({\n workspace,\n actions,\n}: {\n workspace: WebTemplateRailWorkspace;\n actions: WebTemplateRailActions;\n}) {\n const [removeOpen, setRemoveOpen] = useState(false);\n const [removeError, setRemoveError] = useState('');\n const [removing, setRemoving] = useState(false);\n const { id, name, root, available, legacy } = workspace;\n const unregister = async (): Promise<void> => {\n setRemoving(true);\n setRemoveError('');\n const result = await actions.deleteWorkspace(id);\n setRemoving(false);\n if (result !== undefined) setRemoveError(result.error);\n else setRemoveOpen(false);\n };\n return (\n <section data-testid={`workspace-group-${id}`} data-available={available} className=\"flex flex-col gap-1.5 pt-4\">\n <div className=\"group/workspace flex min-w-0 items-center gap-1 px-1\">\n <p\n className=\"min-w-0 flex-1 truncate text-2xs font-bold tracking-widest text-doom-faint uppercase\"\n title={root}\n >\n {name}\n </p>\n {legacy ? null : (\n <span className=\"flex items-center gap-0.5 opacity-0 transition-opacity group-focus-within/workspace:opacity-100 group-hover/workspace:opacity-100\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`workspace-new-session-${id}`}\n title=\"new session\"\n aria-label={`new session in ${name}`}\n disabled={!available}\n onClick={() => actions.createSession(id)}\n className=\"text-doom-faint hover:text-doom-hi\"\n >\n <PlusIcon className=\"h-3 w-3\" />\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid={`workspace-menu-${id}`}\n title=\"workspace actions\"\n aria-label={`${name} actions`}\n className=\"text-doom-faint hover:text-doom-hi\"\n >\n <KebabIcon className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem disabled={!available} onSelect={() => actions.resumeInWorkspace(id)}>\n resume session\n </DropdownMenuItem>\n <DropdownMenuItem disabled={!available} onSelect={() => actions.openWorkspaceSettings(id)}>\n workspace settings\n </DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n data-testid={`workspace-delete-${id}`}\n onSelect={() => {\n setRemoveError('');\n setRemoveOpen(true);\n }}\n >\n delete workspace\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </span>\n )}\n </div>\n {!available ? <p className=\"px-1 text-2xs text-doom-red\">workspace unavailable</p> : null}\n {workspace.sessions.length > 0 ? (\n <div className=\"flex flex-col gap-1.5\">\n {workspace.sessions.map((session) => (\n <ElegantSessionCard key={session.id} session={session} actions={actions} />\n ))}\n </div>\n ) : available ? (\n <p className=\"px-1 text-2xs text-doom-faint\">no sessions yet</p>\n ) : null}\n <Dialog open={removeOpen} onOpenChange={(next) => !next && !removing && setRemoveOpen(false)}>\n <DialogContent width=\"sm\" data-testid={`workspace-delete-dialog-${id}`} aria-describedby={undefined}>\n <DialogHeader>\n <DialogTitle>delete workspace</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <DialogDescription>\n this unregisters <span className=\"font-bold text-doom-hi\">{name}</span> from DoomPi only. files at{' '}\n <code>{root}</code> stay on disk. its sessions must be removed first.\n </DialogDescription>\n {removeError ? (\n <p data-testid={`workspace-delete-error-${id}`} className=\"text-xs text-doom-red\">\n {removeError}\n </p>\n ) : null}\n <DialogFooter>\n <Button\n variant=\"outline\"\n size=\"md\"\n data-testid={`workspace-delete-cancel-${id}`}\n disabled={removing}\n autoFocus\n onClick={() => setRemoveOpen(false)}\n >\n cancel\n </Button>\n <Button\n variant=\"danger\"\n size=\"md\"\n data-testid={`workspace-delete-confirm-${id}`}\n disabled={removing}\n onClick={() => void unregister()}\n >\n {removing ? 'deleting…' : 'delete'}\n </Button>\n </DialogFooter>\n </DialogBody>\n </DialogContent>\n </Dialog>\n </section>\n );\n}\n","import type { WebTemplateRail } from '@agimon-ai/doompi-core/web';\nimport { Button, Dot, GearIcon, PlusIcon, ShieldIcon } from '@agimon-ai/doompi-web-components';\n\nimport { ElegantWorkspaceGroup } from './ElegantWorkspaceGroup';\n\n/** The drawer's session list: quiet labels, soft tiles, and a low-key footer. */\nexport function ElegantRail({ rail }: { rail: WebTemplateRail }) {\n const { remote, actions } = rail;\n const live = remote.status === 'on' || remote.status === 'starting';\n return (\n <div className=\"flex h-full flex-col gap-2 px-3 pb-3\">\n <div className=\"flex items-center justify-between gap-2 pt-1\">\n <Button\n variant=\"subtle\"\n size=\"sm\"\n data-testid=\"add-workspace-open\"\n aria-label=\"add workspace\"\n onClick={actions.openAddWorkspace}\n className=\"gap-1.5\"\n >\n <PlusIcon className=\"h-3 w-3\" />\n workspace\n </Button>\n <Button\n variant={live ? 'primary' : remote.status === 'failed' ? 'danger-outline' : 'ghost'}\n size=\"sm\"\n data-testid=\"remote-access-open\"\n aria-label={`remote access is ${remote.status}`}\n onClick={actions.openRemoteAccess}\n className=\"gap-1.5\"\n >\n {live ? <Dot tone=\"yellow\" pulse data-testid=\"remote-access-live\" /> : <ShieldIcon className=\"h-3 w-3\" />}\n remote\n </Button>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {rail.workspaces.map((workspace) => (\n <ElegantWorkspaceGroup key={workspace.id} workspace={workspace} actions={actions} />\n ))}\n {rail.workspaces.length === 0 ? (\n <Button\n variant=\"outline\"\n size=\"lg\"\n data-testid=\"add-workspace-empty\"\n onClick={actions.openAddWorkspace}\n className=\"mt-4 w-full justify-start px-3 text-sm\"\n >\n <PlusIcon className=\"h-3 w-3\" />\n add your first workspace\n </Button>\n ) : null}\n {rail.pluginContent}\n </div>\n\n {remote.status === 'off' ? null : (\n <div\n data-testid=\"remote-banner\"\n className={`flex items-center gap-2 rounded-lg px-3 py-2 text-xs ${\n remote.status === 'failed' ? 'bg-doom-tint-red text-doom-red' : 'bg-doom-tint-yellow text-doom-yellow'\n }`}\n >\n <Dot tone={remote.status === 'failed' ? 'red' : 'yellow'} />\n <span className=\"min-w-0 flex-1 truncate\">\n {remote.status === 'failed'\n ? `remote access failed: ${remote.error ?? 'the tunnel stopped'}`\n : `remote ${remote.status === 'starting' ? 'starting' : 'on'}${\n remote.host === undefined ? '' : ` · ${remote.host}`\n } · ${String(remote.deviceCount)} device${remote.deviceCount === 1 ? '' : 's'}`}\n </span>\n <Button variant=\"ghost\" size=\"xs\" data-testid=\"remote-banner-open\" onClick={actions.openRemoteAccess}>\n manage\n </Button>\n <Button variant=\"ghost\" size=\"xs\" data-testid=\"remote-banner-off\" onClick={actions.turnRemoteAccessOff}>\n off\n </Button>\n </div>\n )}\n <div className=\"flex items-center justify-between border-t border-doom-border-soft pt-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"settings-open\"\n aria-label=\"settings\"\n onClick={actions.openSettings}\n className=\"gap-1.5 text-doom-faint\"\n >\n <GearIcon className=\"h-3 w-3\" />\n settings\n </Button>\n <span className=\"text-2xs text-doom-faint max-sm:hidden\">ctrl+t new session</span>\n </div>\n </div>\n );\n}\n","import type { WebTemplateProps } from '@agimon-ai/doompi-core/web';\nimport { Drawer } from '@agimon-ai/doompi-web-components';\n\nimport { ElegantAddWorkspaceDialog } from './ElegantAddWorkspaceDialog';\nimport { ElegantRail } from './ElegantRail';\n\n/** A conversation-first frame, with the same host capabilities available on demand. */\nexport function ElegantLayout({\n view,\n slots,\n rail,\n navigationOpen,\n mobileActivityOpen,\n onNavigationOpenChange,\n onMobileActivityOpenChange,\n}: WebTemplateProps) {\n const conversation = view === 'conversation' || view === 'welcome';\n return (\n <div className=\"relative flex h-full min-w-0 flex-col overflow-hidden bg-doom-bg\">\n <Drawer\n open={navigationOpen}\n onOpenChange={onNavigationOpenChange}\n side=\"left\"\n title=\"Sessions\"\n data-testid=\"session-rail-panel\"\n backdropTestId=\"mobile-drawer-backdrop\"\n >\n <ElegantRail rail={rail} />\n </Drawer>\n {slots.notices}\n {slots.header({ navigationToggle: 'always', activityToggle: 'always' })}\n <main className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\">\n <div\n data-testid=\"template-content\"\n className={\n conversation\n ? 'mx-auto flex min-h-0 w-full max-w-[960px] flex-1 flex-col overflow-hidden px-2 sm:px-6'\n : 'flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden'\n }\n >\n {slots.content}\n {slots.composer == null ? null : (\n <div className=\"mx-2 mb-3 shrink-0 overflow-hidden rounded-lg border border-doom-border bg-doom-panel sm:mx-4 sm:mb-5\">\n {slots.composer}\n </div>\n )}\n {slots.controls == null ? null : (\n <details className=\"shrink-0 px-3 pb-3 text-sm text-doom-dim\">\n <summary\n data-testid=\"template-controls-toggle\"\n className=\"cursor-pointer rounded-sm px-1 py-1 focus-visible:outline focus-visible:outline-doom-blue\"\n >\n Session controls\n </summary>\n {slots.controls}\n </details>\n )}\n </div>\n </main>\n {slots.activity == null ? null : (\n <Drawer\n open={mobileActivityOpen}\n onOpenChange={onMobileActivityOpenChange}\n side=\"right\"\n title=\"Activity\"\n showHeader={false}\n backdropTestId=\"mobile-activity-backdrop\"\n className=\"w-auto max-w-[calc(100vw-48px)]\"\n >\n {slots.activity}\n </Drawer>\n )}\n {rail.addWorkspace ? (\n <ElegantAddWorkspaceDialog suggestedPaths={rail.addWorkspace.suggestedPaths} actions={rail.actions} />\n ) : null}\n </div>\n );\n}\n","import type { WebTemplateFile } from '@agimon-ai/doompi-core/web';\n\nimport { ElegantLayout } from '../_components/ElegantLayout';\n\nexport const elegantTemplate = {\n label: 'Elegant',\n description: 'A focused conversation with collapsible navigation, session controls, and activity.',\n contractVersion: 1,\n layout: ElegantLayout,\n} satisfies WebTemplateFile;\n","import { defineWebTemplate } from '@agimon-ai/doompi-core/web';\n\nimport { elegantTemplate } from './_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","import { defineWebTemplate } from '@agimon-ai/doompi-core/web';\n\nimport { elegantTemplate } from '../../../(frontend)/template/_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","import { defineWebTemplate } from '@agimon-ai/doompi-core/web';\n\nimport { elegantTemplate } from '../../../../(frontend)/template/_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/doompi-core/web';\n\nimport templateDoompiTemplateElegant from '../src/extensions/(frontend)/template/doompi-template-elegant.web';\nimport templateDoompiTemplateElegant2 from '../src/extensions/workspaces/(frontend)/template/doompi-template-elegant.web';\nimport templateDoompiTemplateElegant3 from '../src/extensions/workspaces/sessions/(frontend)/template/doompi-template-elegant.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'template-elegant',\n global: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'doompi-template-elegant' }, templateDoompiTemplateElegant)]; },\n },\n workspace: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'doompi-template-elegant' }, templateDoompiTemplateElegant2)]; },\n },\n session: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'doompi-template-elegant' }, templateDoompiTemplateElegant3)]; },\n },\n});\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-template-elegant",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.23",
|
|
4
4
|
"description": "Elegant chat-first template for the DoomPi web client.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
55
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
54
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.103",
|
|
55
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.61"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@agimon-ai/doompi-build": "0.0.1-alpha.24",
|