@agimon-ai/po-template-elegant 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 @@
1
+ {"version":3,"file":"web.mjs","names":["folderName","templatePoTemplateElegant","templatePoTemplateElegant2","templatePoTemplateElegant3"],"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/_components/ElegantConversation.tsx","../../src/extensions/(frontend)/template/_components/ElegantSettings.tsx","../../src/extensions/(frontend)/template/_components/ElegantDashboard.tsx","../../src/extensions/(frontend)/template/_lib/definition.ts","../../src/extensions/(frontend)/template/po-template-elegant.web.ts","../../src/extensions/workspaces/(frontend)/template/po-template-elegant.web.ts","../../src/extensions/workspaces/sessions/(frontend)/template/po-template-elegant.web.ts","../../generated/web.ts"],"sourcesContent":["import type { WebTemplateRailActions, WebTemplateRailDirectoryListing } from '@agimon-ai/po-core/web';\nimport { Button, ChevronUpIcon, OptionRow } from '@agimon-ai/po-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-sm 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-sm 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-sm text-doom-dim\">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 \"\n >\n {folderName(directory)}\n </OptionRow>\n ))}\n </div>\n </div>\n );\n}\n","import type { WebTemplateRailActions } from '@agimon-ai/po-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/po-web-components';\nimport { workspaceAdmissionStore, updateWorkspaceAdmission } from '@agimon-ai/po-web-dashboard';\nimport { useStore } from '@tanstack/react-store';\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 draft = useStore(workspaceAdmissionStore, (state) => state);\n const { name, nameEdited, pending: busy, error } = draft;\n const path = draft.path ?? suggestedPaths[0] ?? '';\n const setName = (name: string): void => updateWorkspaceAdmission({ name });\n const setNameEdited = (nameEdited: boolean): void => updateWorkspaceAdmission({ nameEdited });\n const setPath = (path: string): void => updateWorkspaceAdmission({ path });\n const [browsing, setBrowsing] = useState(false);\n const [suggestions, setSuggestions] = useState<readonly string[]>([]);\n const [highlight, setHighlight] = useState(NO_HIGHLIGHT);\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 await actions.addWorkspace({\n name: shownName.trim(),\n ...(trimmedPath === '' ? {} : { path: trimmedPath }),\n });\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-base font-medium text-doom-dim\">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-base font-medium text-doom-dim\">\n folder <span className=\"text-doom-dim\">(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 \"\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-sm text-doom-dim\">\n creates ~/.po/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-sm 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/po-core/web';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n KebabIcon,\n} from '@agimon-ai/po-web-components';\nimport { useDashboardState } from '@agimon-ai/po-web-dashboard';\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 key = JSON.stringify(['rail/setup', sessionId, setup.id]);\n const [busy, setBusy, busyState] = useDashboardState(`${key}/busy`, false);\n const [error, setError] = useDashboardState(`${key}/error`, '');\n const remove = async (): Promise<void> => {\n if (busyState.state) 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-base font-semibold 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-sm text-doom-red' : 'text-sm text-doom-dim'}>{setup.status}</p>\n {setup.recovery ? (\n <p role={setup.failed ? 'alert' : undefined} className=\"text-sm text-doom-dim\">\n {setup.recovery}\n </p>\n ) : null}\n {error ? (\n <p role=\"alert\" className=\"text-sm text-doom-red\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n","import type { WebTemplateRailActions, WebTemplateRailSession } from '@agimon-ai/po-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 LoaderIcon,\n} from '@agimon-ai/po-web-components';\nimport { useDashboardState } from '@agimon-ai/po-web-dashboard';\nimport { useRef } 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 key = `rail/session/${session.id}`;\n const [mode, setMode] = useDashboardState<CardMode>(`${key}/mode`, 'view');\n const [draft, setDraft] = useDashboardState(`${key}/draft`, '');\n const [removeError, setRemoveError] = useDashboardState(`${key}/error`, '');\n const [, setRemoving, removingState] = useDashboardState(`${key}/removing`, false);\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 border border-doom-edge-green bg-doom-tint-green px-3 hover:bg-doom-tint-green'\n : 'rounded-lg border border-transparent px-3 hover:bg-doom-panel';\n const failed = session.status.startsWith('failed') || session.status.includes(' failed');\n const running = session.status.startsWith('running');\n const commitRename = (): void => {\n actions.renameSession(session.id, draft);\n enterMode('view');\n };\n const remove = async (): Promise<void> => {\n if (removingState.state) return;\n setRemoving(true);\n enterMode('view');\n setRemoveError('');\n const result = await actions.removeSession(session.id);\n setRemoving(false);\n if (result !== undefined) setRemoveError(result.error);\n };\n\n const body = (\n <>\n <span className=\"flex w-full min-w-0 items-start gap-2.5\">\n <Avatar\n data-testid={session.profile ? 'session-avatar' : undefined}\n aria-label={session.profile?.label ?? 'Po'}\n title={session.profile?.label}\n className=\"size-8 shrink-0 rounded-full\"\n >\n {session.profile?.avatarUrl ? <AvatarImage src={session.profile.avatarUrl} alt=\"\" /> : null}\n <AvatarFallback className=\"bg-doom-tint-green text-xs font-semibold text-doom-green\">\n {session.profile?.initials ?? 'PO'}\n </AvatarFallback>\n </Avatar>\n <span className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"flex min-w-0 items-start gap-2\">\n {session.nested && session.provenance === 'workflow-session' ? (\n <ActivityIcon\n aria-label=\"workflow session\"\n className={`mt-1 size-3 shrink-0 ${active ? 'text-doom-green' : '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={`mt-1 size-3 shrink-0 ${active ? 'text-doom-green' : 'text-doom-faint'}`}\n />\n ) : null}\n <span className=\"min-w-0 flex-1 text-base font-semibold break-words text-doom-hi\">\n {session.name || 'Untitled'}\n </span>\n {session.ordinal <= 9 ? (\n <span\n title={`press ${String(session.ordinal)} to focus`}\n 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\"\n >\n {session.ordinal}\n </span>\n ) : null}\n </span>\n <span\n className={`flex min-w-0 items-start gap-1.5 text-sm leading-snug ${\n failed ? 'text-doom-red' : running ? 'text-doom-yellow' : active ? 'text-doom-text' : 'text-doom-dim'\n }`}\n >\n {session.awaitingInput ? (\n <AlertIcon\n data-testid=\"session-awaiting-input\"\n aria-label=\"Waiting for your input\"\n className=\"mt-0.5 size-3 shrink-0 text-doom-magenta\"\n />\n ) : running ? (\n <LoaderIcon aria-hidden className=\"mt-0.5 size-3 shrink-0 animate-spin\" />\n ) : failed ? (\n <AlertIcon aria-hidden className=\"mt-0.5 size-3 shrink-0\" />\n ) : null}\n <span data-testid=\"session-status\" className={active ? 'line-clamp-2' : 'truncate'}>\n {session.status}\n </span>\n </span>\n </span>\n </span>\n {session.git ? (\n <span data-testid=\"session-branch\" className=\"flex min-w-0 items-center gap-1.5 pl-10.5 text-sm text-doom-dim\">\n <BranchIcon className={`size-3 shrink-0 ${active ? 'text-doom-green' : ''}`} />\n <span className=\"truncate font-mono\">{session.git.branch}</span>\n {session.git.dirty ? <span className=\"shrink-0 text-doom-yellow\">modified</span> : null}\n </span>\n ) : null}\n {error ? (\n <span data-testid=\"session-error\" className=\"line-clamp-3 text-sm break-words text-doom-red\">\n {error}\n </span>\n ) : null}\n </>\n );\n\n const menuOpen = mode === 'menu';\n return (\n <>\n <div\n className={cn('group relative', session.nested && 'pl-5')}\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=\"text-doom-dim 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 || session.restartBlocked === true}\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-semibold text-doom-hi\">{session.name || 'untitled'}</span> and removes\n it 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/po-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 FolderIcon,\n KebabIcon,\n PlusIcon,\n} from '@agimon-ai/po-web-components';\nimport { useDashboardState } from '@agimon-ai/po-web-dashboard';\n\nimport { ElegantSessionCard } from './ElegantSessionCard';\n\n/** A folder heading over its sessions; only a hover tint marks the row. */\nexport function ElegantWorkspaceGroup({\n workspace,\n actions,\n}: {\n workspace: WebTemplateRailWorkspace;\n actions: WebTemplateRailActions;\n}) {\n const key = `rail/workspace/${workspace.id}`;\n const [removeOpen, setRemoveOpen] = useDashboardState(`${key}/open`, false);\n const [removeError, setRemoveError] = useDashboardState(`${key}/error`, '');\n const [removing, setRemoving, removingState] = useDashboardState(`${key}/removing`, false);\n const { id, name, root, available, legacy } = workspace;\n const unregister = async (): Promise<void> => {\n if (removingState.state) return;\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\">\n <div className=\"flex min-w-0 items-start gap-2.5 rounded-md px-2 py-1 transition-colors hover:bg-doom-panel/60\">\n <FolderIcon aria-hidden className=\"mt-0.5 size-4 shrink-0 text-doom-dim\" />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <p className=\"truncate text-base font-semibold text-doom-hi\">{name}</p>\n <p className=\"truncate font-mono text-sm text-doom-dim\" title={root}>\n {root}\n </p>\n </div>\n {legacy ? null : (\n <span className=\"flex items-center gap-0.5\">\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=\"size-3.5\" />\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=\"size-3.5\" />\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-9 text-sm text-doom-red\">Workspace unavailable</p> : null}\n {workspace.sessions.length > 0 ? (\n <div className=\"flex flex-col gap-1\">\n {workspace.sessions.map((session) => (\n <ElegantSessionCard key={session.id} session={session} actions={actions} />\n ))}\n </div>\n ) : available ? (\n <p className=\"px-9 pb-1 text-sm text-doom-dim\">No sessions yet. Start or resume one.</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-semibold text-doom-hi\">{name}</span> from Po 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-sm 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/po-core/web';\nimport { Button, CloseIcon, Dot, GearIcon, Kbd, PlusIcon, ShieldIcon } from '@agimon-ai/po-web-components';\n\nimport { ElegantWorkspaceGroup } from './ElegantWorkspaceGroup';\n\n/** The drawer's session list: brand, workspaces with their sessions, remote access, and settings. */\nexport function ElegantRail({ rail, onClose }: { rail: WebTemplateRail; onClose: () => void }) {\n const { remote, actions } = rail;\n const live = remote.status === 'on' || remote.status === 'starting';\n return (\n <div className=\"flex min-h-full flex-col\">\n <div className=\"flex items-center justify-between gap-2 px-5 pt-4 pb-3\">\n <span className=\"flex items-center gap-2.5\" aria-label=\"Po\">\n <img src=\"/favicon.svg\" alt=\"\" aria-hidden=\"true\" className=\"size-9 rounded-lg\" />\n <span aria-hidden=\"true\" className=\"text-2xl font-semibold text-doom-hi\">\n Po\n </span>\n </span>\n <span className=\"flex items-center gap-1\">\n <Button\n variant={remote.status === 'failed' ? 'danger-outline' : 'outline'}\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 rounded-md ${remote.status === 'failed' ? '' : 'bg-doom-panel'}`}\n >\n {live ? <Dot tone=\"yellow\" pulse data-testid=\"remote-access-live\" /> : <ShieldIcon className=\"size-3.5\" />}\n Remote access\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"mobile-sessions-close\"\n title=\"Hide sessions\"\n aria-label=\"Hide sessions\"\n onClick={onClose}\n className=\"text-doom-dim\"\n >\n <CloseIcon className=\"size-3.5\" />\n </Button>\n </span>\n </div>\n\n <div className=\"flex items-center justify-between px-5 pt-3 pb-2\">\n <h2 className=\"text-lg font-semibold text-doom-hi\">Workspaces</h2>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"add-workspace-open\"\n title=\"Add workspace\"\n aria-label=\"Add workspace\"\n onClick={actions.openAddWorkspace}\n className=\"text-doom-faint hover:text-doom-hi\"\n >\n <PlusIcon className=\"size-3.5\" />\n </Button>\n </div>\n <div className=\"flex flex-col gap-4 px-3 pb-3\">\n {rail.workspaces.map((workspace) => (\n <ElegantWorkspaceGroup key={workspace.id} workspace={workspace} actions={actions} />\n ))}\n {rail.workspaces.length === 0 ? (\n <div className=\"flex flex-col gap-3 rounded-lg border border-dashed border-doom-border px-4 py-5\">\n <p className=\"text-sm text-doom-dim\">Add a folder to start working with Po.</p>\n <Button\n variant=\"outline\"\n size=\"md\"\n data-testid=\"add-workspace-empty\"\n onClick={actions.openAddWorkspace}\n className=\"justify-start gap-2 bg-doom-panel\"\n >\n <PlusIcon className=\"size-3.5\" />\n Add workspace\n </Button>\n </div>\n ) : null}\n </div>\n {rail.pluginContent}\n <div className=\"flex-1\" />\n\n <div className=\"sticky bottom-0 mt-auto shrink-0 bg-doom-rail\">\n {remote.status === 'off' ? null : (\n <div\n data-testid=\"remote-banner\"\n className={`flex items-center gap-2 border-t border-doom-border-soft px-4 py-2 text-sm ${\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 access ${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 Turn off\n </Button>\n </div>\n )}\n <div className=\"flex flex-col gap-1 border-t border-doom-border-soft px-3 py-3\">\n <Button\n variant=\"ghost\"\n size=\"md\"\n data-testid=\"settings-open\"\n onClick={actions.openSettings}\n className=\"justify-start gap-2.5 px-2 text-doom-text\"\n >\n <GearIcon className=\"size-4 text-doom-dim\" />\n Settings\n </Button>\n <span className=\"px-2 text-sm text-doom-dim max-sm:hidden\">\n <Kbd className=\"bg-doom-panel\">ctrl+k</Kbd> commands · <Kbd className=\"bg-doom-panel\">ctrl+t</Kbd> new\n session\n </span>\n </div>\n </div>\n </div>\n );\n}\n","import { Drawer } from '@agimon-ai/po-web-components';\n\nimport type { LayoutProps } from '../_types/layout';\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}: LayoutProps) {\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 showHeader={false}\n data-testid=\"session-rail-panel\"\n backdropTestId=\"mobile-drawer-backdrop\"\n className=\"w-[min(340px,calc(100vw-48px))] border-doom-border-soft\"\n >\n <ElegantRail rail={rail} onClose={() => onNavigationOpenChange(false)} />\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 : <div className=\"mb-2 shrink-0 sm:mb-4\">{slots.composer}</div>}\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 { useDashboardRoute } from '@agimon-ai/po-web-dashboard';\nimport { pluginActivityGroups, webTabs } from '@agimon-ai/po-web-dashboard';\nimport { useSessionMcp } from '@agimon-ai/po-web-dashboard';\nimport { sessionsStore, useActiveSessionMeta, useNoSessions } from '@agimon-ai/po-web-dashboard';\nimport { useActiveSession } from '@agimon-ai/po-web-dashboard';\nimport { findTransientTab, transientTabsStore } from '@agimon-ai/po-web-dashboard';\nimport { setDockOpen, uiStore } from '@agimon-ai/po-web-dashboard';\nimport { usePluginSlotProps } from '@agimon-ai/po-web-dashboard';\nimport { useWebPluginRegistry } from '@agimon-ai/po-web-dashboard';\nimport { workspacesStore } from '@agimon-ai/po-web-dashboard';\nimport { SessionMcp } from '@agimon-ai/po-web-dashboard/views';\nimport { ActivityDock } from '@agimon-ai/po-web-dashboard/views';\nimport { SelectionBar } from '@agimon-ai/po-web-dashboard/views';\nimport { Composer } from '@agimon-ai/po-web-dashboard/views';\nimport { Timeline } from '@agimon-ai/po-web-dashboard/views';\nimport { SessionRailDialogs } from '@agimon-ai/po-web-dashboard/views';\nimport { useSessionRail } from '@agimon-ai/po-web-dashboard/views';\nimport { WelcomePanel } from '@agimon-ai/po-web-dashboard/views';\nimport { TopBar } from '@agimon-ai/po-web-dashboard/views';\nimport { useStore } from '@tanstack/react-store';\nimport { useState } from 'react';\n\nimport { ElegantLayout } from './ElegantLayout';\n\nexport function ElegantConversation() {\n useWebPluginRegistry();\n const dockOpen = useStore(uiStore, (state) => state.dockOpen);\n const [railOpen, setRailOpen] = useState(false);\n const [mobileActivityOpen, setMobileActivityOpen] = useState(false);\n const { sessionId, tabId } = useDashboardRoute();\n const slotProps = usePluginSlotProps(sessionId ?? null);\n const sessionWorkspaceId = useStore(sessionsStore, (state) =>\n sessionId === undefined ? undefined : state.byId[sessionId]?.summary.workspaceId,\n );\n const selectedWorkspaceId = useStore(workspacesStore, (state) => state.selectedId);\n const workspaceId = sessionId === undefined ? (selectedWorkspaceId ?? undefined) : sessionWorkspaceId;\n const mcp = useSessionMcp(workspaceId, sessionId);\n const mcpView = tabId === 'mcp';\n const mcpEnabled = mcp.snapshot?.enabled === true || mcpView;\n const transferLabel = useStore(sessionsStore, (state) => {\n if (state.transferringToId === null) return null;\n return state.byId[state.transferringToId]?.summary.name ?? 'destination session';\n });\n const noSessions = useNoSessions();\n const activeMeta = useActiveSessionMeta();\n const dormantMeta = activeMeta?.summary.dormant === true ? activeMeta : null;\n const dialogId = useActiveSession((state) => state.dialog?.id ?? null);\n // A declared tab first, then one a plugin opened at runtime for this session.\n // Session plugin compositions replace the builtin plugin module after verification.\n // Refresh activity-owned tabs from the active registry so a tab opened during that\n // handoff does not keep rendering the retired module's disconnected stores.\n const storedTransientTab = useStore(transientTabsStore, (state) => findTransientTab(state, sessionId, tabId));\n const transientTab =\n storedTransientTab === undefined\n ? undefined\n : (pluginActivityGroups()\n .map((group) => group.transientTab?.())\n .find((candidate) => candidate?.id === storedTransientTab.id) ?? storedTransientTab);\n const tab = (tabId === undefined ? undefined : webTabs().find((entry) => entry.id === tabId)) ?? transientTab;\n // Only a runtime tab carries composer context; a declared tab with the same id wins and carries none.\n const composerContext = tab === transientTab ? transientTab?.composerContext : undefined;\n\n // Both side panels are temporary drawers on mobile. Route changes can also\n // come from plugin navigation, so they dismiss the drawers even when no\n // drawer item produced the navigation event directly. A modal must not\n // compete with the mobile activity drawer for the viewport either, so an\n // opening dialog closes it. Both are adjustments made while rendering the\n // change rather than in an effect, so no extra pass paints the open drawer.\n const routeKey = `${sessionId ?? ''}\\u0000${tabId ?? ''}`;\n const [lastRouteKey, setLastRouteKey] = useState(routeKey);\n if (lastRouteKey !== routeKey) {\n setLastRouteKey(routeKey);\n setRailOpen(false);\n setMobileActivityOpen(false);\n }\n\n const [lastDialogId, setLastDialogId] = useState(dialogId);\n if (lastDialogId !== dialogId) {\n setLastDialogId(dialogId);\n if (dialogId !== null) {\n setMobileActivityOpen(false);\n setRailOpen(false);\n }\n }\n\n const rail = useSessionRail({ onDismiss: () => setRailOpen(false) });\n\n const closeActivity = (): void => {\n if (mobileActivityOpen) setMobileActivityOpen(false);\n else setDockOpen(false);\n };\n return (\n <div data-testid=\"cockpit\" className=\"h-full min-w-0 overflow-hidden\">\n <ElegantLayout\n view={mcpView || tab ? 'panel' : noSessions ? 'welcome' : 'conversation'}\n navigationOpen={railOpen}\n desktopActivityOpen={dockOpen}\n mobileActivityOpen={mobileActivityOpen}\n onNavigationOpenChange={setRailOpen}\n onDesktopActivityOpenChange={setDockOpen}\n onMobileActivityOpenChange={setMobileActivityOpen}\n rail={rail}\n slots={{\n header: (options) => (\n <TopBar\n {...options}\n view={mcpView ? 'mcp' : (tab?.id ?? 'conversation')}\n mcpEnabled={mcpEnabled}\n onShowSessions={() => {\n setMobileActivityOpen(false);\n setRailOpen(true);\n }}\n onShowActivity={() => {\n setRailOpen(false);\n setMobileActivityOpen(true);\n }}\n />\n ),\n notices:\n transferLabel === null ? null : (\n <output\n data-testid=\"voice-transfer-transition\"\n className=\"border-b border-doom-cyan/30 bg-doom-cyan/10 px-4 py-2 text-center text-base font-medium text-doom-cyan\"\n >\n Transferring voice to {transferLabel}...\n </output>\n ),\n content: mcpView ? (\n <SessionMcp key={sessionId} state={mcp} />\n ) : tab ? (\n <tab.panel {...slotProps} />\n ) : noSessions ? (\n <WelcomePanel />\n ) : (\n <Timeline />\n ),\n // MCP history is a read-only surface, not an alternative prompt composer.\n composer: mcpView ? null : tab ? (\n tab.retainComposer === true ? (\n <Composer composerContext={composerContext} />\n ) : null\n ) : noSessions ? null : (\n <Composer />\n ),\n controls: !mcpView && !tab && !noSessions && dormantMeta === null ? <SelectionBar /> : null,\n activity: (\n <ActivityDock mcp={mcp} onClose={closeActivity} onOpenContent={() => setMobileActivityOpen(false)} />\n ),\n }}\n />\n <SessionRailDialogs />\n </div>\n );\n}\n","import { Button, NavTab } from '@agimon-ai/po-web-components';\nimport { useDashboardRoute, useDashboardState } from '@agimon-ai/po-web-dashboard';\nimport { refreshWebPluginCompositions } from '@agimon-ai/po-web-dashboard';\nimport {\n DEFAULT_REPOSITORY_SETTINGS_SECTION,\n DEFAULT_SETTINGS_SECTION,\n settingsSection,\n} from '@agimon-ai/po-web-dashboard';\nimport { sessionsStore } from '@agimon-ai/po-web-dashboard';\nimport { useWebPluginRegistry } from '@agimon-ai/po-web-dashboard';\nimport { AppearanceSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { ContributedSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { ImageSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { NotificationSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { PluginSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { ProviderSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { RemoteControlSettings } from '@agimon-ai/po-web-dashboard/views';\nimport { RepositoryWorkspace } from '@agimon-ai/po-web-dashboard/views';\nimport { SettingsMenu } from '@agimon-ai/po-web-dashboard/views';\nimport { SettingsPanelHost } from '@agimon-ai/po-web-dashboard/views';\nimport { Link, useNavigate } from '@tanstack/react-router';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect, useState } from 'react';\n\n/** Settings have their own page frame, independent of session navigation. */\nexport function ElegantSettings() {\n useWebPluginRegistry();\n const { section, workspaceId } = useDashboardRoute();\n const navigate = useNavigate();\n const activeId = useStore(sessionsStore, (state) => state.activeId);\n const [loadError, setLoadError] = useState<string>();\n const [repositoryReady, setRepositoryReady] = useState(false);\n const [templateTarget, setTemplateTarget] = useDashboardState('settings/template-target', 'global');\n const current = settingsSection(section);\n const workspace = current?.workspace ?? (section?.startsWith('repository-') ? 'repository' : 'general');\n\n useEffect(() => {\n if (current) return;\n if (workspace === 'repository' && !repositoryReady) return;\n let cancelled = false;\n void refreshWebPluginCompositions()\n .then(() => {\n if (cancelled || settingsSection(section)) return;\n void navigate({\n to: '/settings/$section',\n params: { section: DEFAULT_SETTINGS_SECTION },\n search: { workspace: workspaceId },\n replace: true,\n });\n })\n .catch((error: unknown) => {\n if (!cancelled) setLoadError(error instanceof Error ? error.message : String(error));\n });\n return () => {\n cancelled = true;\n };\n }, [current, section, navigate, workspace, workspaceId, repositoryReady]);\n\n return (\n <div data-testid=\"settings\" className=\"flex h-full min-h-0 min-w-0 flex-col overflow-hidden bg-doom-bg\">\n <header 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\">\n <h1 className=\"order-1 min-w-0 truncate text-xl font-semibold text-doom-hi sm:order-none\">Settings</h1>\n <nav\n 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\"\n aria-label=\"settings workspace\"\n >\n <NavTab\n asChild\n active={workspace === 'general'}\n className=\"min-h-8 flex-1 justify-center rounded-md px-4 focus-visible:ring-2 focus-visible:ring-doom-green sm:flex-none\"\n aria-current={workspace === 'general' ? 'true' : undefined}\n >\n <Link\n to=\"/settings/$section\"\n params={{ section: DEFAULT_SETTINGS_SECTION }}\n search={{ workspace: workspaceId }}\n data-testid=\"settings-workspace-general\"\n >\n General\n </Link>\n </NavTab>\n <NavTab\n asChild\n active={workspace === 'repository'}\n className=\"min-h-8 flex-1 justify-center rounded-md px-4 focus-visible:ring-2 focus-visible:ring-doom-green sm:flex-none\"\n aria-current={workspace === 'repository' ? 'true' : undefined}\n >\n <Link\n to=\"/settings/$section\"\n params={{ section: DEFAULT_REPOSITORY_SETTINGS_SECTION }}\n search={{ workspace: workspaceId }}\n data-testid=\"settings-workspace-repository\"\n >\n Workspaces\n </Link>\n </NavTab>\n </nav>\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"order-2 sm:order-none sm:justify-self-end\">\n {activeId !== null ? (\n <Link to=\"/session/$sessionId\" params={{ sessionId: activeId }} data-testid=\"settings-close\">\n <span className=\"sm:hidden\">Back</span>\n <span className=\"hidden sm:inline\">Back to session</span>\n </Link>\n ) : (\n <Link to=\"/\" data-testid=\"settings-close\">\n Back\n </Link>\n )}\n </Button>\n </header>\n <main className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\">\n {workspace === 'repository' ? (\n <RepositoryWorkspace\n key={workspaceId ?? 'remembered-workspace'}\n current={current ?? { id: section ?? '', label: '', detail: '', workspace: 'repository' }}\n initialRepositoryId={workspaceId}\n onRepositoryChange={(nextWorkspaceId) => {\n void navigate({\n to: '/settings/$section',\n params: { section: current?.id ?? section ?? DEFAULT_REPOSITORY_SETTINGS_SECTION },\n search: { workspace: nextWorkspaceId },\n replace: true,\n });\n }}\n onReady={setRepositoryReady}\n />\n ) : (\n <div className=\"flex min-h-0 flex-1 flex-col lg:flex-row\">\n <SettingsMenu active={current?.id} workspace=\"general\" repositoryId={workspaceId} />\n <section\n data-testid=\"settings-content\"\n 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\"\n >\n {/* One column width for every page, so moving between sections does\n not re-flow the reading line. */}\n <div className=\"mx-auto flex w-full max-w-[720px] flex-col gap-8\">\n {!current && loadError ? <p role=\"alert\">{loadError}</p> : null}\n {current?.id === 'providers' ? <ProviderSettings /> : null}\n {current?.id === 'appearance' ? (\n <AppearanceSettings templateTarget={templateTarget} onTemplateTargetChange={setTemplateTarget} />\n ) : null}\n {current?.id === 'notifications' ? <NotificationSettings /> : null}\n {current?.id === 'images' ? <ImageSettings /> : null}\n {current?.id === 'remote' ? <RemoteControlSettings /> : null}\n {current?.id === 'plugins' ? <PluginSettings /> : null}\n {current?.contribution === undefined ? null : (\n <ContributedSettings section={current.contribution} scope=\"global\" />\n )}\n {current?.panel === undefined ? null : <SettingsPanelHost panel={current.panel} />}\n </div>\n </section>\n </div>\n )}\n </main>\n </div>\n );\n}\n","import {\n useDashboardRoute,\n sessionsStore,\n HOST_SLOTS,\n DashboardRendererProvider,\n type DashboardRenderers,\n watchDashboardTranscript,\n} from '@agimon-ai/po-web-dashboard';\nimport {\n DialogOverlay,\n RefusedCard,\n CommandPalette,\n PluginSurface,\n RemoteAccessDialog,\n PairingApprovalDialog,\n ThreadView,\n SessionActivity,\n SessionTranscriptView,\n} from '@agimon-ai/po-web-dashboard/views';\nimport { useStore } from '@tanstack/react-store';\n\nimport { ElegantConversation } from './ElegantConversation';\nimport { ElegantSettings } from './ElegantSettings';\n\nconst renderers: DashboardRenderers = {\n thread: (id, threadId, options) => <ThreadView sessionId={id} threadId={threadId} options={options} />,\n activity: (id, open) => <SessionActivity sessionId={id} onOpenConversation={open} />,\n transcript: (id, options) => (\n <SessionTranscriptView sessionId={id} options={options} watch={watchDashboardTranscript} />\n ),\n};\n\nexport function ElegantDashboard() {\n const route = useDashboardRoute();\n const sessionId = useStore(sessionsStore, (state) => state.activeId);\n return (\n <DashboardRendererProvider value={renderers}>\n {route.kind === 'settings' ? <ElegantSettings /> : <ElegantConversation />}\n <DialogOverlay />\n <RefusedCard />\n <CommandPalette />\n <PluginSurface slot={HOST_SLOTS.overlay} sessionId={sessionId} />\n <RemoteAccessDialog />\n <PairingApprovalDialog />\n </DashboardRendererProvider>\n );\n}\n","import type { WebTemplateFile } from '@agimon-ai/po-core/web';\n\nimport { ElegantDashboard } from '../_components/ElegantDashboard';\n\nexport const elegantTemplate = {\n label: 'Elegant',\n description: 'A focused conversation with collapsible navigation, session controls, and activity.',\n contractVersion: 2,\n app: ElegantDashboard,\n} satisfies WebTemplateFile;\n","import { defineWebTemplate } from '@agimon-ai/po-core/web';\n\nimport { elegantTemplate } from './_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","import { defineWebTemplate } from '@agimon-ai/po-core/web';\n\nimport { elegantTemplate } from '../../../(frontend)/template/_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","import { defineWebTemplate } from '@agimon-ai/po-core/web';\n\nimport { elegantTemplate } from '../../../../(frontend)/template/_lib/definition';\n\nexport default defineWebTemplate(elegantTemplate);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport templatePoTemplateElegant from '../src/extensions/(frontend)/template/po-template-elegant.web';\nimport templatePoTemplateElegant2 from '../src/extensions/workspaces/(frontend)/template/po-template-elegant.web';\nimport templatePoTemplateElegant3 from '../src/extensions/workspaces/sessions/(frontend)/template/po-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: 'po-template-elegant' }, templatePoTemplateElegant)]; },\n },\n workspace: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'po-template-elegant' }, templatePoTemplateElegant2)]; },\n },\n session: {\n get templates(): WebPluginContributions['templates'] { return [via({ id: 'po-template-elegant' }, templatePoTemplateElegant3)]; },\n },\n});\n"],"mappings":"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"}
package/llms.txt ADDED
@@ -0,0 +1,5 @@
1
+ # Po Elegant Template
2
+
3
+ A chat-first, independently installable web layout for the Po client.
4
+
5
+ - [Package guide](README.md): Installation through modes.yaml, scoped default configuration, and the template contribution contract.
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@agimon-ai/po-template-elegant",
3
+ "version": "0.0.0-alpha.0",
4
+ "description": "Elegant chat-first template for the Po web client.",
5
+ "keywords": [
6
+ "ai",
7
+ "coding-agent",
8
+ "developer-tools",
9
+ "pi-package",
10
+ "po",
11
+ "template",
12
+ "web"
13
+ ],
14
+ "bugs": {
15
+ "url": "https://github.com/AgiFlow/po/issues"
16
+ },
17
+ "license": "MIT",
18
+ "author": "Vuong Ngo",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/AgiFlow/po.git",
22
+ "directory": "layers/template/po-template-elegant"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE",
28
+ "llms.txt"
29
+ ],
30
+ "type": "module",
31
+ "exports": {
32
+ "./extensions/web": {
33
+ "import": "./dist/extensions/web.mjs"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "@agimon-ai/po-core": "0.0.0-alpha.0",
42
+ "@agimon-ai/po-web-components": "0.0.0-alpha.0",
43
+ "@agimon-ai/po-web-dashboard": "0.0.0-alpha.0",
44
+ "@tanstack/react-router": "1.170.41",
45
+ "@tanstack/react-store": "0.11.2"
46
+ },
47
+ "devDependencies": {
48
+ "@agimon-ai/po-build": "0.0.0-alpha.0",
49
+ "@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.0-alpha.0",
50
+ "@earendil-works/pi-coding-agent": "1.0.2",
51
+ "@types/node": "26.6.4",
52
+ "@types/react": "19.3.0",
53
+ "@types/react-dom": "19.3.0",
54
+ "react": "19.3.0",
55
+ "react-dom": "19.3.0",
56
+ "tsdown": "0.23.0",
57
+ "typescript": "7.0.2",
58
+ "vitest": "5.0.3"
59
+ },
60
+ "peerDependencies": {
61
+ "@earendil-works/pi-coding-agent": "1.0.2",
62
+ "react": "^19.0.0",
63
+ "react-dom": "^19.0.0"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "@earendil-works/pi-coding-agent": {
67
+ "optional": true
68
+ }
69
+ },
70
+ "engines": {
71
+ "node": ">=24"
72
+ },
73
+ "poWeb": {
74
+ "pluginId": "template-elegant",
75
+ "channels": [],
76
+ "client": "./dist/extensions/web.mjs",
77
+ "scopes": [
78
+ "global",
79
+ "workspace",
80
+ "session"
81
+ ]
82
+ },
83
+ "scripts": {
84
+ "build": "tsdown",
85
+ "test": "vitest --run",
86
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
87
+ "lint": "oxlint . && oxfmt . --check",
88
+ "fixcode": "oxlint . --fix && oxfmt ."
89
+ }
90
+ }