@inf-monkeys-tech/monkeys-design 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/agent-workbench/index.d.mts +3 -1
- package/dist/components/agent-workbench/index.d.ts +3 -1
- package/dist/components/agent-workbench/index.js +30 -5
- package/dist/components/agent-workbench/index.js.map +1 -1
- package/dist/components/agent-workbench/index.mjs +30 -5
- package/dist/components/agent-workbench/index.mjs.map +1 -1
- package/dist/index.js +30 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +30 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/locale/en-US.ts","../../../src/locale/resolve-locale.ts","../../../src/provider/context.ts","../../../src/components/layout/index.tsx","../../../src/components/agent-workbench/activity-model.ts","../../../src/components/agent-workbench/AgentWorkbenchTool.tsx","../../../src/components/agent-workbench/AgentWorkbenchActivity.tsx","../../../src/components/agent-workbench/details-model.ts","../../../src/components/agent-workbench/AgentWorkbenchTaskDetails.tsx"],"names":["createContext","useContext","jsx","Clock3","Loader2","CheckCircle2","XCircle","useState","jsxs","event","TerminalSquare","ChevronDown","Circle","JsonValue","CircleStop","Check","X","FileOutput","Download","latestBy","formatDuration","StatusIcon","RefreshCw","AlertCircle","Copy","RotateCcw","FileCode2","Files","TestTube2"],"mappings":"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","file":"index.js","sourcesContent":["import type { MonkeysLocale } from './types';\n\nexport const enUS = {\n locale: 'en-US',\n messages: {\n pagination: {\n navigation: 'Pagination',\n first: 'First',\n previous: 'Previous',\n next: 'Next',\n last: 'Last',\n page: ({ page, pageCount }) => `Page ${page} of ${pageCount}`,\n currentPage: ({ page, pageCount }) =>\n `Page ${page} of ${pageCount}, current page`,\n emptyResults: '0 results',\n range: ({ start, end, total }) => `${start}-${end} of ${total}`,\n },\n dialog: {\n close: 'Close dialog',\n },\n dropdownMenu: {\n actions: 'Actions',\n },\n loading: {\n spinner: 'Loading',\n },\n layout: {\n resizePanels: 'Resize panels',\n },\n steps: {\n label: 'Progress',\n current: 'Current',\n completed: 'Completed',\n error: 'Error',\n disabled: 'Disabled',\n },\n numberInput: {\n increment: 'Increase value',\n decrement: 'Decrease value',\n },\n passwordInput: {\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n },\n multiSelect: {\n placeholder: 'Select options',\n empty: 'No options',\n removeOption: ({ value }) => `Remove ${value}`,\n },\n table: {\n dragColumn: ({ columnId }) => `Drag column ${columnId}`,\n resizeColumn: ({ columnId }) => `Resize column ${columnId}`,\n sortColumn: ({ columnId }) =>\n columnId ? `Sort column ${columnId}` : 'Sort column',\n loadingRow: 'Loading table row',\n },\n toolbar: {\n theme: {\n label: 'Appearance',\n toggle: 'Toggle theme',\n auto: 'Auto',\n light: 'Light',\n dark: 'Dark',\n },\n language: {\n label: 'Language',\n switch: 'Switch language',\n },\n },\n toast: {\n errorTitle: 'Error',\n warningTitle: 'Warning',\n defaultErrorDescription: 'Something went wrong.',\n defaultWarningDescription: 'Please check and try again.',\n },\n dataExplorer: {\n viewTree: {\n actions: 'More actions',\n expand: 'Expand',\n collapse: 'Collapse',\n loading: 'Loading...',\n empty: 'No views',\n error: 'Unable to load views',\n },\n },\n workbench: {\n interactiveTable: {\n columnActions: 'Column actions',\n freezeColumn: 'Freeze to left',\n freezeEndColumn: 'Freeze to right',\n unfreezeColumn: 'Unfreeze from left',\n unfreezeEndColumn: 'Unfreeze from right',\n unfreezeAllColumns: 'Unfreeze all columns',\n resetColumnWidth: 'Reset column width',\n frozenColumnTitle: 'Frozen column',\n },\n },\n agentWorkbench: {\n label: 'Session activity',\n reasoning: 'Reasoning',\n plan: 'Plan',\n taskNoDetail: 'No additional details',\n tool: {\n input: 'Input',\n output: 'Output',\n status: {\n pending: 'Pending',\n running: 'Running',\n completed: 'Completed',\n failed: 'Error',\n denied: 'Denied',\n },\n },\n approval: {\n approve: 'Approve',\n reject: 'Reject',\n approved: 'Approved',\n rejected: 'Rejected',\n },\n artifact: {\n pending: 'Preparing',\n ready: 'Ready',\n failed: 'Failed',\n open: ({ name }) => `Open ${name}`,\n },\n run: {\n stopping: 'Stopping...',\n stoppedAfter: ({ duration }) => `You stopped after ${duration}`,\n },\n usage: {\n label: 'Context usage',\n context: ({ used, total }) => `${used} / ${total} tokens`,\n },\n details: {\n title: 'Task details',\n description: 'Summary and workspace activity',\n duration: 'Duration',\n updated: 'Updated',\n summary: 'Summary',\n summaryEmpty: 'No summary is available yet.',\n summaryFailed: 'The summary could not be generated.',\n highlights: 'Highlights',\n pendingItems: 'Pending items',\n tabs: {\n label: 'Task detail views',\n summary: 'Summary',\n workspace: 'Workspace',\n },\n status: {\n queued: 'Queued',\n running: 'Running',\n waiting_approval: 'Waiting for approval',\n stopping: 'Stopping',\n stopped: 'Stopped',\n completed: 'Completed',\n failed: 'Failed',\n },\n state: {\n loading: { title: 'Loading task details', description: 'Restoring the latest session activity.' },\n empty: { title: 'No task selected', description: 'Select a task to inspect its details.' },\n error: { title: 'Unable to load task details', description: 'Try again after the session is available.' },\n },\n actions: {\n close: 'Close task details',\n copySummary: 'Copy summary',\n retry: 'Retry',\n retrySummary: 'Retry summary',\n resume: 'Resume',\n },\n workspace: {\n diffs: 'Code changes',\n files: 'Files',\n terminals: 'Terminals',\n tests: 'Tests',\n artifacts: 'Artifacts',\n exitCode: ({ code }) => `Exit code ${code}`,\n diffStatus: { added: 'Added', modified: 'Modified', deleted: 'Deleted', renamed: 'Renamed' },\n fileOperation: { upsert: 'Updated', delete: 'Deleted' },\n },\n },\n },\n },\n} satisfies MonkeysLocale;\n","import { enUS } from './en-US';\nimport type {\n MonkeysBuiltInLocaleId,\n MonkeysLocale,\n MonkeysLocaleInput,\n MonkeysLocaleMessages,\n MonkeysLocaleMessagesOverride,\n MonkeysResolvedLocale,\n} from './types';\nimport { zhCN } from './zh-CN';\n\nconst BUILT_IN_LOCALES: Record<MonkeysBuiltInLocaleId, MonkeysLocale> = {\n 'en-US': enUS,\n 'zh-CN': zhCN,\n};\n\nfunction normalizeLocaleId(locale: unknown): string {\n if (typeof locale !== 'string' || !locale.trim()) {\n throw new TypeError('Monkeys locale must be a non-empty BCP 47 string.');\n }\n\n try {\n return Intl.getCanonicalLocales(locale)[0];\n } catch {\n throw new RangeError(\n `Monkeys locale \"${locale}\" is not a valid BCP 47 identifier.`,\n );\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction validateMessageOverride(\n value: unknown,\n schema: unknown,\n path: string,\n) {\n if (!isRecord(value) || !isRecord(schema)) {\n throw new TypeError(`${path} must be an object.`);\n }\n\n for (const [key, candidate] of Object.entries(value)) {\n if (candidate === undefined) continue;\n if (!(key in schema)) {\n throw new TypeError(`${path}.${key} is not a supported Monkeys message.`);\n }\n\n const expected = schema[key];\n const candidatePath = `${path}.${key}`;\n if (typeof expected === 'function') {\n if (typeof candidate !== 'function') {\n throw new TypeError(`${candidatePath} must be a function.`);\n }\n } else if (typeof expected === 'string') {\n if (typeof candidate !== 'string') {\n throw new TypeError(`${candidatePath} must be a string.`);\n }\n } else {\n validateMessageOverride(candidate, expected, candidatePath);\n }\n }\n}\n\nfunction assertMessagesOverride(\n value: unknown,\n path: string,\n): asserts value is MonkeysLocaleMessagesOverride {\n validateMessageOverride(value, enUS.messages, path);\n}\n\nfunction isBuiltInLocale(locale: string): locale is MonkeysBuiltInLocaleId {\n return locale === 'en-US' || locale === 'zh-CN';\n}\n\nfunction normalizeLocaleInput(input: MonkeysLocaleInput | undefined): {\n locale: string | undefined;\n messages: MonkeysLocaleMessagesOverride | undefined;\n hasExplicitLocale: boolean;\n} {\n if (input === undefined) {\n return {\n locale: undefined,\n messages: undefined,\n hasExplicitLocale: false,\n };\n }\n\n if (typeof input === 'string') {\n const locale = normalizeLocaleId(input);\n if (!isBuiltInLocale(locale)) {\n throw new RangeError(\n `Unsupported built-in Monkeys locale \"${locale}\". Provide a locale pack object for custom locales.`,\n );\n }\n return { locale, messages: undefined, hasExplicitLocale: true };\n }\n\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n throw new TypeError('Monkeys locale must be a locale id or locale pack object.');\n }\n\n const locale = normalizeLocaleId(input.locale);\n assertMessagesOverride(input.messages, 'Monkeys locale messages');\n\n return {\n locale,\n messages: input.messages,\n hasExplicitLocale: true,\n };\n}\n\nexport function mergeMonkeysLocaleMessages(\n base: MonkeysLocaleMessages,\n override?: MonkeysLocaleMessagesOverride,\n): MonkeysLocaleMessages {\n if (!override) return base;\n\n return {\n pagination: { ...base.pagination, ...override.pagination },\n dialog: { ...base.dialog, ...override.dialog },\n dropdownMenu: { ...base.dropdownMenu, ...override.dropdownMenu },\n loading: { ...base.loading, ...override.loading },\n layout: { ...base.layout, ...override.layout },\n steps: { ...base.steps, ...override.steps },\n numberInput: { ...base.numberInput, ...override.numberInput },\n passwordInput: { ...base.passwordInput, ...override.passwordInput },\n multiSelect: { ...base.multiSelect, ...override.multiSelect },\n table: { ...base.table, ...override.table },\n toolbar: {\n theme: { ...base.toolbar.theme, ...override.toolbar?.theme },\n language: { ...base.toolbar.language, ...override.toolbar?.language },\n },\n toast: { ...base.toast, ...override.toast },\n dataExplorer: {\n viewTree: {\n ...base.dataExplorer.viewTree,\n ...override.dataExplorer?.viewTree,\n },\n },\n workbench: {\n interactiveTable: {\n ...base.workbench.interactiveTable,\n ...override.workbench?.interactiveTable,\n },\n },\n agentWorkbench: {\n ...base.agentWorkbench,\n ...override.agentWorkbench,\n tool: {\n ...base.agentWorkbench.tool,\n ...override.agentWorkbench?.tool,\n status: {\n ...base.agentWorkbench.tool.status,\n ...override.agentWorkbench?.tool?.status,\n },\n },\n approval: {\n ...base.agentWorkbench.approval,\n ...override.agentWorkbench?.approval,\n },\n artifact: {\n ...base.agentWorkbench.artifact,\n ...override.agentWorkbench?.artifact,\n },\n run: {\n ...base.agentWorkbench.run,\n ...override.agentWorkbench?.run,\n },\n usage: {\n ...base.agentWorkbench.usage,\n ...override.agentWorkbench?.usage,\n },\n details: {\n ...base.agentWorkbench.details,\n ...override.agentWorkbench?.details,\n tabs: {\n ...base.agentWorkbench.details.tabs,\n ...override.agentWorkbench?.details?.tabs,\n },\n status: {\n ...base.agentWorkbench.details.status,\n ...override.agentWorkbench?.details?.status,\n },\n state: {\n loading: {\n ...base.agentWorkbench.details.state.loading,\n ...override.agentWorkbench?.details?.state?.loading,\n },\n empty: {\n ...base.agentWorkbench.details.state.empty,\n ...override.agentWorkbench?.details?.state?.empty,\n },\n error: {\n ...base.agentWorkbench.details.state.error,\n ...override.agentWorkbench?.details?.state?.error,\n },\n },\n actions: {\n ...base.agentWorkbench.details.actions,\n ...override.agentWorkbench?.details?.actions,\n },\n workspace: {\n ...base.agentWorkbench.details.workspace,\n ...override.agentWorkbench?.details?.workspace,\n diffStatus: {\n ...base.agentWorkbench.details.workspace.diffStatus,\n ...override.agentWorkbench?.details?.workspace?.diffStatus,\n },\n fileOperation: {\n ...base.agentWorkbench.details.workspace.fileOperation,\n ...override.agentWorkbench?.details?.workspace?.fileOperation,\n },\n },\n },\n },\n };\n}\n\nexport const defaultMonkeysLocale: MonkeysResolvedLocale = {\n locale: enUS.locale,\n messages: mergeMonkeysLocaleMessages(\n enUS.messages as MonkeysLocaleMessages,\n ),\n};\n\nexport function resolveMonkeysLocale(\n input?: MonkeysLocaleInput,\n override?: MonkeysLocaleMessagesOverride,\n parent?: MonkeysResolvedLocale,\n): MonkeysResolvedLocale {\n if (override !== undefined) {\n assertMessagesOverride(override, 'MonkeysProvider messages');\n }\n const normalized = normalizeLocaleInput(input);\n const locale = normalized.locale ?? parent?.locale ?? enUS.locale;\n const builtInMessages = isBuiltInLocale(locale)\n ? BUILT_IN_LOCALES[locale].messages\n : undefined;\n let messages = mergeMonkeysLocaleMessages(\n enUS.messages as MonkeysLocaleMessages,\n builtInMessages,\n );\n\n if (parent && (!normalized.hasExplicitLocale || parent.locale === locale)) {\n messages = mergeMonkeysLocaleMessages(messages, parent.messages);\n }\n\n messages = mergeMonkeysLocaleMessages(messages, normalized.messages);\n messages = mergeMonkeysLocaleMessages(messages, override);\n\n return { locale, messages };\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type Context,\n} from 'react';\n\nimport type { BaseAppearance } from '../components/base/types';\nimport type { DataExplorerAppearance } from '../components/data-explorer/types';\nimport {\n defaultMonkeysLocale,\n type MonkeysLocaleMessages,\n type MonkeysResolvedLocale,\n} from '../locale';\nimport type { CompiledThemeTokens } from '../theme-system';\n\nexport type MonkeysDirection = 'ltr' | 'rtl';\n\nexport interface MonkeysEnvironment {\n getDocument?: () => Document | null;\n getWindow?: () => Window | null;\n}\n\nexport type MonkeysPortalContainer =\n | Element\n | null\n | (() => Element | null);\n\nexport interface MonkeysPortalOptions {\n container?: MonkeysPortalContainer;\n disabled?: boolean;\n}\n\nexport interface MonkeysComponentAttributes {\n dir?: MonkeysDirection;\n 'data-monkeys-direction'?: MonkeysDirection;\n 'data-monkeys-locale'?: string;\n 'data-monkeys-theme'?: string;\n 'data-monkeys-theme-mode'?: string;\n}\n\ninterface MonkeysLocaleContextValue extends MonkeysResolvedLocale {\n provided: boolean;\n}\n\ninterface MonkeysThemeContextValue {\n provided: boolean;\n resolvedTheme?: CompiledThemeTokens;\n themeId?: string;\n baseAppearance?: BaseAppearance;\n dataExplorerAppearance?: DataExplorerAppearance;\n}\n\ninterface MonkeysDirectionContextValue {\n provided: boolean;\n direction?: MonkeysDirection;\n}\n\ninterface MonkeysEnvironmentContextValue {\n provided: boolean;\n environment: MonkeysEnvironment;\n portal: MonkeysPortalOptions;\n}\n\nconst EMPTY_ENVIRONMENT = Object.freeze({}) satisfies MonkeysEnvironment;\nconst EMPTY_PORTAL = Object.freeze({}) satisfies MonkeysPortalOptions;\n\ninterface MonkeysProviderContexts {\n locale: Context<MonkeysLocaleContextValue>;\n theme: Context<MonkeysThemeContextValue>;\n direction: Context<MonkeysDirectionContextValue>;\n environment: Context<MonkeysEnvironmentContextValue>;\n}\n\n// Every bundled public entry contains this module. Keep only the Context\n// identities in a realm-wide registry so root, provider, and component\n// subpaths interoperate in both CJS and ESM builds. Provider values remain in\n// React trees, so SSR requests are isolated. Bump the contract key only when\n// these Context value shapes become intentionally incompatible.\nconst MONKEYS_PROVIDER_CONTEXTS_KEY = Symbol.for(\n '@inf-monkeys-tech/monkeys-design/provider-context@1',\n);\n\ntype MonkeysProviderContextHost = typeof globalThis & {\n [MONKEYS_PROVIDER_CONTEXTS_KEY]?: MonkeysProviderContexts;\n};\n\nfunction createMonkeysProviderContexts(): MonkeysProviderContexts {\n return Object.freeze({\n locale: createContext<MonkeysLocaleContextValue>({\n ...defaultMonkeysLocale,\n provided: false,\n }),\n theme: createContext<MonkeysThemeContextValue>({\n provided: false,\n }),\n direction: createContext<MonkeysDirectionContextValue>({\n provided: false,\n }),\n environment: createContext<MonkeysEnvironmentContextValue>({\n provided: false,\n environment: EMPTY_ENVIRONMENT,\n portal: EMPTY_PORTAL,\n }),\n });\n}\n\nfunction getMonkeysProviderContexts(): MonkeysProviderContexts {\n const host = globalThis as MonkeysProviderContextHost;\n const existing = host[MONKEYS_PROVIDER_CONTEXTS_KEY];\n if (existing) return existing;\n\n const contexts = createMonkeysProviderContexts();\n Object.defineProperty(host, MONKEYS_PROVIDER_CONTEXTS_KEY, {\n value: contexts,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return contexts;\n}\n\nconst providerContexts = getMonkeysProviderContexts();\n\nexport const MonkeysLocaleContext = providerContexts.locale;\n\nexport const MonkeysThemeContext = providerContexts.theme;\n\nexport const MonkeysDirectionContext = providerContexts.direction;\n\nexport const MonkeysEnvironmentContext = providerContexts.environment;\n\nfunction mergeAppearance<T extends { slots?: object; styles?: object }>(\n inherited: T | undefined,\n explicit: T | undefined,\n): T | undefined {\n if (explicit === undefined) return inherited;\n if (inherited === undefined) return explicit;\n\n return {\n ...inherited,\n ...explicit,\n slots:\n inherited.slots || explicit.slots\n ? { ...inherited.slots, ...explicit.slots }\n : undefined,\n styles:\n inherited.styles || explicit.styles\n ? { ...inherited.styles, ...explicit.styles }\n : undefined,\n };\n}\n\nexport function useMonkeysLocale() {\n return useContext(MonkeysLocaleContext);\n}\n\nexport function useMonkeysLocaleMessages(): MonkeysLocaleMessages {\n return useContext(MonkeysLocaleContext).messages;\n}\n\nexport function useMonkeysResolvedTheme() {\n return useContext(MonkeysThemeContext).resolvedTheme;\n}\n\nexport function useMonkeysBaseAppearance(\n explicit?: BaseAppearance,\n): BaseAppearance | undefined {\n const inherited = useContext(MonkeysThemeContext).baseAppearance;\n return useMemo(\n () => mergeAppearance(inherited, explicit),\n [explicit, inherited],\n );\n}\n\nexport function useMonkeysDataExplorerAppearance(\n explicit?: DataExplorerAppearance,\n): DataExplorerAppearance | undefined {\n const inherited = useContext(MonkeysThemeContext).dataExplorerAppearance;\n return useMemo(\n () => mergeAppearance(inherited, explicit),\n [explicit, inherited],\n );\n}\n\nexport function useMonkeysDirection() {\n return useContext(MonkeysDirectionContext).direction;\n}\n\nexport function useMonkeysEnvironment() {\n return useContext(MonkeysEnvironmentContext).environment;\n}\n\nexport function useMonkeysPortalOptions() {\n return useContext(MonkeysEnvironmentContext).portal;\n}\n\nexport function useMonkeysComponentAttributes(): MonkeysComponentAttributes {\n const locale = useContext(MonkeysLocaleContext);\n const theme = useContext(MonkeysThemeContext);\n const direction = useContext(MonkeysDirectionContext);\n const providerActive = locale.provided || theme.provided || direction.provided;\n\n return useMemo(\n () =>\n providerActive\n ? {\n dir: direction.direction,\n 'data-monkeys-direction': direction.direction,\n 'data-monkeys-locale': locale.locale,\n 'data-monkeys-theme': theme.themeId,\n 'data-monkeys-theme-mode': theme.resolvedTheme?.colorMode,\n }\n : {},\n [\n direction.direction,\n locale.locale,\n providerActive,\n theme.resolvedTheme?.colorMode,\n theme.themeId,\n ],\n );\n}\n","import {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { BaseButton, BaseTooltip, type BaseAppearance } from \"../base\";\nexport { AppShellSidebar } from \"./AppShellSidebar\";\nexport type {\n AppShellSidebarClassNames,\n AppShellSidebarProps,\n} from \"./AppShellSidebar\";\nexport { UserAccountMenu } from \"./UserAccountMenu\";\nexport type {\n UserAccountMenuClassNames,\n UserAccountMenuItem,\n UserAccountMenuProps,\n UserAccountMenuRadius,\n UserAccountMenuSelectorConfig,\n UserAccountMenuSelectorOption,\n UserAccountMenuSide,\n UserAccountMenuTriggerVariant,\n UserAccountMenuUser,\n} from \"./UserAccountMenu\";\n\n// ============================================================\n// cn utility (inline clsx + tailwind-merge–lite for zero deps)\n// ============================================================\nexport function cn(...inputs: (string | undefined | null | false)[]): string {\n return inputs.filter(Boolean).join(\" \");\n}\n\n// ============================================================\n// NavButton\n// ============================================================\nexport interface NavButtonProps {\n /** 是否处于激活状态 */\n active?: boolean;\n /** 左侧图标 */\n icon?: ReactNode;\n /** 右侧附加内容(如 chevron) */\n postfix?: ReactNode;\n /** 点击回调 */\n onClick?: () => void;\n className?: string;\n children: ReactNode;\n}\n\nexport function NavButton({\n active,\n icon,\n postfix,\n onClick,\n className,\n children,\n}: NavButtonProps) {\n return (\n <div\n className={cn(\n \"flex w-full cursor-pointer select-none items-center gap-2 rounded-xl border p-2 text-xs text-[hsl(var(--foreground))] transition-colors\",\n active\n ? \"border-[hsl(var(--input))] bg-[hsl(var(--muted))] font-bold\"\n : \"border-transparent hover:border-[hsl(var(--input))]/60 hover:bg-[hsl(var(--muted))]/60\",\n className,\n )}\n onClick={onClick}\n >\n <div className=\"w-[20px] [&_svg]:h-[16px] [&_svg]:w-[16px]\">{icon}</div>\n <span className=\"text-sm\">{children}</span>\n {postfix}\n </div>\n );\n}\n\n// ============================================================\n// AppHeader\n// ============================================================\nexport interface HeaderTab {\n id: string;\n label: string;\n}\n\nexport interface AppHeaderLogo {\n /** Logo 图片 URL,若为空则显示 fallback */\n url?: string;\n /** 品牌名称 */\n title: string;\n /** 点击 Logo 回调 */\n onClick?: () => void;\n}\n\nexport interface AppHeaderUser {\n name?: string;\n email?: string;\n photo?: string;\n}\n\nexport interface AppHeaderProps {\n /** 品牌 Logo */\n logo: AppHeaderLogo;\n /** 导航 tabs */\n tabs?: HeaderTab[];\n /** 当前激活的 tab id */\n activeTab?: string;\n /** tab 切换回调 */\n onTabChange?: (tabId: string) => void;\n /** 用户信息 */\n user?: AppHeaderUser;\n /** 退出登录回调 */\n onLogout?: () => void;\n /** 退出登录文案 */\n logoutLabel?: string;\n /** 用户菜单中的额外菜单项(在退出登录按钮之前渲染) */\n userMenuItems?: ReactNode;\n /** header 右侧额外内容 */\n extra?: ReactNode;\n className?: string;\n}\n\nexport function AppHeader({\n logo,\n tabs,\n activeTab,\n onTabChange,\n user,\n onLogout,\n logoutLabel = \"退出登录\",\n userMenuItems,\n extra,\n className,\n}: AppHeaderProps) {\n const getUserInitials = (name: string) =>\n name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n\n return (\n <header\n className={cn(\n \"flex h-[72px] w-full shrink-0 items-center justify-between gap-4 rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-[var(--global-spacing,0.75rem)]\",\n className,\n )}\n >\n {/* Logo */}\n <div\n className=\"flex shrink-0 cursor-pointer items-center gap-2\"\n onClick={logo.onClick}\n >\n <div\n className={cn(\n \"flex h-8 w-8 items-center justify-center rounded-lg overflow-hidden\",\n logo.url\n ? \"bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"h-full w-full object-contain\"\n />\n ) : (\n <span className=\"text-sm font-bold\">{logo.title.charAt(0)}</span>\n )}\n </div>\n <span className=\"text-lg font-semibold whitespace-nowrap\">\n {logo.title}\n </span>\n </div>\n\n {/* Separator + Tabs */}\n {tabs && tabs.length > 0 && (\n <>\n <div className=\"h-1/2 w-px bg-[hsl(var(--border))]\" />\n <div className=\"flex flex-1 items-center\">\n <div className=\"inline-flex h-9 items-center gap-1 rounded-md bg-transparent p-1\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n className={cn(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all\",\n tab.id === activeTab\n ? \"bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--muted))]/50\",\n )}\n onClick={() => onTabChange?.(tab.id)}\n >\n {tab.label}\n </button>\n ))}\n </div>\n </div>\n </>\n )}\n {(!tabs || tabs.length === 0) && <div className=\"flex-1\" />}\n\n {/* Right side */}\n <div className=\"flex shrink-0 items-center gap-4\">\n {extra}\n {user && (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button className=\"flex h-8 w-8 items-center justify-center rounded-full hover:ring-2 hover:ring-[hsl(var(--ring))]/20 transition-all overflow-hidden focus-visible:outline-none\">\n {user.photo ? (\n <img\n src={user.photo}\n alt={user.name}\n className=\"h-8 w-8 rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-xs font-medium\">\n {user.name ? getUserInitials(user.name) : \"U\"}\n </div>\n )}\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"z-50 w-52 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-1 text-[hsl(var(--popover-foreground))] shadow-md animate-in fade-in-0 zoom-in-95\"\n sideOffset={5}\n align=\"end\"\n >\n {/* User info label */}\n <DropdownMenu.Label className=\"flex items-center gap-2 px-2 py-1.5 font-normal\">\n {user.photo ? (\n <img\n src={user.photo}\n alt={user.name}\n className=\"h-8 w-8 rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-xs font-medium\">\n {user.name ? getUserInitials(user.name) : \"U\"}\n </div>\n )}\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium leading-none\">\n {user.name}\n </span>\n {user.email && (\n <span className=\"text-xs text-[hsl(var(--muted-foreground))] leading-none mt-1\">\n {user.email}\n </span>\n )}\n </div>\n </DropdownMenu.Label>\n\n <DropdownMenu.Separator className=\"h-px bg-[hsl(var(--border))] my-1\" />\n\n <DropdownMenu.Group>\n {userMenuItems}\n\n {/* Logout */}\n <DropdownMenu.Item\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-[hsl(var(--destructive))] outline-none transition-colors hover:bg-[hsl(var(--accent))]\"\n onSelect={() => onLogout?.()}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </svg>\n {logoutLabel}\n </DropdownMenu.Item>\n </DropdownMenu.Group>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n )}\n </div>\n </header>\n );\n}\n\n// ============================================================\n// AppSidebar\n// ============================================================\nexport interface SidebarNavItem {\n id: string;\n label: string;\n icon?: ReactNode;\n /** 如果有 children 则为分组,点击展开/折叠 */\n children?: SidebarNavItem[];\n}\n\nexport interface SidebarAccount {\n name?: string;\n photo?: string;\n}\n\nexport interface AppSidebarProps {\n /** Logo */\n logo?: AppHeaderLogo;\n /** 导航菜单 */\n navItems: SidebarNavItem[];\n /** 当前路径/激活的 item id */\n activeItemId?: string;\n /** 点击导航项回调 */\n onNavigate?: (itemId: string) => void;\n /** 账户信息 */\n account?: SidebarAccount;\n /** 退出登录回调 */\n onLogout?: () => void;\n /** 退出登录文案 */\n logoutLabel?: string;\n /** 底部额外内容(如版本号) */\n footer?: ReactNode;\n /** 默认展开的分组 id 列表 */\n defaultExpandedGroups?: string[];\n className?: string;\n}\n\nexport function AppSidebar({\n logo,\n navItems,\n activeItemId,\n onNavigate,\n account,\n onLogout,\n logoutLabel = \"退出登录\",\n footer,\n defaultExpandedGroups,\n className,\n}: AppSidebarProps) {\n return (\n <div\n className={cn(\n \"flex w-[13.7rem] shrink-0 flex-col justify-between gap-[var(--global-spacing,0.75rem)] overflow-y-hidden rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-5\",\n className,\n )}\n >\n {/* Logo */}\n {logo && (\n <div\n className=\"flex shrink-0 cursor-pointer items-center gap-2\"\n onClick={logo.onClick}\n >\n <div\n className={cn(\n \"flex h-8 w-8 items-center justify-center rounded-lg overflow-hidden\",\n logo.url\n ? \"bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"h-full w-full object-contain\"\n />\n ) : (\n <span className=\"text-sm font-bold\">{logo.title.charAt(0)}</span>\n )}\n </div>\n <span className=\"text-lg font-semibold whitespace-nowrap\">\n {logo.title}\n </span>\n </div>\n )}\n\n {/* Navigation */}\n <SidebarNavList\n items={navItems}\n activeItemId={activeItemId}\n onNavigate={onNavigate}\n defaultExpandedGroups={defaultExpandedGroups}\n />\n\n {/* Account Section */}\n {(account || footer) && (\n <div className=\"flex flex-col gap-2\">\n {account && (\n <div className=\"flex w-full flex-col gap-2 rounded-lg bg-[hsl(var(--muted))] p-2 shadow-sm\">\n <div className=\"flex w-full items-center justify-between px-3 py-1\">\n <div className=\"flex items-center gap-2\">\n {account.photo ? (\n <img\n src={account.photo}\n alt={account.name}\n className=\"h-5 w-5 rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex h-5 w-5 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[10px] font-medium\">\n {account.name\n ? account.name.charAt(0).toUpperCase()\n : \"U\"}\n </div>\n )}\n <span className=\"text-xs font-medium truncate max-w-[100px]\">\n {account.name}\n </span>\n </div>\n {onLogout && (\n <button\n onClick={onLogout}\n className=\"flex items-center justify-center text-[hsl(var(--destructive))] hover:opacity-80 transition-opacity\"\n title={logoutLabel}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n )}\n {footer}\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================\n// SidebarNavList (internal accordion-style nav)\n// ============================================================\ninterface SidebarNavListProps {\n items: SidebarNavItem[];\n activeItemId?: string;\n onNavigate?: (itemId: string) => void;\n defaultExpandedGroups?: string[];\n}\n\nfunction SidebarNavList({\n items,\n activeItemId,\n onNavigate,\n defaultExpandedGroups,\n}: SidebarNavListProps) {\n const [expanded, setExpanded] = useState<Record<string, boolean>>(() => {\n const map: Record<string, boolean> = {};\n (defaultExpandedGroups ?? items.map((i) => i.id)).forEach((id) => {\n map[id] = true;\n });\n return map;\n });\n const [localActiveItemId, setLocalActiveItemId] = useState<\n string | undefined\n >(activeItemId);\n\n useEffect(() => {\n if (activeItemId !== undefined) {\n setLocalActiveItemId(activeItemId);\n }\n }, [activeItemId]);\n\n const toggle = (id: string) => {\n setExpanded((prev: Record<string, boolean>) => ({\n ...prev,\n [id]: !prev[id],\n }));\n };\n const resolvedActiveItemId = activeItemId ?? localActiveItemId;\n\n return (\n <div\n className=\"h-full flex-1 overflow-y-auto\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n <style>{`.monkeys-sidebar-nav::-webkit-scrollbar { display: none; }`}</style>\n <div className=\"monkeys-sidebar-nav flex w-full flex-col gap-2 text-xs text-[hsl(var(--foreground))]\">\n {items.map((item) => {\n if (item.children && item.children.length > 0) {\n const isExpanded = expanded[item.id] ?? true;\n return (\n <div key={item.id}>\n <NavButton\n icon={item.icon}\n onClick={() => toggle(item.id)}\n postfix={\n <div className=\"flex flex-1 justify-end\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0 text-[hsl(var(--foreground))] transition-transform duration-200\"\n style={{\n transform: isExpanded\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\",\n }}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </div>\n }\n >\n {item.label}\n </NavButton>\n {isExpanded && (\n <div className=\"flex flex-col gap-1 mt-1\">\n {item.children.map((child) => (\n <NavButton\n key={child.id}\n active={child.id === resolvedActiveItemId}\n onClick={() => {\n setLocalActiveItemId(child.id);\n onNavigate?.(child.id);\n }}\n >\n {child.label}\n </NavButton>\n ))}\n </div>\n )}\n </div>\n );\n }\n return (\n <NavButton\n key={item.id}\n icon={item.icon}\n active={item.id === resolvedActiveItemId}\n onClick={() => {\n setLocalActiveItemId(item.id);\n onNavigate?.(item.id);\n }}\n >\n {item.label}\n </NavButton>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ============================================================\n// AppLayout\n// ============================================================\nexport interface AppLayoutProps {\n /** header 组件 */\n header?: ReactNode;\n /** sidebar 组件 */\n sidebar?: ReactNode;\n /** 主内容 */\n children: ReactNode;\n /** 是否 flush 布局(无内边距) */\n flush?: boolean;\n className?: string;\n}\n\nexport function AppLayout({\n header,\n sidebar,\n children,\n flush = false,\n className,\n}: AppLayoutProps) {\n return (\n <div\n className={cn(\n \"flex h-screen flex-col gap-[var(--global-spacing,0.75rem)] overflow-hidden p-[var(--global-spacing,0.75rem)]\",\n className,\n )}\n style={{ backgroundColor: \"hsl(var(--muted))\" }}\n >\n {header ? header : null}\n <div className=\"flex flex-1 gap-[var(--global-spacing,0.75rem)] overflow-hidden min-h-0\">\n {sidebar ? sidebar : null}\n <main\n className={cn(\n \"flex-1 min-h-0 overflow-hidden rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))]\",\n !flush && \"overflow-y-auto\",\n )}\n >\n {flush ? (\n children\n ) : (\n <div className=\"h-full overflow-y-auto\">{children}</div>\n )}\n </main>\n </div>\n </div>\n );\n}\n\n// ============================================================\n// NavigationLayout\n// ============================================================\nexport type NavigationMode = \"sidebar\" | \"headbar\";\nexport type HeadbarLayoutMode = \"boxed\" | \"full-bleed\";\nexport type HeadbarMenuRadius =\n \"default\" | \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\nexport type HeadbarNavPosition = \"left\" | \"center\" | \"right\";\nexport type HeadbarSurface = \"card\" | \"glassy\" | \"ghost\";\n\nexport interface LayoutNavItem {\n id: string;\n label: ReactNode;\n headbarLabel?: ReactNode;\n icon?: ReactNode;\n children?: LayoutNavItem[];\n disabled?: boolean;\n trailing?: ReactNode;\n}\n\ninterface NavigationLayoutAction {\n id: string;\n label: ReactNode;\n title?: string;\n icon?: ReactNode;\n onClick?: () => void;\n}\n\nexport interface HeadbarLayout {\n brandTitle?: ReactNode;\n heightPx?: number;\n layoutMode?: HeadbarLayoutMode;\n menuRadius?: HeadbarMenuRadius;\n navPosition?: HeadbarNavPosition;\n surface?: HeadbarSurface;\n}\n\nexport interface NavigationLayoutProps {\n activeItemId?: string;\n activeRootId?: string;\n allowModeSwitch?: boolean;\n accountMenu?: ReactNode;\n children: ReactNode;\n className?: string;\n collapsedSidebarAccountMenu?: ReactNode;\n collapsedSidebarWidth?: string;\n defaultMode?: NavigationMode;\n defaultSidebarCollapsed?: boolean;\n expandedSidebarWidth?: string;\n expandSidebarLabel?: string;\n flush?: boolean;\n headbarActions?: ReactNode;\n headbarLayout?: HeadbarLayout;\n logo?: AppHeaderLogo;\n mode?: NavigationMode;\n navItems: LayoutNavItem[];\n onModeChange?: (mode: NavigationMode) => void;\n onNavigate?: (itemId: string) => void;\n onSidebarCollapsedChange?: (collapsed: boolean) => void;\n renderHeadbarExtra?: ReactNode;\n collapseSidebarLabel?: string;\n sidebarCollapsed?: boolean;\n sidebarAccountMenu?: ReactNode;\n sidebarFooter?: ReactNode;\n sidebarHeader?: ReactNode;\n switchToHeadbarLabel?: string;\n switchToSidebarLabel?: string;\n}\n\nconst NAVIGATION_LAYOUT_SIDEBAR_EXPANDED_WIDTH = \"13.7rem\";\nconst NAVIGATION_LAYOUT_SIDEBAR_COLLAPSED_WIDTH = \"4.25rem\";\nconst NAVIGATION_LAYOUT_TRANSITION_TIMING = \"cubic-bezier(0.22, 1, 0.36, 1)\";\nconst NAVIGATION_LAYOUT_HEADBAR_DEFAULT_HEIGHT_PX = 72;\nconst NAVIGATION_LAYOUT_HEADBAR_MIN_HEIGHT_PX = 56;\nconst NAVIGATION_LAYOUT_HEADBAR_MAX_HEIGHT_PX = 120;\nconst NAVIGATION_LAYOUT_HEADBAR_COMPACT_HEIGHT_THRESHOLD_PX = 64;\nconst NAVIGATION_LAYOUT_HEADBAR_BOXED_VERTICAL_PADDING_PX = 12;\nconst NAVIGATION_LAYOUT_HEADBAR_COMPACT_VERTICAL_PADDING_PX = 8;\nconst NAVIGATION_LAYOUT_HEADBAR_LOGO_DEFAULT_SIZE_PX = 44;\nconst NAVIGATION_LAYOUT_HEADBAR_LOGO_COMPACT_SIZE_PX = 36;\nconst NAVIGATION_LAYOUT_DEFAULT_APPEARANCE: BaseAppearance = {\n preset: \"soft\",\n density: \"compact\",\n radius: \"lg\",\n border: \"subtle\",\n background: \"soft\",\n};\n\nconst NAVIGATION_LAYOUT_MENU_RADIUS_CLASS_MAP: Record<\n Exclude<HeadbarMenuRadius, \"default\">,\n { all: string; left: string; right: string }\n> = {\n none: { all: \"rounded-none\", left: \"!rounded-none\", right: \"!rounded-none\" },\n sm: {\n all: \"rounded-sm\",\n left: \"!rounded-l-sm !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-sm\",\n },\n md: {\n all: \"rounded-md\",\n left: \"!rounded-l-md !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-md\",\n },\n lg: {\n all: \"rounded-lg\",\n left: \"!rounded-l-lg !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-lg\",\n },\n xl: {\n all: \"rounded-xl\",\n left: \"!rounded-l-xl !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-xl\",\n },\n full: {\n all: \"rounded-full\",\n left: \"!rounded-l-full !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-full\",\n },\n};\n\nfunction clampHeadbarHeight(value?: number) {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n return NAVIGATION_LAYOUT_HEADBAR_DEFAULT_HEIGHT_PX;\n return Math.min(\n NAVIGATION_LAYOUT_HEADBAR_MAX_HEIGHT_PX,\n Math.max(NAVIGATION_LAYOUT_HEADBAR_MIN_HEIGHT_PX, Math.round(value)),\n );\n}\n\nfunction getHeadbarVerticalPaddingPx(heightPx: number) {\n return heightPx <= NAVIGATION_LAYOUT_HEADBAR_COMPACT_HEIGHT_THRESHOLD_PX\n ? NAVIGATION_LAYOUT_HEADBAR_COMPACT_VERTICAL_PADDING_PX\n : NAVIGATION_LAYOUT_HEADBAR_BOXED_VERTICAL_PADDING_PX;\n}\n\nfunction getHeadbarLogoSizePx(heightPx: number) {\n return heightPx <= NAVIGATION_LAYOUT_HEADBAR_COMPACT_HEIGHT_THRESHOLD_PX\n ? NAVIGATION_LAYOUT_HEADBAR_LOGO_COMPACT_SIZE_PX\n : NAVIGATION_LAYOUT_HEADBAR_LOGO_DEFAULT_SIZE_PX;\n}\n\nfunction getHeadbarMenuRadiusClass(\n menuRadius: HeadbarMenuRadius = \"default\",\n part: \"all\" | \"left\" | \"right\" = \"all\",\n) {\n if (menuRadius === \"default\") {\n if (part === \"left\") return \"rounded-l-lg rounded-r-none\";\n if (part === \"right\") return \"rounded-l-none rounded-r-lg\";\n return \"rounded-lg\";\n }\n return NAVIGATION_LAYOUT_MENU_RADIUS_CLASS_MAP[menuRadius][part];\n}\n\nfunction getHeadbarFrameClass(\n layoutMode: HeadbarLayoutMode = \"boxed\",\n navPosition: HeadbarNavPosition = \"center\",\n) {\n const columns =\n navPosition === \"center\"\n ? \"grid-cols-[minmax(max-content,1fr)_minmax(0,max-content)_minmax(max-content,1fr)]\"\n : \"grid-cols-[max-content_minmax(0,1fr)_max-content]\";\n return layoutMode === \"full-bleed\"\n ? cn(\n \"sticky top-0 z-40 grid w-full shrink-0 items-center gap-4 rounded-none border-b border-x-0 border-t-0 border-[hsl(var(--input))] bg-[hsl(var(--background))] p-[var(--global-spacing,0.75rem)]\",\n columns,\n )\n : cn(\n \"sticky top-0 z-40 grid w-full shrink-0 items-center gap-4 rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-[var(--global-spacing,0.75rem)]\",\n columns,\n );\n}\n\nfunction getHeadbarFrameStyle(\n layoutMode: HeadbarLayoutMode = \"boxed\",\n heightPx: number,\n surface: HeadbarSurface = \"card\",\n): CSSProperties {\n const verticalPaddingPx = getHeadbarVerticalPaddingPx(heightPx);\n const fallbackBackground = \"hsl(var(--background))\";\n const style: CSSProperties = {\n height: `var(--monkeys-component-navigation-headbar-height, ${heightPx}px)`,\n minHeight: `var(--monkeys-component-navigation-headbar-height, ${heightPx}px)`,\n paddingTop: `${verticalPaddingPx}px`,\n paddingBottom: `${verticalPaddingPx}px`,\n background: `var(--monkeys-component-navigation-headbar-frame-background, ${fallbackBackground})`,\n color:\n \"var(--monkeys-component-navigation-headbar-frame-foreground, hsl(var(--foreground)))\",\n borderColor:\n surface === \"glassy\"\n ? \"var(--monkeys-component-navigation-headbar-frame-border-color, rgb(255 255 255 / 0.5))\"\n : \"var(--monkeys-component-navigation-headbar-frame-border-color, hsl(var(--input)))\",\n borderRadius:\n layoutMode === \"full-bleed\"\n ? \"0\"\n : \"var(--monkeys-component-navigation-headbar-frame-radius, var(--radius, 0.75rem))\",\n boxShadow:\n surface === \"glassy\"\n ? \"var(--monkeys-component-navigation-headbar-frame-shadow, inset 0 0 0 0 rgb(0 0 0 / 0.1))\"\n : \"var(--monkeys-component-navigation-headbar-frame-shadow, none)\",\n backdropFilter: `blur(var(--monkeys-component-navigation-headbar-frame-backdrop-blur, ${surface === \"glassy\" ? \"45px\" : \"0px\"}))`,\n };\n\n if (layoutMode === \"full-bleed\") {\n style.marginLeft = \"calc(var(--global-spacing,0.75rem) * -1)\";\n style.marginRight = \"calc(var(--global-spacing,0.75rem) * -1)\";\n style.marginTop = \"calc(var(--global-spacing,0.75rem) * -1)\";\n style.width = \"calc(100% + (var(--global-spacing,0.75rem) * 2))\";\n }\n\n return style;\n}\n\nfunction getHeadbarNavClass(navPosition: HeadbarNavPosition = \"center\") {\n if (navPosition === \"left\") return \"justify-start\";\n if (navPosition === \"right\") return \"justify-end\";\n return \"justify-center\";\n}\n\nfunction getHeadbarItemStyle(\n active: boolean,\n useTokenRadius = true,\n): CSSProperties {\n return {\n height: \"var(--monkeys-component-navigation-headbar-item-height, 2.25rem)\",\n borderRadius: useTokenRadius\n ? \"var(--monkeys-component-navigation-headbar-item-radius, var(--radius, 0.5rem))\"\n : undefined,\n paddingInline:\n \"var(--monkeys-component-navigation-headbar-item-padding-inline, 0.75rem)\",\n columnGap: \"var(--monkeys-component-navigation-headbar-item-gap, 0.375rem)\",\n color: active\n ? \"var(--monkeys-component-navigation-headbar-item-active-foreground, hsl(var(--foreground)))\"\n : \"var(--monkeys-component-navigation-headbar-item-foreground, hsl(var(--muted-foreground)))\",\n background: active\n ? \"var(--monkeys-component-navigation-headbar-item-active-background, hsl(var(--muted)))\"\n : \"transparent\",\n borderColor: active\n ? \"var(--monkeys-component-navigation-headbar-item-active-border-color, transparent)\"\n : \"transparent\",\n fontSize:\n \"var(--monkeys-component-navigation-headbar-item-font-size, 0.875rem)\",\n fontWeight:\n \"var(--monkeys-component-navigation-headbar-item-font-weight, 500)\",\n };\n}\n\nfunction findNavigationRootId(\n items: LayoutNavItem[],\n activeItemId?: string,\n): string | undefined {\n for (const item of items) {\n if (item.id === activeItemId) return item.id;\n if (item.children?.some((child) => child.id === activeItemId))\n return item.id;\n }\n return activeItemId;\n}\n\nfunction getNavigationActionTitle(action: NavigationLayoutAction) {\n return (\n action.title ||\n (typeof action.label === \"string\" ? action.label : undefined)\n );\n}\n\nfunction NavigationLayoutActionButtons({\n actions,\n compact,\n}: {\n actions: NavigationLayoutAction[];\n compact: boolean;\n}) {\n if (!actions.length) return null;\n\n if (compact) {\n return (\n <div className=\"flex flex-col items-center gap-2\">\n {actions.map((action) => {\n const title = getNavigationActionTitle(action);\n return (\n <BaseTooltip\n key={action.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n content={action.label}\n placement=\"right\"\n portal\n >\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n iconOnly\n icon={action.icon}\n onClick={action.onClick}\n title={title}\n ariaLabel={title}\n className={cn(\n \"h-10 w-10 rounded-lg border-transparent text-[hsl(var(--muted-foreground))] shadow-none\",\n \"hover:-translate-y-0.5 hover:border-[hsl(var(--input))]/80 hover:bg-[hsl(var(--muted))] hover:text-[hsl(var(--foreground))]\",\n \"active:translate-y-0 active:scale-[0.96]\",\n )}\n />\n </BaseTooltip>\n );\n })}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {actions.map((action) => (\n <BaseButton\n key={action.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n icon={action.icon}\n label={<span className=\"truncate\">{action.label}</span>}\n onClick={action.onClick}\n title={getNavigationActionTitle(action)}\n className={cn(\n \"h-9 w-full justify-start gap-2.5 rounded-lg border-transparent px-3 text-left text-[13px] text-[hsl(var(--muted-foreground))] shadow-none\",\n \"hover:-translate-y-0.5 hover:border-[hsl(var(--input))]/80 hover:bg-[hsl(var(--muted))]/70 hover:text-[hsl(var(--foreground))]\",\n \"active:translate-y-0 active:scale-[0.985]\",\n )}\n />\n ))}\n </div>\n );\n}\n\nfunction SidebarNavigationList({\n activeItemId,\n items,\n onNavigate,\n revealRequest,\n}: {\n activeItemId?: string;\n items: LayoutNavItem[];\n onNavigate?: (itemId: string) => void;\n revealRequest?: { id: string; nonce: number } | null;\n}) {\n const navRef = useRef<HTMLDivElement | null>(null);\n const [expandedByRoot, setExpandedByRoot] = useState<Record<string, boolean>>(\n {},\n );\n\n const toggleRoot = (id: string) => {\n setExpandedByRoot((current) => ({\n ...current,\n [id]: !current[id],\n }));\n };\n\n useEffect(() => {\n if (!revealRequest) return;\n setExpandedByRoot((current) => ({\n ...current,\n [revealRequest.id]: true,\n }));\n\n const frameId = window.requestAnimationFrame(() => {\n const targetElement = navRef.current?.querySelector(\n `[data-navigation-sidebar-root-id=\"${CSS.escape(revealRequest.id)}\"]`,\n );\n if (targetElement instanceof HTMLElement) {\n targetElement.scrollIntoView({\n behavior: \"auto\",\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n });\n\n return () => window.cancelAnimationFrame(frameId);\n }, [revealRequest]);\n\n return (\n <div\n className=\"h-full flex-1 overflow-y-auto\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n <style>{`.monkeys-navigation-sidebar-nav::-webkit-scrollbar { display: none; }`}</style>\n <div\n ref={navRef}\n className=\"monkeys-navigation-sidebar-nav flex w-full flex-col gap-2 text-xs text-[hsl(var(--foreground))]\"\n >\n {items.map((item) => {\n const isGroup = Boolean(item.children?.length);\n const isExpanded = Boolean(expandedByRoot[item.id]);\n const isActive = activeItemId === item.id;\n\n if (isGroup) {\n return (\n <div key={item.id} data-navigation-sidebar-root-id={item.id}>\n <NavButton\n icon={item.icon}\n onClick={() => toggleRoot(item.id)}\n postfix={\n <div className=\"flex flex-1 justify-end\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0 text-[hsl(var(--foreground))] transition-transform duration-200\"\n style={{\n transform: isExpanded\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\",\n }}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </div>\n }\n >\n {item.label}\n </NavButton>\n {isExpanded ? (\n <div className=\"mt-1 flex flex-col gap-1\">\n {item.children?.map((child) => (\n <NavButton\n key={child.id}\n active={activeItemId === child.id}\n onClick={() => onNavigate?.(child.id)}\n >\n {child.label}\n </NavButton>\n ))}\n </div>\n ) : null}\n </div>\n );\n }\n\n return (\n <div key={item.id} data-navigation-sidebar-root-id={item.id}>\n <NavButton\n active={isActive}\n icon={item.icon}\n onClick={() => onNavigate?.(item.id)}\n >\n {item.label}\n </NavButton>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction SidebarBrand({\n collapsed,\n logo,\n title,\n}: {\n collapsed?: boolean;\n logo?: AppHeaderLogo;\n title?: ReactNode;\n}) {\n if (!logo) return null;\n\n const brandTitle = title ?? logo.title;\n const logoMark = (\n <div\n className={cn(\n \"flex h-9 w-9 shrink-0 items-center justify-center overflow-hidden rounded-lg\",\n logo.url\n ? \"bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"h-full w-full object-contain\"\n />\n ) : (\n <span className=\"text-sm font-bold\">{logo.title.charAt(0)}</span>\n )}\n </div>\n );\n\n if (collapsed) {\n return (\n <BaseTooltip\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n content={brandTitle}\n placement=\"right\"\n portal\n >\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n ariaLabel={typeof brandTitle === \"string\" ? brandTitle : logo.title}\n className=\"h-10 w-10 rounded-lg border-transparent bg-transparent p-0 shadow-none hover:bg-[hsl(var(--muted))]/60\"\n icon={logoMark}\n iconOnly\n onClick={logo.onClick}\n title={typeof brandTitle === \"string\" ? brandTitle : logo.title}\n tone=\"muted\"\n />\n </BaseTooltip>\n );\n }\n\n return (\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n ariaLabel={logo.title}\n className=\"h-auto w-full justify-start gap-3 border-transparent bg-transparent p-0 text-left shadow-none hover:bg-transparent\"\n classNames={{ icon: \"h-9 w-9\" }}\n icon={logoMark}\n label={\n <span className=\"min-w-0 truncate text-sm font-semibold text-[hsl(var(--foreground))]\">\n {brandTitle}\n </span>\n }\n onClick={logo.onClick}\n title={typeof brandTitle === \"string\" ? brandTitle : logo.title}\n tone=\"muted\"\n />\n );\n}\n\nfunction Sidebar({\n accountMenu,\n activeItemId,\n actions = [],\n collapsed,\n collapsedAccountMenu,\n footer,\n header,\n items,\n logo,\n onCollapsedChange,\n onNavigate,\n onRevealRoot,\n revealRequest,\n title,\n}: {\n accountMenu?: ReactNode;\n activeItemId?: string;\n actions?: NavigationLayoutAction[];\n collapsed?: boolean;\n collapsedAccountMenu?: ReactNode;\n footer?: ReactNode;\n header?: ReactNode;\n items: LayoutNavItem[];\n logo?: AppHeaderLogo;\n onCollapsedChange?: (collapsed: boolean) => void;\n onNavigate?: (itemId: string) => void;\n onRevealRoot?: (rootId: string) => void;\n revealRequest?: { id: string; nonce: number } | null;\n title?: ReactNode;\n}) {\n if (collapsed) {\n const activeRootId = findNavigationRootId(items, activeItemId);\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-2 shadow-sm\">\n <div className=\"mb-3 flex shrink-0 justify-center\">\n {header ?? <SidebarBrand collapsed logo={logo} title={title} />}\n </div>\n <div\n className=\"flex min-h-0 flex-1 flex-col items-center gap-2 overflow-y-auto pb-3\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n {items.map((item) => {\n const isActive = activeRootId === item.id;\n return (\n <BaseTooltip\n key={item.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n content={item.label}\n placement=\"right\"\n portal\n >\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n active={isActive}\n iconOnly\n icon={item.icon}\n onClick={() => {\n onRevealRoot?.(item.id);\n onCollapsedChange?.(false);\n if (item.children?.length) return;\n onNavigate?.(item.id);\n }}\n title={\n typeof item.label === \"string\" ? item.label : undefined\n }\n ariaLabel={\n typeof item.label === \"string\" ? item.label : item.id\n }\n className={cn(\n \"h-10 w-10 rounded-lg border text-[hsl(var(--muted-foreground))] shadow-none\",\n \"hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.96]\",\n isActive\n ? \"border-[hsl(var(--input))] bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"border-transparent hover:border-[hsl(var(--input))]/80 hover:bg-[hsl(var(--muted))]/70 hover:text-[hsl(var(--foreground))]\",\n )}\n />\n </BaseTooltip>\n );\n })}\n </div>\n <div className=\"-mx-2 mt-2 border-t border-[hsl(var(--input))] bg-[hsl(var(--background))] px-2 pt-2.5 pb-0.5\">\n <NavigationLayoutActionButtons actions={actions} compact />\n {collapsedAccountMenu ? (\n <div className=\"mt-2 flex justify-center border-t border-[hsl(var(--input))] pt-2\">\n {collapsedAccountMenu}\n </div>\n ) : null}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col justify-between gap-0 overflow-y-hidden rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] px-5 pt-5 pb-1.5\">\n <div className=\"mb-4 shrink-0\">\n {header ?? <SidebarBrand logo={logo} title={title} />}\n </div>\n <SidebarNavigationList\n activeItemId={activeItemId}\n items={items}\n onNavigate={onNavigate}\n revealRequest={revealRequest}\n />\n <div className=\"-mx-5 mt-2 border-t border-[hsl(var(--input))] bg-[hsl(var(--background))] px-4 pt-2.5 pb-1\">\n <NavigationLayoutActionButtons actions={actions} compact={false} />\n {footer}\n {accountMenu ? (\n <div className=\"mt-2 border-t border-[hsl(var(--input))] pt-2\">\n {accountMenu}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction HeadbarChevronIcon({ open }: { open: boolean }) {\n return (\n <svg\n aria-hidden=\"true\"\n className={cn(\n \"h-4 w-4 shrink-0 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nfunction HeadbarNavMenuItem({\n activeItemId,\n isActive,\n item,\n label,\n menuButtonRadiusClass,\n menuContentRadiusClass,\n menuItemRadiusClass,\n onNavigate,\n useTokenRadius,\n}: {\n activeItemId?: string;\n isActive: boolean;\n item: LayoutNavItem;\n label: ReactNode;\n menuButtonRadiusClass: string;\n menuContentRadiusClass: string;\n menuItemRadiusClass: string;\n onNavigate?: (itemId: string) => void;\n useTokenRadius: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearCloseTimer = () => {\n if (!closeTimerRef.current) return;\n clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n };\n\n const openMenu = () => {\n clearCloseTimer();\n setOpen(true);\n };\n\n const scheduleCloseMenu = () => {\n clearCloseTimer();\n closeTimerRef.current = setTimeout(() => {\n setOpen(false);\n closeTimerRef.current = null;\n }, 120);\n };\n\n useEffect(() => clearCloseTimer, []);\n\n return (\n <DropdownMenu.Root modal={false} open={open} onOpenChange={setOpen}>\n <DropdownMenu.Trigger asChild>\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n active={isActive || open}\n icon={item.icon}\n endIcon={<HeadbarChevronIcon open={open} />}\n label={<span className=\"truncate whitespace-nowrap\">{label}</span>}\n disabled={item.disabled}\n onClick={() => setOpen(true)}\n onMouseEnter={openMenu}\n onMouseLeave={scheduleCloseMenu}\n style={getHeadbarItemStyle(isActive || open, useTokenRadius)}\n classNames={{\n icon: \"text-[inherit] [&_*]:!text-[inherit] [&_svg]:!stroke-current\",\n label: \"text-[inherit] [&_*]:!text-[inherit]\",\n }}\n className={cn(\n \"max-w-[12rem] shrink-0 border shadow-none\",\n menuButtonRadiusClass,\n isActive || open\n ? \"\"\n : \"hover:!bg-[var(--monkeys-component-navigation-headbar-item-hover-background,hsl(var(--muted)))] hover:!text-[var(--monkeys-component-navigation-headbar-item-hover-foreground,hsl(var(--foreground)))]\",\n )}\n />\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n align=\"start\"\n sideOffset={5}\n onCloseAutoFocus={(event) => event.preventDefault()}\n onMouseEnter={openMenu}\n onMouseLeave={scheduleCloseMenu}\n className={cn(\n \"z-50 min-w-56 border p-1.5 animate-in fade-in-0 zoom-in-95\",\n menuContentRadiusClass,\n )}\n style={{\n background:\n \"var(--monkeys-component-navigation-headbar-menu-background, hsl(var(--popover)))\",\n borderColor:\n \"var(--monkeys-component-navigation-headbar-menu-border-color, hsl(var(--border)))\",\n color:\n \"var(--monkeys-component-navigation-headbar-menu-foreground, hsl(var(--popover-foreground)))\",\n boxShadow:\n \"var(--monkeys-component-navigation-headbar-menu-shadow, 0 10px 15px -3px rgb(0 0 0 / 0.1))\",\n backdropFilter:\n \"blur(var(--monkeys-component-navigation-headbar-menu-backdrop-blur, 0px))\",\n }}\n >\n {item.children?.map((child) => (\n <DropdownMenu.Item\n key={child.id}\n disabled={child.disabled}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2.5 px-3 py-2 text-sm outline-none transition-colors hover:bg-[var(--monkeys-component-navigation-headbar-item-hover-background,hsl(var(--accent)))]\",\n menuItemRadiusClass,\n )}\n style={getHeadbarItemStyle(\n child.id === activeItemId,\n useTokenRadius,\n )}\n onSelect={() => {\n if (child.disabled) return;\n setOpen(false);\n onNavigate?.(child.id);\n }}\n >\n {child.icon ? (\n <span className=\"inline-flex h-4 w-4 shrink-0 items-center justify-center text-[hsl(var(--muted-foreground))]\">\n {child.icon}\n </span>\n ) : null}\n <span className=\"min-w-0 truncate\">\n {child.headbarLabel ?? child.label}\n </span>\n {child.trailing}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n}\n\nexport interface NavigationHeadbarMenuProps {\n activeItemId?: string;\n activeRootId?: string;\n items: LayoutNavItem[];\n menuRadius?: HeadbarMenuRadius;\n onNavigate?: (itemId: string) => void;\n}\n\nexport function NavigationHeadbarMenu({\n activeItemId,\n activeRootId,\n items,\n menuRadius = \"default\",\n onNavigate,\n}: NavigationHeadbarMenuProps) {\n const menuButtonRadiusClass = getHeadbarMenuRadiusClass(menuRadius);\n const menuContentRadiusClass = getHeadbarMenuRadiusClass(menuRadius);\n const menuItemRadiusClass = getHeadbarMenuRadiusClass(menuRadius);\n const useTokenRadius = menuRadius === \"default\";\n\n return (\n <div className=\"flex w-max min-w-0 shrink-0 items-center gap-1\">\n {items.map((item) => {\n const isActive = activeRootId === item.id || activeItemId === item.id;\n const label = item.headbarLabel ?? item.label;\n\n if (item.children?.length) {\n return (\n <HeadbarNavMenuItem\n key={item.id}\n activeItemId={activeItemId}\n isActive={isActive}\n item={item}\n label={label}\n menuButtonRadiusClass={menuButtonRadiusClass}\n menuContentRadiusClass={menuContentRadiusClass}\n menuItemRadiusClass={menuItemRadiusClass}\n onNavigate={onNavigate}\n useTokenRadius={useTokenRadius}\n />\n );\n }\n\n return (\n <BaseButton\n key={item.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n active={isActive}\n disabled={item.disabled}\n icon={item.icon}\n label={\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span className=\"truncate whitespace-nowrap\">{label}</span>\n {item.trailing}\n </span>\n }\n onClick={() => onNavigate?.(item.id)}\n style={getHeadbarItemStyle(isActive, useTokenRadius)}\n classNames={{\n icon: \"text-[inherit] [&_*]:!text-[inherit] [&_svg]:!stroke-current\",\n label: \"text-[inherit] [&_*]:!text-[inherit]\",\n }}\n className={cn(\n \"max-w-[12rem] shrink-0 border shadow-none\",\n menuButtonRadiusClass,\n isActive\n ? \"\"\n : \"hover:!bg-[var(--monkeys-component-navigation-headbar-item-hover-background,hsl(var(--muted)))] hover:!text-[var(--monkeys-component-navigation-headbar-item-hover-foreground,hsl(var(--foreground)))]\",\n )}\n />\n );\n })}\n </div>\n );\n}\n\nexport interface NavigationHeadbarProps {\n activeItemId?: string;\n activeRootId?: string;\n actions?: ReactNode;\n accountMenu?: ReactNode;\n className?: string;\n extra?: ReactNode;\n layout?: HeadbarLayout;\n brand?: ReactNode;\n logo?: AppHeaderLogo;\n navigation?: ReactNode;\n navItems?: LayoutNavItem[];\n onNavigate?: (itemId: string) => void;\n}\n\nexport function NavigationHeadbar({\n activeItemId,\n activeRootId,\n actions,\n accountMenu,\n className,\n extra,\n layout,\n brand,\n logo,\n navigation,\n navItems = [],\n onNavigate,\n}: NavigationHeadbarProps) {\n const heightPx = clampHeadbarHeight(layout?.heightPx);\n const layoutMode = layout?.layoutMode ?? \"boxed\";\n const menuRadius = layout?.menuRadius ?? \"default\";\n const surface = layout?.surface ?? \"card\";\n const logoHeightPx = getHeadbarLogoSizePx(heightPx);\n const frameStyle = getHeadbarFrameStyle(layoutMode, heightPx, surface);\n const showBrandTitle = Boolean(layout?.brandTitle);\n\n return (\n <header\n className={cn(\n getHeadbarFrameClass(layoutMode, layout?.navPosition),\n className,\n )}\n data-navigation-headbar=\"\"\n data-navigation-headbar-surface={surface}\n style={frameStyle}\n >\n <div className=\"flex min-w-0 items-center justify-start\">\n {brand ??\n (logo ? (\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n icon={\n <div\n className={cn(\n \"flex items-center justify-center overflow-hidden rounded-lg\",\n logo.url\n ? \"w-auto max-w-[min(22rem,30vw)] bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n style={\n logo.url\n ? { height: logoHeightPx }\n : { width: logoHeightPx, height: logoHeightPx }\n }\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"block h-full w-auto object-contain\"\n />\n ) : (\n <span className=\"text-base font-bold\">\n {logo.title.charAt(0)}\n </span>\n )}\n </div>\n }\n label={\n showBrandTitle ? (\n <span className=\"truncate whitespace-nowrap text-base font-medium text-[hsl(var(--foreground))]\">\n {layout?.brandTitle}\n </span>\n ) : null\n }\n ariaLabel={logo.title}\n title={logo.title}\n className=\"h-auto min-w-0 justify-start border-transparent bg-transparent p-0 shadow-none hover:bg-transparent\"\n classNames={\n logo.url ? { icon: \"!h-auto !w-auto shrink-0\" } : undefined\n }\n onClick={logo.onClick}\n />\n ) : null)}\n </div>\n\n <div\n className={cn(\n \"flex min-w-0 items-center\",\n getHeadbarNavClass(layout?.navPosition),\n )}\n >\n <div className=\"no-scrollbar flex max-w-full min-w-0 items-center overflow-x-auto overscroll-x-contain\">\n {navigation ?? (\n <NavigationHeadbarMenu\n activeItemId={activeItemId}\n activeRootId={activeRootId}\n items={navItems}\n menuRadius={menuRadius}\n onNavigate={onNavigate}\n />\n )}\n </div>\n </div>\n\n <div className=\"flex min-w-0 items-center justify-end gap-3\">\n {actions}\n {extra}\n {accountMenu}\n </div>\n </header>\n );\n}\n\nexport function NavigationLayout({\n activeItemId,\n activeRootId,\n allowModeSwitch = false,\n accountMenu,\n children,\n className,\n collapsedSidebarAccountMenu,\n collapsedSidebarWidth = NAVIGATION_LAYOUT_SIDEBAR_COLLAPSED_WIDTH,\n defaultMode = \"headbar\",\n defaultSidebarCollapsed = false,\n expandedSidebarWidth = NAVIGATION_LAYOUT_SIDEBAR_EXPANDED_WIDTH,\n expandSidebarLabel = \"Expand sidebar\",\n flush = false,\n headbarActions,\n headbarLayout,\n logo,\n mode,\n navItems,\n onModeChange,\n onNavigate,\n onSidebarCollapsedChange,\n renderHeadbarExtra,\n collapseSidebarLabel = \"Collapse sidebar\",\n sidebarCollapsed: controlledSidebarCollapsed,\n sidebarAccountMenu,\n sidebarFooter,\n sidebarHeader,\n switchToHeadbarLabel = \"Switch to headbar\",\n switchToSidebarLabel = \"Switch to sidebar\",\n}: NavigationLayoutProps) {\n const [uncontrolledMode, setUncontrolledMode] =\n useState<NavigationMode>(defaultMode);\n const [uncontrolledSidebarCollapsed, setUncontrolledSidebarCollapsed] =\n useState(defaultSidebarCollapsed);\n const [revealRequest, setRevealRequest] = useState<{\n id: string;\n nonce: number;\n } | null>(null);\n const isModeControlled = mode !== undefined;\n const isSidebarCollapsedControlled = controlledSidebarCollapsed !== undefined;\n const navigationMode = isModeControlled ? mode : uncontrolledMode;\n const sidebarCollapsed = isSidebarCollapsedControlled\n ? controlledSidebarCollapsed\n : uncontrolledSidebarCollapsed;\n const isHeadbarMode = navigationMode === \"headbar\";\n const sidebarWidth = sidebarCollapsed\n ? collapsedSidebarWidth\n : expandedSidebarWidth;\n\n useEffect(() => {\n if (!isModeControlled) {\n setUncontrolledMode(defaultMode);\n }\n }, [defaultMode, isModeControlled]);\n\n useEffect(() => {\n if (!isSidebarCollapsedControlled) {\n setUncontrolledSidebarCollapsed(defaultSidebarCollapsed);\n }\n }, [defaultSidebarCollapsed, isSidebarCollapsedControlled]);\n\n const setNavigationMode = (nextMode: NavigationMode) => {\n if (!isModeControlled) {\n setUncontrolledMode(nextMode);\n }\n onModeChange?.(nextMode);\n };\n\n const setCollapsed = (collapsed: boolean) => {\n if (!isSidebarCollapsedControlled) {\n setUncontrolledSidebarCollapsed(collapsed);\n }\n onSidebarCollapsedChange?.(collapsed);\n };\n\n const navigationActions: NavigationLayoutAction[] = [];\n if (allowModeSwitch) {\n navigationActions.push({\n id: \"toggle-headbar\",\n label: switchToHeadbarLabel,\n onClick: () => setNavigationMode(\"headbar\"),\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-[18px] w-[18px] rotate-180\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n </svg>\n ),\n });\n }\n navigationActions.push({\n id: \"toggle-sidebar\",\n label: sidebarCollapsed ? expandSidebarLabel : collapseSidebarLabel,\n onClick: () => setCollapsed(!sidebarCollapsed),\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-[18px] w-[18px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d={sidebarCollapsed ? \"m14 9 3 3-3 3\" : \"m16 15-3-3 3-3\"} />\n </svg>\n ),\n });\n\n const sidebar = isHeadbarMode ? null : (\n <div\n className={cn(\n \"relative h-full min-h-0 shrink-0 transition-[width] duration-260\",\n sidebarCollapsed ? \"z-20 overflow-visible\" : \"z-10 overflow-hidden\",\n )}\n style={{\n width: sidebarWidth,\n transitionTimingFunction: NAVIGATION_LAYOUT_TRANSITION_TIMING,\n }}\n >\n <Sidebar\n accountMenu={sidebarAccountMenu ?? accountMenu}\n activeItemId={activeItemId}\n actions={navigationActions}\n collapsed={sidebarCollapsed}\n collapsedAccountMenu={collapsedSidebarAccountMenu ?? accountMenu}\n footer={sidebarFooter}\n header={sidebarHeader}\n items={navItems}\n logo={logo}\n onCollapsedChange={setCollapsed}\n onNavigate={onNavigate}\n onRevealRoot={(rootId) =>\n setRevealRequest((prev) => ({\n id: rootId,\n nonce: (prev?.nonce ?? 0) + 1,\n }))\n }\n revealRequest={revealRequest}\n title={headbarLayout?.brandTitle}\n />\n </div>\n );\n\n const header = isHeadbarMode ? (\n <NavigationHeadbar\n activeItemId={activeItemId}\n activeRootId={\n activeRootId ?? findNavigationRootId(navItems, activeItemId)\n }\n actions={\n allowModeSwitch ? (\n <>\n {headbarActions}\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n icon={\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d=\"m14 9 3 3-3 3\" />\n </svg>\n }\n label={\n <span className=\"truncate whitespace-nowrap\">\n {switchToSidebarLabel}\n </span>\n }\n onClick={() => setNavigationMode(\"sidebar\")}\n className={cn(\n \"h-auto min-w-0 shrink px-3 py-2 text-sm font-medium text-[hsl(var(--muted-foreground))] shadow-none hover:border-[hsl(var(--input))]/70 hover:bg-[hsl(var(--muted))]/60 hover:text-[hsl(var(--foreground))]\",\n getHeadbarMenuRadiusClass(headbarLayout?.menuRadius),\n )}\n />\n </>\n ) : (\n headbarActions\n )\n }\n accountMenu={accountMenu}\n extra={renderHeadbarExtra}\n layout={headbarLayout}\n logo={logo}\n navItems={navItems}\n onNavigate={onNavigate}\n />\n ) : null;\n\n return (\n <AppLayout\n header={header}\n sidebar={sidebar}\n flush={flush}\n className={className}\n >\n {children}\n </AppLayout>\n );\n}\n","import type {\n AgentSessionCapabilities,\n AgentSessionEvent,\n AgentSessionViewModel,\n} from '@inf-monkeys-tech/monkeys';\n\ntype SessionEventType = AgentSessionEvent['eventType'];\nexport type AgentWorkbenchEventOf<Type extends SessionEventType> = Extract<\n AgentSessionEvent,\n { eventType: Type }\n>;\n\nconst EVENT_CAPABILITIES = {\n reasoning: 'reasoning',\n plan: 'plan',\n task: 'tasks',\n tool: 'tools',\n approval: 'approval',\n artifact: 'artifacts',\n usage: 'usage',\n} as const satisfies Partial<\n Record<SessionEventType, keyof AgentSessionCapabilities>\n>;\n\nexport interface AgentWorkbenchActivityModel {\n mode: AgentSessionViewModel['snapshot']['mode'];\n status: AgentSessionViewModel['status'];\n reasoning: AgentWorkbenchEventOf<'reasoning'>[];\n plans: AgentWorkbenchEventOf<'plan'>[];\n tasks: AgentWorkbenchEventOf<'task'>[];\n tools: AgentWorkbenchEventOf<'tool'>[];\n approvals: AgentWorkbenchEventOf<'approval'>[];\n artifacts: AgentWorkbenchEventOf<'artifact'>[];\n usage?: AgentWorkbenchEventOf<'usage'>;\n run?: AgentWorkbenchEventOf<'status'>;\n}\n\nfunction isVisible(\n event: AgentSessionEvent,\n capabilities: AgentSessionCapabilities,\n): boolean {\n const capability = EVENT_CAPABILITIES[\n event.eventType as keyof typeof EVENT_CAPABILITIES\n ];\n return capability ? capabilities[capability] === true : true;\n}\n\nfunction latestBy<Type extends SessionEventType>(\n events: AgentSessionEvent[],\n eventType: Type,\n key: (event: AgentWorkbenchEventOf<Type>) => string,\n): AgentWorkbenchEventOf<Type>[] {\n const latest = new Map<string, AgentWorkbenchEventOf<Type>>();\n for (const event of events) {\n if (event.eventType !== eventType) continue;\n const typedEvent = event as AgentWorkbenchEventOf<Type>;\n latest.set(key(typedEvent), typedEvent);\n }\n return [...latest.values()].sort(\n (left, right) => left.sequence - right.sequence,\n );\n}\n\nexport function createAgentWorkbenchActivityModel(\n viewModel: AgentSessionViewModel,\n): AgentWorkbenchActivityModel {\n const visibleEvents = viewModel.events.filter((event) =>\n isVisible(event, viewModel.snapshot.capabilities),\n );\n\n return {\n mode: viewModel.snapshot.mode,\n status: viewModel.status,\n reasoning: latestBy(\n visibleEvents,\n 'reasoning',\n (event) => event.payload.reasoningId,\n ),\n plans: latestBy(\n visibleEvents,\n 'plan',\n (event) => event.payload.planId,\n ),\n tasks: latestBy(\n visibleEvents,\n 'task',\n (event) => event.payload.taskId,\n ),\n tools: latestBy(\n visibleEvents,\n 'tool',\n (event) => event.payload.toolCallId,\n ),\n approvals: latestBy(\n visibleEvents,\n 'approval',\n (event) => event.payload.approvalId,\n ),\n artifacts: latestBy(\n visibleEvents,\n 'artifact',\n (event) => event.payload.artifactId,\n ),\n usage: [...visibleEvents]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'usage'> =>\n event.eventType === 'usage',\n ),\n run: [...visibleEvents]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'status'> =>\n event.eventType === 'status',\n ),\n };\n}\n","import { CheckCircle2, ChevronDown, Clock3, Loader2, TerminalSquare, XCircle } from 'lucide-react';\nimport { useState } from 'react';\n\nimport { useMonkeysLocaleMessages } from '../../provider';\nimport { cn } from '../layout';\nimport type { AgentWorkbenchEventOf } from './activity-model';\n\nexport interface AgentWorkbenchToolClassNames {\n root?: string;\n trigger?: string;\n content?: string;\n input?: string;\n output?: string;\n}\n\nexport interface AgentWorkbenchToolProps {\n event: AgentWorkbenchEventOf<'tool'>;\n expanded?: boolean;\n defaultExpanded?: boolean;\n className?: string;\n classNames?: AgentWorkbenchToolClassNames;\n onExpandedChange?: (expanded: boolean) => void;\n}\n\nfunction JsonValue({ value, className }: { value: unknown; className?: string }) {\n if (value === undefined) return null;\n const content = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return (\n <pre\n className={cn(\n 'max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted p-3 font-mono text-xs text-foreground',\n className,\n )}\n >\n {content}\n </pre>\n );\n}\n\nfunction ToolStatus({ status }: { status: AgentWorkbenchEventOf<'tool'>['payload']['status'] }) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.tool.status;\n const commonClassName = 'size-3.5 shrink-0';\n\n if (status === 'pending') {\n return <Clock3 className={commonClassName} aria-hidden=\"true\" />;\n }\n if (status === 'running') {\n return <Loader2 className={cn(commonClassName, 'animate-spin')} aria-hidden=\"true\" />;\n }\n if (status === 'completed') {\n return <CheckCircle2 className={cn(commonClassName, 'text-primary')} aria-hidden=\"true\" />;\n }\n return <XCircle className={cn(commonClassName, 'text-destructive-text')} aria-hidden=\"true\" />;\n}\n\nexport function AgentWorkbenchTool({\n event,\n expanded,\n defaultExpanded = event.payload.status === 'failed',\n className,\n classNames,\n onExpandedChange,\n}: AgentWorkbenchToolProps) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.tool;\n const [uncontrolledExpanded, setUncontrolledExpanded] = useState(defaultExpanded);\n const isControlled = expanded !== undefined;\n const isExpanded = expanded ?? uncontrolledExpanded;\n const status = event.payload.status;\n const setExpanded = (nextExpanded: boolean) => {\n if (!isControlled) setUncontrolledExpanded(nextExpanded);\n onExpandedChange?.(nextExpanded);\n };\n\n return (\n <details\n open={isExpanded}\n className={cn(\n 'group rounded-lg border border-border bg-card text-card-foreground',\n classNames?.root,\n className,\n )}\n data-tool-status={status}\n >\n <summary\n className={cn(\n 'flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden',\n classNames?.trigger,\n )}\n onClick={(event) => {\n event.preventDefault();\n setExpanded(!isExpanded);\n }}\n >\n <TerminalSquare className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate font-medium\">{event.payload.toolName}</span>\n <span className=\"inline-flex shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground\">\n <ToolStatus status={status} />\n {messages.status[status]}\n </span>\n <ChevronDown\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div className={cn('space-y-3 border-t border-border px-3 py-3 text-sm', classNames?.content)}>\n {event.payload.input !== undefined ? (\n <div className=\"space-y-1.5\">\n <div className=\"text-xs font-medium text-muted-foreground\">{messages.input}</div>\n <JsonValue value={event.payload.input} className={classNames?.input} />\n </div>\n ) : null}\n {event.payload.output !== undefined ? (\n <div className=\"space-y-1.5\">\n <div className=\"text-xs font-medium text-muted-foreground\">{messages.output}</div>\n <JsonValue value={event.payload.output} className={classNames?.output} />\n </div>\n ) : null}\n {event.payload.error ? (\n <p className=\"text-sm text-destructive-text\" role=\"alert\">\n {event.payload.error}\n </p>\n ) : null}\n </div>\n </details>\n );\n}\n","import type { AgentSessionViewModel } from '@inf-monkeys-tech/monkeys';\nimport {\n Check,\n CheckCircle2,\n ChevronDown,\n Circle,\n CircleStop,\n Clock3,\n Download,\n FileOutput,\n Loader2,\n X,\n XCircle,\n} from 'lucide-react';\nimport type { ComponentType, ReactNode } from 'react';\n\nimport { useMonkeysLocaleMessages } from '../../provider';\nimport { cn } from '../layout';\nimport {\n createAgentWorkbenchActivityModel,\n type AgentWorkbenchEventOf,\n} from './activity-model';\nimport { AgentWorkbenchTool } from './AgentWorkbenchTool';\n\nexport interface AgentWorkbenchApprovalIntent {\n approvalId: string;\n approved: boolean;\n}\n\nexport interface AgentWorkbenchArtifactIntent {\n artifactId: string;\n name: string;\n url: string;\n}\n\nexport interface AgentWorkbenchActivityClassNames {\n root?: string;\n item?: string;\n trigger?: string;\n content?: string;\n approval?: string;\n artifact?: string;\n usage?: string;\n}\n\nexport interface AgentWorkbenchActivityProps {\n viewModel?: AgentSessionViewModel;\n hiddenToolCallIds?: ReadonlySet<string>;\n hideReasoning?: boolean;\n hideStoppedRun?: boolean;\n className?: string;\n classNames?: AgentWorkbenchActivityClassNames;\n onApprovalDecision?: (intent: AgentWorkbenchApprovalIntent) => void;\n onArtifactOpen?: (intent: AgentWorkbenchArtifactIntent) => void;\n}\n\ninterface ActivityDetailsProps {\n icon: ComponentType<{ className?: string }>;\n title: ReactNode;\n open?: boolean;\n streaming?: boolean;\n className?: string;\n triggerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n}\n\nfunction ActivityDetails({\n icon: Icon,\n title,\n open,\n streaming,\n className,\n triggerClassName,\n contentClassName,\n children,\n}: ActivityDetailsProps) {\n return (\n <details\n className={cn(\n 'group rounded-lg border border-border bg-card text-card-foreground',\n className,\n )}\n open={open}\n >\n <summary\n className={cn(\n 'flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 text-sm font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden',\n triggerClassName,\n )}\n >\n {streaming ? (\n <Loader2 className=\"size-4 shrink-0 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <Icon className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n )}\n <span className=\"min-w-0 flex-1 truncate\">{title}</span>\n <ChevronDown\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div\n className={cn(\n 'border-t border-border px-3 py-3 text-sm',\n contentClassName,\n )}\n >\n {children}\n </div>\n </details>\n );\n}\n\nfunction StatusIcon({ status }: { status: string }) {\n if (status === 'completed' || status === 'passed') {\n return <CheckCircle2 className=\"size-4 text-primary\" aria-hidden=\"true\" />;\n }\n if (status === 'failed') {\n return <XCircle className=\"size-4 text-destructive-text\" aria-hidden=\"true\" />;\n }\n if (status === 'running') {\n return <Clock3 className=\"size-4 animate-pulse\" aria-hidden=\"true\" />;\n }\n return <Circle className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />;\n}\n\nfunction JsonValue({ value }: { value: unknown }) {\n if (value === undefined) return null;\n const content =\n typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return (\n <pre className=\"max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted p-3 font-mono text-xs text-foreground\">\n {content}\n </pre>\n );\n}\n\nfunction formatDuration(durationMs: number): string {\n if (durationMs < 1_000) return '<1s';\n const totalSeconds = Math.floor(durationMs / 1_000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;\n}\n\nfunction RunStatus({ event }: { event: AgentWorkbenchEventOf<'status'> }) {\n const messages = useMonkeysLocaleMessages().agentWorkbench;\n const status = event.payload.status;\n if (status !== 'stopping' && status !== 'stopped') return null;\n\n return (\n <div\n className=\"flex items-center gap-2 text-sm text-muted-foreground\"\n role=\"status\"\n >\n {status === 'stopping' ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <CircleStop className=\"size-4\" aria-hidden=\"true\" />\n )}\n <span>\n {status === 'stopping'\n ? messages.run.stopping\n : messages.run.stoppedAfter({\n duration: formatDuration(event.payload.durationMs ?? 0),\n })}\n </span>\n </div>\n );\n}\n\nexport function AgentWorkbenchActivity({\n viewModel,\n hiddenToolCallIds,\n hideReasoning = false,\n hideStoppedRun = false,\n className,\n classNames,\n onApprovalDecision,\n onArtifactOpen,\n}: AgentWorkbenchActivityProps) {\n const messages = useMonkeysLocaleMessages().agentWorkbench;\n if (!viewModel) return null;\n\n const activity = createAgentWorkbenchActivityModel(viewModel);\n const reasoning = hideReasoning ? [] : activity.reasoning;\n const tools = activity.tools.filter(\n (event) => !hiddenToolCallIds?.has(event.payload.toolCallId),\n );\n const approvals = activity.approvals.filter(\n (event) =>\n !event.payload.toolCallId ||\n !hiddenToolCallIds?.has(event.payload.toolCallId),\n );\n const usage = activity.usage?.payload;\n const contextWindow =\n typeof usage?.contextWindow === 'number' && usage.contextWindow > 0\n ? usage.contextWindow\n : undefined;\n const showRun =\n activity.run?.payload.status === 'stopping' ||\n (activity.run?.payload.status === 'stopped' && !hideStoppedRun);\n const hasActivity =\n reasoning.length > 0 ||\n activity.plans.length > 0 ||\n activity.tasks.length > 0 ||\n tools.length > 0 ||\n approvals.length > 0 ||\n activity.artifacts.length > 0 ||\n showRun ||\n contextWindow !== undefined;\n if (!hasActivity) return null;\n\n return (\n <section\n className={cn('space-y-3', classNames?.root, className)}\n aria-label={messages.label}\n data-agent-workbench-mode={activity.mode}\n data-agent-workbench-status={activity.status}\n >\n {reasoning.map((event) => (\n <ActivityDetails\n key={event.payload.reasoningId}\n icon={Circle}\n title={messages.reasoning}\n open={event.payload.status === 'streaming'}\n streaming={event.payload.status === 'streaming'}\n className={classNames?.item}\n triggerClassName={classNames?.trigger}\n contentClassName={classNames?.content}\n >\n <div className=\"whitespace-pre-wrap text-muted-foreground\">\n {event.payload.text}\n </div>\n </ActivityDetails>\n ))}\n\n {activity.plans.map((event) => (\n <ActivityDetails\n key={event.payload.planId}\n icon={Circle}\n title={event.payload.title || messages.plan}\n open={event.payload.status === 'running'}\n streaming={event.payload.status === 'running'}\n className={classNames?.item}\n triggerClassName={classNames?.trigger}\n contentClassName={classNames?.content}\n >\n <ol className=\"space-y-2\">\n {event.payload.steps.map((step) => (\n <li key={step.id} className=\"flex items-center gap-2\">\n <StatusIcon status={step.status} />\n <span>{step.title}</span>\n </li>\n ))}\n </ol>\n </ActivityDetails>\n ))}\n\n {activity.tasks.map((event) => (\n <ActivityDetails\n key={event.payload.taskId}\n icon={Circle}\n title={event.payload.title}\n open={event.payload.status === 'running'}\n streaming={event.payload.status === 'running'}\n className={classNames?.item}\n triggerClassName={classNames?.trigger}\n contentClassName={classNames?.content}\n >\n <div className=\"flex items-start gap-2\">\n <StatusIcon status={event.payload.status} />\n <span className=\"whitespace-pre-wrap text-muted-foreground\">\n {event.payload.detail || messages.taskNoDetail}\n </span>\n </div>\n </ActivityDetails>\n ))}\n\n {tools.map((event) => (\n <AgentWorkbenchTool\n key={event.payload.toolCallId}\n event={event}\n defaultExpanded={event.payload.status === 'failed'}\n classNames={{\n root: classNames?.item,\n trigger: classNames?.trigger,\n content: classNames?.content,\n }}\n />\n ))}\n\n {approvals.map((event) => {\n const requested = event.payload.status === 'requested';\n const approved = event.payload.status === 'approved';\n return (\n <article\n key={event.payload.approvalId}\n className={cn(\n 'rounded-lg border border-border bg-card p-3 text-card-foreground',\n classNames?.approval,\n )}\n >\n <div className=\"flex items-start gap-3\">\n {requested ? (\n <Clock3 className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n ) : approved ? (\n <Check className=\"mt-0.5 size-4 shrink-0 text-primary\" aria-hidden=\"true\" />\n ) : (\n <X className=\"mt-0.5 size-4 shrink-0 text-destructive-text\" aria-hidden=\"true\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"text-sm font-medium\">{event.payload.title}</h3>\n {event.payload.description ? (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {event.payload.description}\n </p>\n ) : null}\n {event.payload.requestedAction !== undefined ? (\n <div className=\"mt-3\">\n <JsonValue value={event.payload.requestedAction} />\n </div>\n ) : null}\n {requested ? (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n className=\"rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground outline-none hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={!onApprovalDecision}\n onClick={() =>\n onApprovalDecision?.({\n approvalId: event.payload.approvalId,\n approved: true,\n })\n }\n >\n {messages.approval.approve}\n </button>\n <button\n type=\"button\"\n className=\"rounded-md border border-border bg-background px-3 py-1.5 text-sm font-medium text-foreground outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={!onApprovalDecision}\n onClick={() =>\n onApprovalDecision?.({\n approvalId: event.payload.approvalId,\n approved: false,\n })\n }\n >\n {messages.approval.reject}\n </button>\n </div>\n ) : (\n <p className=\"mt-2 text-xs text-muted-foreground\">\n {approved\n ? messages.approval.approved\n : messages.approval.rejected}\n </p>\n )}\n </div>\n </div>\n </article>\n );\n })}\n\n {activity.artifacts.map((event) => {\n const canOpen = Boolean(event.payload.url && onArtifactOpen);\n return (\n <article\n key={event.payload.artifactId}\n className={cn(\n 'flex items-center gap-3 rounded-lg border border-border bg-card p-3 text-card-foreground',\n classNames?.artifact,\n )}\n >\n <FileOutput className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium\">\n {event.payload.name}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {messages.artifact[event.payload.status]}\n </div>\n </div>\n {event.payload.url ? (\n <button\n type=\"button\"\n className=\"rounded-md p-2 text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={messages.artifact.open({\n name: event.payload.name,\n })}\n disabled={!canOpen}\n onClick={() => {\n if (!event.payload.url) return;\n onArtifactOpen?.({\n artifactId: event.payload.artifactId,\n name: event.payload.name,\n url: event.payload.url,\n });\n }}\n >\n <Download className=\"size-4\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </article>\n );\n })}\n\n {showRun && activity.run ? <RunStatus event={activity.run} /> : null}\n\n {usage && contextWindow !== undefined ? (\n <div\n className={cn('flex justify-end', classNames?.usage)}\n aria-label={messages.usage.label}\n >\n <span className=\"rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-muted-foreground\">\n {messages.usage.context({\n used: usage.contextTokens ?? usage.totalTokens ?? 0,\n total: contextWindow,\n })}\n </span>\n </div>\n ) : null}\n </section>\n );\n}\n","import type {\n AgentSessionCapabilities,\n AgentSessionEvent,\n AgentSessionViewModel,\n} from '@inf-monkeys-tech/monkeys';\n\nimport type { AgentWorkbenchEventOf } from './activity-model';\n\nconst WORKSPACE_CAPABILITIES = {\n diff: 'diff',\n 'workspace-file': 'workspaceFiles',\n terminal: 'terminal',\n 'test-result': 'testResults',\n artifact: 'artifacts',\n} as const satisfies Partial<\n Record<AgentSessionEvent['eventType'], keyof AgentSessionCapabilities>\n>;\n\nexport interface AgentWorkbenchTerminalModel {\n terminalId: string;\n stdin: string;\n stdout: string;\n stderr: string;\n status: string;\n exitCode?: number;\n sequence: number;\n}\n\nexport interface AgentWorkbenchDetailsModel {\n mode: AgentSessionViewModel['snapshot']['mode'];\n status: AgentSessionViewModel['status'];\n sessionId: string;\n resumable: boolean;\n summary?: AgentWorkbenchEventOf<'summary'>;\n error?: AgentWorkbenchEventOf<'error'>;\n run?: AgentWorkbenchEventOf<'status'>;\n workspace: {\n diffs: AgentWorkbenchEventOf<'diff'>[];\n files: AgentWorkbenchEventOf<'workspace-file'>[];\n terminals: AgentWorkbenchTerminalModel[];\n tests: AgentWorkbenchEventOf<'test-result'>[];\n artifacts: AgentWorkbenchEventOf<'artifact'>[];\n };\n}\n\nfunction latestBy<Type extends AgentSessionEvent['eventType']>(\n events: AgentSessionEvent[],\n eventType: Type,\n key: (event: AgentWorkbenchEventOf<Type>) => string,\n): AgentWorkbenchEventOf<Type>[] {\n const latest = new Map<string, AgentWorkbenchEventOf<Type>>();\n for (const event of events) {\n if (event.eventType !== eventType) continue;\n const typedEvent = event as AgentWorkbenchEventOf<Type>;\n latest.set(key(typedEvent), typedEvent);\n }\n return [...latest.values()].sort(\n (left, right) => left.sequence - right.sequence,\n );\n}\n\nfunction projectTerminals(\n events: AgentWorkbenchEventOf<'terminal'>[],\n): AgentWorkbenchTerminalModel[] {\n const terminals = new Map<string, AgentWorkbenchTerminalModel>();\n for (const event of events) {\n const current = terminals.get(event.payload.terminalId) ?? {\n terminalId: event.payload.terminalId,\n stdin: '',\n stdout: '',\n stderr: '',\n status: '',\n sequence: event.sequence,\n };\n const stream = event.payload.stream;\n terminals.set(event.payload.terminalId, {\n ...current,\n ...(stream === 'status'\n ? { status: event.payload.chunk }\n : { [stream]: `${current[stream]}${event.payload.chunk}` }),\n ...(event.payload.exitCode === undefined\n ? {}\n : { exitCode: event.payload.exitCode }),\n sequence: event.sequence,\n });\n }\n return [...terminals.values()].sort(\n (left, right) => left.sequence - right.sequence,\n );\n}\n\nexport function createAgentWorkbenchDetailsModel(\n viewModel: AgentSessionViewModel,\n): AgentWorkbenchDetailsModel {\n const capabilities = viewModel.snapshot.capabilities;\n const workspaceEvents = viewModel.events.filter((event) => {\n const capability = WORKSPACE_CAPABILITIES[\n event.eventType as keyof typeof WORKSPACE_CAPABILITIES\n ];\n return capability ? capabilities[capability] === true : false;\n });\n const run = [...viewModel.events]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'status'> =>\n event.eventType === 'status',\n );\n const currentRunId = run?.runId;\n const summary = [...viewModel.events]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'summary'> =>\n event.eventType === 'summary' &&\n capabilities.summary === true &&\n (!currentRunId || event.runId === currentRunId),\n );\n\n return {\n mode: viewModel.snapshot.mode,\n status: viewModel.status,\n sessionId: viewModel.sessionId,\n resumable: capabilities.resume === true && viewModel.resumable,\n summary,\n error: [...viewModel.events]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'error'> =>\n event.eventType === 'error',\n ),\n run,\n workspace: {\n diffs: latestBy(workspaceEvents, 'diff', (event) => event.payload.path),\n files: latestBy(\n workspaceEvents,\n 'workspace-file',\n (event) => event.payload.path,\n ),\n terminals: projectTerminals(\n workspaceEvents.filter(\n (event): event is AgentWorkbenchEventOf<'terminal'> =>\n event.eventType === 'terminal',\n ),\n ),\n tests: latestBy(\n workspaceEvents,\n 'test-result',\n (event) => event.payload.testId,\n ),\n artifacts: latestBy(\n workspaceEvents,\n 'artifact',\n (event) => event.payload.artifactId,\n ),\n },\n };\n}\n","import type { AgentSessionViewModel } from '@inf-monkeys-tech/monkeys';\nimport {\n AlertCircle,\n CheckCircle2,\n ChevronDown,\n Circle,\n Clock3,\n Copy,\n FileCode2,\n FileOutput,\n Files,\n RefreshCw,\n RotateCcw,\n TerminalSquare,\n TestTube2,\n X,\n XCircle,\n} from 'lucide-react';\nimport type { ComponentType, KeyboardEvent, ReactNode } from 'react';\n\nimport { useMonkeysLocale, useMonkeysLocaleMessages } from '../../provider';\nimport { cn } from '../layout';\nimport {\n createAgentWorkbenchDetailsModel,\n type AgentWorkbenchDetailsModel,\n} from './details-model';\n\nexport type AgentWorkbenchDetailsTab = 'summary' | 'workspace';\nexport type AgentWorkbenchDetailsState =\n | 'ready'\n | 'loading'\n | 'empty'\n | 'error';\n\nexport type AgentWorkbenchDetailsIntent =\n | { type: 'close' }\n | { type: 'copy-summary'; summaryId: string; text: string }\n | { type: 'retry'; eventId: string }\n | { type: 'retry-summary'; eventId: string }\n | { type: 'resume'; sessionId: string };\n\nexport interface AgentWorkbenchTaskDetailsClassNames {\n root?: string;\n header?: string;\n tabs?: string;\n body?: string;\n section?: string;\n code?: string;\n}\n\nexport interface AgentWorkbenchTaskDetailsProps {\n viewModel?: AgentSessionViewModel;\n state?: AgentWorkbenchDetailsState;\n activeTab?: AgentWorkbenchDetailsTab;\n className?: string;\n classNames?: AgentWorkbenchTaskDetailsClassNames;\n onActiveTabChange?: (tab: AgentWorkbenchDetailsTab) => void;\n onIntent?: (intent: AgentWorkbenchDetailsIntent) => void;\n}\n\nfunction formatDuration(durationMs: number | undefined): string {\n if (durationMs === undefined) return '-';\n const seconds = Math.max(0, Math.round(durationMs / 1_000));\n if (seconds < 60) return `${seconds}s`;\n return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;\n}\n\nfunction formatDate(value: string | undefined, locale: string): string {\n if (!value) return '-';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return '-';\n return new Intl.DateTimeFormat(locale, {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n\nfunction Count({ value }: { value: number }) {\n return (\n <span className=\"rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-semibold text-muted-foreground\">\n {value}\n </span>\n );\n}\n\nfunction DetailsSection({\n title,\n count,\n icon: Icon,\n className,\n children,\n}: {\n title: string;\n count: number;\n icon: ComponentType<{ className?: string }>;\n className?: string;\n children: ReactNode;\n}) {\n if (count === 0) return null;\n return (\n <details\n className={cn(\n 'group rounded-lg border border-border bg-card text-card-foreground',\n className,\n )}\n open\n >\n <summary className=\"flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 text-sm font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden\">\n <Icon className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate\">{title}</span>\n <Count value={count} />\n <ChevronDown\n className=\"size-4 text-muted-foreground transition-transform group-open:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div className=\"border-t border-border p-3\">{children}</div>\n </details>\n );\n}\n\nfunction StatusIcon({ status }: { status: string }) {\n if (status === 'completed' || status === 'passed') {\n return <CheckCircle2 className=\"size-4 text-primary\" aria-hidden=\"true\" />;\n }\n if (status === 'failed') {\n return <XCircle className=\"size-4 text-destructive-text\" aria-hidden=\"true\" />;\n }\n if (status === 'running') {\n return <Clock3 className=\"size-4 animate-pulse\" aria-hidden=\"true\" />;\n }\n return <Circle className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />;\n}\n\nfunction StateContent({ state }: { state: Exclude<AgentWorkbenchDetailsState, 'ready'> }) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details;\n const error = state === 'error';\n return (\n <div\n className=\"flex min-h-48 flex-col items-center justify-center gap-2 px-6 text-center\"\n role={error ? 'alert' : state === 'loading' ? 'status' : undefined}\n aria-busy={state === 'loading' || undefined}\n >\n {state === 'loading' ? (\n <RefreshCw className=\"size-5 animate-spin text-muted-foreground\" aria-hidden=\"true\" />\n ) : error ? (\n <AlertCircle className=\"size-5 text-destructive-text\" aria-hidden=\"true\" />\n ) : (\n <FileOutput className=\"size-5 text-muted-foreground\" aria-hidden=\"true\" />\n )}\n <div className=\"text-sm font-medium\">{messages.state[state].title}</div>\n <div className=\"text-xs text-muted-foreground\">\n {messages.state[state].description}\n </div>\n </div>\n );\n}\n\nfunction SummaryPanel({\n model,\n onIntent,\n}: {\n model: AgentWorkbenchDetailsModel;\n onIntent?: (intent: AgentWorkbenchDetailsIntent) => void;\n}) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details;\n const locale = useMonkeysLocale().locale;\n const summary = model.summary;\n const run = model.run?.payload;\n const error = model.error;\n const retryable = model.status === 'failed' && error?.payload.retryable;\n const canResume =\n model.resumable && ['stopped', 'completed', 'failed'].includes(model.status);\n\n return (\n <div className=\"space-y-3\">\n <section className=\"rounded-lg border border-border bg-muted/40 p-3\">\n <div className=\"flex items-center gap-2\">\n <StatusIcon status={model.status} />\n <span className=\"text-sm font-semibold\">\n {messages.status[model.status]}\n </span>\n </div>\n <dl className=\"mt-3 grid grid-cols-2 gap-3 text-xs\">\n <div>\n <dt className=\"text-muted-foreground\">{messages.duration}</dt>\n <dd className=\"mt-0.5 font-medium\">\n {formatDuration(run?.durationMs)}\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground\">{messages.updated}</dt>\n <dd className=\"mt-0.5 truncate font-medium\">\n {formatDate(\n run?.stoppedAt ?? run?.completedAt ?? run?.failedAt,\n locale,\n )}\n </dd>\n </div>\n </dl>\n {error ? (\n <div className=\"mt-3 rounded-md border border-destructive/30 bg-destructive/5 p-2.5 text-sm text-destructive-text\" role=\"alert\">\n {error.payload.message}\n </div>\n ) : null}\n {retryable || canResume ? (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n {retryable ? (\n <button\n type=\"button\"\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={!onIntent}\n onClick={() => onIntent?.({ type: 'retry', eventId: error.eventId })}\n >\n {messages.actions.retry}\n </button>\n ) : null}\n {canResume ? (\n <button\n type=\"button\"\n className=\"rounded-md bg-primary px-2.5 py-1.5 text-xs font-medium text-primary-foreground outline-none hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={!onIntent}\n onClick={() =>\n onIntent?.({ type: 'resume', sessionId: model.sessionId })\n }\n >\n {messages.actions.resume}\n </button>\n ) : null}\n </div>\n ) : null}\n </section>\n\n <section className=\"rounded-lg border border-border bg-card p-3 text-card-foreground\">\n <div className=\"flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">{messages.summary}</h3>\n {summary?.payload.text ? (\n <button\n type=\"button\"\n className=\"rounded-md p-1.5 text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={messages.actions.copySummary}\n disabled={!onIntent}\n onClick={() =>\n onIntent?.({\n type: 'copy-summary',\n summaryId: summary.payload.summaryId,\n text: summary.payload.text,\n })\n }\n >\n <Copy className=\"size-4\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n {summary?.payload.status === 'failed' ? (\n <div className=\"mt-3 space-y-2\">\n <p className=\"text-sm text-destructive-text\" role=\"alert\">\n {messages.summaryFailed}\n </p>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={!onIntent}\n onClick={() =>\n onIntent?.({ type: 'retry-summary', eventId: summary.eventId })\n }\n >\n <RotateCcw className=\"size-3.5\" aria-hidden=\"true\" />\n {messages.actions.retrySummary}\n </button>\n </div>\n ) : summary?.payload.text ? (\n <div className=\"mt-3 space-y-3 text-sm\">\n <p className=\"whitespace-pre-wrap text-muted-foreground\">\n {summary.payload.text}\n </p>\n {summary.payload.highlights.length > 0 ? (\n <div>\n <h4 className=\"text-xs font-medium\">{messages.highlights}</h4>\n <ul className=\"mt-1 list-disc space-y-1 pl-5 text-muted-foreground\">\n {summary.payload.highlights.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n </div>\n ) : null}\n {summary.payload.pendingItems.length > 0 ? (\n <div>\n <h4 className=\"text-xs font-medium\">{messages.pendingItems}</h4>\n <ul className=\"mt-1 list-disc space-y-1 pl-5 text-muted-foreground\">\n {summary.payload.pendingItems.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n ) : (\n <p className=\"mt-3 text-sm text-muted-foreground\">\n {messages.summaryEmpty}\n </p>\n )}\n </section>\n </div>\n );\n}\n\nfunction WorkspacePanel({\n model,\n sectionClassName,\n codeClassName,\n}: {\n model: AgentWorkbenchDetailsModel;\n sectionClassName?: string;\n codeClassName?: string;\n}) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details.workspace;\n const workspace = model.workspace;\n return (\n <div className=\"space-y-3\">\n <DetailsSection\n title={messages.diffs}\n count={workspace.diffs.length}\n icon={FileCode2}\n className={sectionClassName}\n >\n <div className=\"space-y-3\">\n {workspace.diffs.map((event) => (\n <div key={event.payload.path} className=\"min-w-0\">\n <div className=\"flex items-center justify-between gap-2 text-xs\">\n <span className=\"truncate font-medium\">{event.payload.path}</span>\n <span className=\"shrink-0 text-muted-foreground\">\n {messages.diffStatus[event.payload.status]}\n </span>\n </div>\n {event.payload.patch ? (\n <pre className={cn('mt-2 max-h-72 overflow-auto whitespace-pre-wrap rounded-md bg-muted p-3 font-mono text-xs', codeClassName)}>\n {event.payload.patch}\n </pre>\n ) : null}\n </div>\n ))}\n </div>\n </DetailsSection>\n\n <DetailsSection\n title={messages.files}\n count={workspace.files.length}\n icon={Files}\n className={sectionClassName}\n >\n <ul className=\"space-y-2 text-xs\">\n {workspace.files.map((event) => (\n <li key={event.payload.path} className=\"flex items-center gap-2\">\n <FileOutput className=\"size-3.5 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate\">{event.payload.path}</span>\n <span className=\"text-muted-foreground\">\n {messages.fileOperation[event.payload.operation]}\n </span>\n </li>\n ))}\n </ul>\n </DetailsSection>\n\n <DetailsSection\n title={messages.terminals}\n count={workspace.terminals.length}\n icon={TerminalSquare}\n className={sectionClassName}\n >\n <div className=\"space-y-3\">\n {workspace.terminals.map((terminal) => (\n <div key={terminal.terminalId}>\n <div className=\"flex justify-between gap-2 text-xs font-medium\">\n <span>{terminal.terminalId}</span>\n <span className=\"text-muted-foreground\">\n {terminal.exitCode === undefined\n ? terminal.status\n : messages.exitCode({ code: terminal.exitCode })}\n </span>\n </div>\n <pre className={cn('mt-2 max-h-72 overflow-auto whitespace-pre-wrap rounded-md bg-muted p-3 font-mono text-xs', codeClassName)}>\n {[terminal.stdin, terminal.stdout, terminal.stderr]\n .filter(Boolean)\n .join('\\n')}\n </pre>\n </div>\n ))}\n </div>\n </DetailsSection>\n\n <DetailsSection\n title={messages.tests}\n count={workspace.tests.length}\n icon={TestTube2}\n className={sectionClassName}\n >\n <ul className=\"space-y-2 text-xs\">\n {workspace.tests.map((event) => (\n <li key={event.payload.testId}>\n <div className=\"flex items-center gap-2\">\n <StatusIcon status={event.payload.status} />\n <span className=\"min-w-0 flex-1 truncate\">{event.payload.name}</span>\n {event.payload.durationMs === undefined ? null : (\n <span className=\"text-muted-foreground\">\n {formatDuration(event.payload.durationMs)}\n </span>\n )}\n </div>\n {event.payload.output ? (\n <pre className={cn('mt-2 max-h-48 overflow-auto whitespace-pre-wrap rounded-md bg-muted p-3 font-mono text-xs', codeClassName)}>\n {event.payload.output}\n </pre>\n ) : null}\n </li>\n ))}\n </ul>\n </DetailsSection>\n\n <DetailsSection\n title={messages.artifacts}\n count={workspace.artifacts.length}\n icon={FileOutput}\n className={sectionClassName}\n >\n <ul className=\"space-y-2 text-xs\">\n {workspace.artifacts.map((event) => (\n <li key={event.payload.artifactId} className=\"flex items-center gap-2\">\n <FileOutput className=\"size-3.5 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate\">{event.payload.name}</span>\n <span className=\"text-muted-foreground\">\n {event.payload.kind}\n </span>\n </li>\n ))}\n </ul>\n </DetailsSection>\n </div>\n );\n}\n\nexport function AgentWorkbenchTaskDetails({\n viewModel,\n state = 'ready',\n activeTab = 'summary',\n className,\n classNames,\n onActiveTabChange,\n onIntent,\n}: AgentWorkbenchTaskDetailsProps) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details;\n if (state !== 'ready') {\n return (\n <aside className={cn('flex h-full min-h-0 flex-col border-l border-border bg-background', classNames?.root, className)}>\n <StateContent state={state} />\n </aside>\n );\n }\n if (!viewModel) {\n return (\n <aside className={cn('flex h-full min-h-0 flex-col border-l border-border bg-background', classNames?.root, className)}>\n <StateContent state=\"empty\" />\n </aside>\n );\n }\n\n const model = createAgentWorkbenchDetailsModel(viewModel);\n const workspaceCount = Object.values(model.workspace).reduce(\n (total, items) => total + items.length,\n 0,\n );\n const workspaceAvailable = workspaceCount > 0;\n const resolvedTab = activeTab === 'workspace' && !workspaceAvailable ? 'summary' : activeTab;\n const tabs: Array<{ id: AgentWorkbenchDetailsTab; label: string; count: number }> = [\n { id: 'summary', label: messages.tabs.summary, count: model.summary ? 1 : 0 },\n ...(workspaceAvailable\n ? [{ id: 'workspace' as const, label: messages.tabs.workspace, count: workspaceCount }]\n : []),\n ];\n const tabId = (tab: AgentWorkbenchDetailsTab) =>\n `agent-workbench-details-${viewModel.sessionId}-${tab}`.replace(\n /[^a-zA-Z0-9_-]/g,\n '-',\n );\n const onTabKeyDown = (\n event: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;\n event.preventDefault();\n const nextIndex =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? tabs.length - 1\n : (index + (event.key === 'ArrowRight' ? 1 : -1) + tabs.length) %\n tabs.length;\n onActiveTabChange?.(tabs[nextIndex].id);\n };\n\n return (\n <aside\n className={cn(\n 'flex h-full min-h-0 min-w-0 flex-col border-l border-border bg-background text-foreground',\n classNames?.root,\n className,\n )}\n data-agent-workbench-mode={model.mode}\n >\n <header className={cn('flex shrink-0 items-center gap-2 border-b border-border px-4 py-3', classNames?.header)}>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"truncate text-sm font-semibold\">{messages.title}</h2>\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {messages.description}\n </p>\n </div>\n {onIntent ? (\n <button\n type=\"button\"\n className=\"rounded-md p-2 text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={messages.actions.close}\n onClick={() => onIntent({ type: 'close' })}\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </header>\n\n <div className={cn('flex shrink-0 gap-1 border-b border-border px-3 py-2', classNames?.tabs)} role=\"tablist\" aria-label={messages.tabs.label}>\n {tabs.map((tab, index) => (\n <button\n key={tab.id}\n id={tabId(tab.id)}\n type=\"button\"\n role=\"tab\"\n aria-selected={resolvedTab === tab.id}\n aria-controls={`${tabId(tab.id)}-panel`}\n tabIndex={resolvedTab === tab.id ? 0 : -1}\n className={cn(\n 'inline-flex min-w-0 flex-1 items-center justify-center gap-1 rounded-md px-2 py-1.5 text-xs font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring',\n resolvedTab === tab.id\n ? 'bg-primary/10 text-primary'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n onClick={() => onActiveTabChange?.(tab.id)}\n onKeyDown={(event) => onTabKeyDown(event, index)}\n >\n <span className=\"truncate\">{tab.label}</span>\n <Count value={tab.count} />\n </button>\n ))}\n </div>\n\n <div\n id={`${tabId(resolvedTab)}-panel`}\n role=\"tabpanel\"\n aria-labelledby={tabId(resolvedTab)}\n tabIndex={0}\n className={cn('min-h-0 flex-1 overflow-y-auto p-3 outline-none', classNames?.body)}\n >\n {resolvedTab === 'summary' ? (\n <SummaryPanel model={model} onIntent={onIntent} />\n ) : (\n <WorkspacePanel\n model={model}\n sectionClassName={classNames?.section}\n codeClassName={classNames?.code}\n />\n )}\n </div>\n </aside>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/locale/en-US.ts","../../../src/locale/resolve-locale.ts","../../../src/provider/context.ts","../../../src/components/layout/index.tsx","../../../src/components/agent-workbench/activity-model.ts","../../../src/components/agent-workbench/AgentWorkbenchTool.tsx","../../../src/components/agent-workbench/AgentWorkbenchActivity.tsx","../../../src/components/agent-workbench/details-model.ts","../../../src/components/agent-workbench/AgentWorkbenchTaskDetails.tsx"],"names":["createContext","useContext","jsx","Clock3","Loader2","CheckCircle2","XCircle","useState","jsxs","event","TerminalSquare","ChevronDown","Circle","JsonValue","CircleStop","Check","X","FileOutput","Download","latestBy","formatDuration","StatusIcon","RefreshCw","AlertCircle","Copy","RotateCcw","FileCode2","Files","TestTube2"],"mappings":"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","file":"index.js","sourcesContent":["import type { MonkeysLocale } from './types';\n\nexport const enUS = {\n locale: 'en-US',\n messages: {\n pagination: {\n navigation: 'Pagination',\n first: 'First',\n previous: 'Previous',\n next: 'Next',\n last: 'Last',\n page: ({ page, pageCount }) => `Page ${page} of ${pageCount}`,\n currentPage: ({ page, pageCount }) =>\n `Page ${page} of ${pageCount}, current page`,\n emptyResults: '0 results',\n range: ({ start, end, total }) => `${start}-${end} of ${total}`,\n },\n dialog: {\n close: 'Close dialog',\n },\n dropdownMenu: {\n actions: 'Actions',\n },\n loading: {\n spinner: 'Loading',\n },\n layout: {\n resizePanels: 'Resize panels',\n },\n steps: {\n label: 'Progress',\n current: 'Current',\n completed: 'Completed',\n error: 'Error',\n disabled: 'Disabled',\n },\n numberInput: {\n increment: 'Increase value',\n decrement: 'Decrease value',\n },\n passwordInput: {\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n },\n multiSelect: {\n placeholder: 'Select options',\n empty: 'No options',\n removeOption: ({ value }) => `Remove ${value}`,\n },\n table: {\n dragColumn: ({ columnId }) => `Drag column ${columnId}`,\n resizeColumn: ({ columnId }) => `Resize column ${columnId}`,\n sortColumn: ({ columnId }) =>\n columnId ? `Sort column ${columnId}` : 'Sort column',\n loadingRow: 'Loading table row',\n },\n toolbar: {\n theme: {\n label: 'Appearance',\n toggle: 'Toggle theme',\n auto: 'Auto',\n light: 'Light',\n dark: 'Dark',\n },\n language: {\n label: 'Language',\n switch: 'Switch language',\n },\n },\n toast: {\n errorTitle: 'Error',\n warningTitle: 'Warning',\n defaultErrorDescription: 'Something went wrong.',\n defaultWarningDescription: 'Please check and try again.',\n },\n dataExplorer: {\n viewTree: {\n actions: 'More actions',\n expand: 'Expand',\n collapse: 'Collapse',\n loading: 'Loading...',\n empty: 'No views',\n error: 'Unable to load views',\n },\n },\n workbench: {\n interactiveTable: {\n columnActions: 'Column actions',\n freezeColumn: 'Freeze to left',\n freezeEndColumn: 'Freeze to right',\n unfreezeColumn: 'Unfreeze from left',\n unfreezeEndColumn: 'Unfreeze from right',\n unfreezeAllColumns: 'Unfreeze all columns',\n resetColumnWidth: 'Reset column width',\n frozenColumnTitle: 'Frozen column',\n },\n },\n agentWorkbench: {\n label: 'Session activity',\n reasoning: 'Reasoning',\n plan: 'Plan',\n taskNoDetail: 'No additional details',\n tool: {\n input: 'Input',\n output: 'Output',\n status: {\n pending: 'Pending',\n running: 'Running',\n completed: 'Completed',\n failed: 'Error',\n denied: 'Denied',\n },\n },\n approval: {\n approve: 'Approve',\n reject: 'Reject',\n approved: 'Approved',\n rejected: 'Rejected',\n },\n artifact: {\n pending: 'Preparing',\n ready: 'Ready',\n failed: 'Failed',\n open: ({ name }) => `Open ${name}`,\n },\n run: {\n stopping: 'Stopping...',\n stoppedAfter: ({ duration }) => `You stopped after ${duration}`,\n },\n usage: {\n label: 'Context usage',\n context: ({ used, total }) => `${used} / ${total} tokens`,\n },\n details: {\n title: 'Task details',\n description: 'Summary and workspace activity',\n duration: 'Duration',\n updated: 'Updated',\n summary: 'Summary',\n summaryEmpty: 'No summary is available yet.',\n summaryFailed: 'The summary could not be generated.',\n highlights: 'Highlights',\n pendingItems: 'Pending items',\n tabs: {\n label: 'Task detail views',\n summary: 'Summary',\n workspace: 'Workspace',\n },\n status: {\n queued: 'Queued',\n running: 'Running',\n waiting_approval: 'Waiting for approval',\n stopping: 'Stopping',\n stopped: 'Stopped',\n completed: 'Completed',\n failed: 'Failed',\n },\n state: {\n loading: { title: 'Loading task details', description: 'Restoring the latest session activity.' },\n empty: { title: 'No task selected', description: 'Select a task to inspect its details.' },\n error: { title: 'Unable to load task details', description: 'Try again after the session is available.' },\n },\n actions: {\n close: 'Close task details',\n copySummary: 'Copy summary',\n retry: 'Retry',\n retrySummary: 'Retry summary',\n resume: 'Resume',\n },\n workspace: {\n diffs: 'Code changes',\n files: 'Files',\n terminals: 'Terminals',\n tests: 'Tests',\n artifacts: 'Artifacts',\n exitCode: ({ code }) => `Exit code ${code}`,\n diffStatus: { added: 'Added', modified: 'Modified', deleted: 'Deleted', renamed: 'Renamed' },\n fileOperation: { upsert: 'Updated', delete: 'Deleted' },\n },\n },\n },\n },\n} satisfies MonkeysLocale;\n","import { enUS } from './en-US';\nimport type {\n MonkeysBuiltInLocaleId,\n MonkeysLocale,\n MonkeysLocaleInput,\n MonkeysLocaleMessages,\n MonkeysLocaleMessagesOverride,\n MonkeysResolvedLocale,\n} from './types';\nimport { zhCN } from './zh-CN';\n\nconst BUILT_IN_LOCALES: Record<MonkeysBuiltInLocaleId, MonkeysLocale> = {\n 'en-US': enUS,\n 'zh-CN': zhCN,\n};\n\nfunction normalizeLocaleId(locale: unknown): string {\n if (typeof locale !== 'string' || !locale.trim()) {\n throw new TypeError('Monkeys locale must be a non-empty BCP 47 string.');\n }\n\n try {\n return Intl.getCanonicalLocales(locale)[0];\n } catch {\n throw new RangeError(\n `Monkeys locale \"${locale}\" is not a valid BCP 47 identifier.`,\n );\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction validateMessageOverride(\n value: unknown,\n schema: unknown,\n path: string,\n) {\n if (!isRecord(value) || !isRecord(schema)) {\n throw new TypeError(`${path} must be an object.`);\n }\n\n for (const [key, candidate] of Object.entries(value)) {\n if (candidate === undefined) continue;\n if (!(key in schema)) {\n throw new TypeError(`${path}.${key} is not a supported Monkeys message.`);\n }\n\n const expected = schema[key];\n const candidatePath = `${path}.${key}`;\n if (typeof expected === 'function') {\n if (typeof candidate !== 'function') {\n throw new TypeError(`${candidatePath} must be a function.`);\n }\n } else if (typeof expected === 'string') {\n if (typeof candidate !== 'string') {\n throw new TypeError(`${candidatePath} must be a string.`);\n }\n } else {\n validateMessageOverride(candidate, expected, candidatePath);\n }\n }\n}\n\nfunction assertMessagesOverride(\n value: unknown,\n path: string,\n): asserts value is MonkeysLocaleMessagesOverride {\n validateMessageOverride(value, enUS.messages, path);\n}\n\nfunction isBuiltInLocale(locale: string): locale is MonkeysBuiltInLocaleId {\n return locale === 'en-US' || locale === 'zh-CN';\n}\n\nfunction normalizeLocaleInput(input: MonkeysLocaleInput | undefined): {\n locale: string | undefined;\n messages: MonkeysLocaleMessagesOverride | undefined;\n hasExplicitLocale: boolean;\n} {\n if (input === undefined) {\n return {\n locale: undefined,\n messages: undefined,\n hasExplicitLocale: false,\n };\n }\n\n if (typeof input === 'string') {\n const locale = normalizeLocaleId(input);\n if (!isBuiltInLocale(locale)) {\n throw new RangeError(\n `Unsupported built-in Monkeys locale \"${locale}\". Provide a locale pack object for custom locales.`,\n );\n }\n return { locale, messages: undefined, hasExplicitLocale: true };\n }\n\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n throw new TypeError('Monkeys locale must be a locale id or locale pack object.');\n }\n\n const locale = normalizeLocaleId(input.locale);\n assertMessagesOverride(input.messages, 'Monkeys locale messages');\n\n return {\n locale,\n messages: input.messages,\n hasExplicitLocale: true,\n };\n}\n\nexport function mergeMonkeysLocaleMessages(\n base: MonkeysLocaleMessages,\n override?: MonkeysLocaleMessagesOverride,\n): MonkeysLocaleMessages {\n if (!override) return base;\n\n return {\n pagination: { ...base.pagination, ...override.pagination },\n dialog: { ...base.dialog, ...override.dialog },\n dropdownMenu: { ...base.dropdownMenu, ...override.dropdownMenu },\n loading: { ...base.loading, ...override.loading },\n layout: { ...base.layout, ...override.layout },\n steps: { ...base.steps, ...override.steps },\n numberInput: { ...base.numberInput, ...override.numberInput },\n passwordInput: { ...base.passwordInput, ...override.passwordInput },\n multiSelect: { ...base.multiSelect, ...override.multiSelect },\n table: { ...base.table, ...override.table },\n toolbar: {\n theme: { ...base.toolbar.theme, ...override.toolbar?.theme },\n language: { ...base.toolbar.language, ...override.toolbar?.language },\n },\n toast: { ...base.toast, ...override.toast },\n dataExplorer: {\n viewTree: {\n ...base.dataExplorer.viewTree,\n ...override.dataExplorer?.viewTree,\n },\n },\n workbench: {\n interactiveTable: {\n ...base.workbench.interactiveTable,\n ...override.workbench?.interactiveTable,\n },\n },\n agentWorkbench: {\n ...base.agentWorkbench,\n ...override.agentWorkbench,\n tool: {\n ...base.agentWorkbench.tool,\n ...override.agentWorkbench?.tool,\n status: {\n ...base.agentWorkbench.tool.status,\n ...override.agentWorkbench?.tool?.status,\n },\n },\n approval: {\n ...base.agentWorkbench.approval,\n ...override.agentWorkbench?.approval,\n },\n artifact: {\n ...base.agentWorkbench.artifact,\n ...override.agentWorkbench?.artifact,\n },\n run: {\n ...base.agentWorkbench.run,\n ...override.agentWorkbench?.run,\n },\n usage: {\n ...base.agentWorkbench.usage,\n ...override.agentWorkbench?.usage,\n },\n details: {\n ...base.agentWorkbench.details,\n ...override.agentWorkbench?.details,\n tabs: {\n ...base.agentWorkbench.details.tabs,\n ...override.agentWorkbench?.details?.tabs,\n },\n status: {\n ...base.agentWorkbench.details.status,\n ...override.agentWorkbench?.details?.status,\n },\n state: {\n loading: {\n ...base.agentWorkbench.details.state.loading,\n ...override.agentWorkbench?.details?.state?.loading,\n },\n empty: {\n ...base.agentWorkbench.details.state.empty,\n ...override.agentWorkbench?.details?.state?.empty,\n },\n error: {\n ...base.agentWorkbench.details.state.error,\n ...override.agentWorkbench?.details?.state?.error,\n },\n },\n actions: {\n ...base.agentWorkbench.details.actions,\n ...override.agentWorkbench?.details?.actions,\n },\n workspace: {\n ...base.agentWorkbench.details.workspace,\n ...override.agentWorkbench?.details?.workspace,\n diffStatus: {\n ...base.agentWorkbench.details.workspace.diffStatus,\n ...override.agentWorkbench?.details?.workspace?.diffStatus,\n },\n fileOperation: {\n ...base.agentWorkbench.details.workspace.fileOperation,\n ...override.agentWorkbench?.details?.workspace?.fileOperation,\n },\n },\n },\n },\n };\n}\n\nexport const defaultMonkeysLocale: MonkeysResolvedLocale = {\n locale: enUS.locale,\n messages: mergeMonkeysLocaleMessages(\n enUS.messages as MonkeysLocaleMessages,\n ),\n};\n\nexport function resolveMonkeysLocale(\n input?: MonkeysLocaleInput,\n override?: MonkeysLocaleMessagesOverride,\n parent?: MonkeysResolvedLocale,\n): MonkeysResolvedLocale {\n if (override !== undefined) {\n assertMessagesOverride(override, 'MonkeysProvider messages');\n }\n const normalized = normalizeLocaleInput(input);\n const locale = normalized.locale ?? parent?.locale ?? enUS.locale;\n const builtInMessages = isBuiltInLocale(locale)\n ? BUILT_IN_LOCALES[locale].messages\n : undefined;\n let messages = mergeMonkeysLocaleMessages(\n enUS.messages as MonkeysLocaleMessages,\n builtInMessages,\n );\n\n if (parent && (!normalized.hasExplicitLocale || parent.locale === locale)) {\n messages = mergeMonkeysLocaleMessages(messages, parent.messages);\n }\n\n messages = mergeMonkeysLocaleMessages(messages, normalized.messages);\n messages = mergeMonkeysLocaleMessages(messages, override);\n\n return { locale, messages };\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type Context,\n} from 'react';\n\nimport type { BaseAppearance } from '../components/base/types';\nimport type { DataExplorerAppearance } from '../components/data-explorer/types';\nimport {\n defaultMonkeysLocale,\n type MonkeysLocaleMessages,\n type MonkeysResolvedLocale,\n} from '../locale';\nimport type { CompiledThemeTokens } from '../theme-system';\n\nexport type MonkeysDirection = 'ltr' | 'rtl';\n\nexport interface MonkeysEnvironment {\n getDocument?: () => Document | null;\n getWindow?: () => Window | null;\n}\n\nexport type MonkeysPortalContainer =\n | Element\n | null\n | (() => Element | null);\n\nexport interface MonkeysPortalOptions {\n container?: MonkeysPortalContainer;\n disabled?: boolean;\n}\n\nexport interface MonkeysComponentAttributes {\n dir?: MonkeysDirection;\n 'data-monkeys-direction'?: MonkeysDirection;\n 'data-monkeys-locale'?: string;\n 'data-monkeys-theme'?: string;\n 'data-monkeys-theme-mode'?: string;\n}\n\ninterface MonkeysLocaleContextValue extends MonkeysResolvedLocale {\n provided: boolean;\n}\n\ninterface MonkeysThemeContextValue {\n provided: boolean;\n resolvedTheme?: CompiledThemeTokens;\n themeId?: string;\n baseAppearance?: BaseAppearance;\n dataExplorerAppearance?: DataExplorerAppearance;\n}\n\ninterface MonkeysDirectionContextValue {\n provided: boolean;\n direction?: MonkeysDirection;\n}\n\ninterface MonkeysEnvironmentContextValue {\n provided: boolean;\n environment: MonkeysEnvironment;\n portal: MonkeysPortalOptions;\n}\n\nconst EMPTY_ENVIRONMENT = Object.freeze({}) satisfies MonkeysEnvironment;\nconst EMPTY_PORTAL = Object.freeze({}) satisfies MonkeysPortalOptions;\n\ninterface MonkeysProviderContexts {\n locale: Context<MonkeysLocaleContextValue>;\n theme: Context<MonkeysThemeContextValue>;\n direction: Context<MonkeysDirectionContextValue>;\n environment: Context<MonkeysEnvironmentContextValue>;\n}\n\n// Every bundled public entry contains this module. Keep only the Context\n// identities in a realm-wide registry so root, provider, and component\n// subpaths interoperate in both CJS and ESM builds. Provider values remain in\n// React trees, so SSR requests are isolated. Bump the contract key only when\n// these Context value shapes become intentionally incompatible.\nconst MONKEYS_PROVIDER_CONTEXTS_KEY = Symbol.for(\n '@inf-monkeys-tech/monkeys-design/provider-context@1',\n);\n\ntype MonkeysProviderContextHost = typeof globalThis & {\n [MONKEYS_PROVIDER_CONTEXTS_KEY]?: MonkeysProviderContexts;\n};\n\nfunction createMonkeysProviderContexts(): MonkeysProviderContexts {\n return Object.freeze({\n locale: createContext<MonkeysLocaleContextValue>({\n ...defaultMonkeysLocale,\n provided: false,\n }),\n theme: createContext<MonkeysThemeContextValue>({\n provided: false,\n }),\n direction: createContext<MonkeysDirectionContextValue>({\n provided: false,\n }),\n environment: createContext<MonkeysEnvironmentContextValue>({\n provided: false,\n environment: EMPTY_ENVIRONMENT,\n portal: EMPTY_PORTAL,\n }),\n });\n}\n\nfunction getMonkeysProviderContexts(): MonkeysProviderContexts {\n const host = globalThis as MonkeysProviderContextHost;\n const existing = host[MONKEYS_PROVIDER_CONTEXTS_KEY];\n if (existing) return existing;\n\n const contexts = createMonkeysProviderContexts();\n Object.defineProperty(host, MONKEYS_PROVIDER_CONTEXTS_KEY, {\n value: contexts,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return contexts;\n}\n\nconst providerContexts = getMonkeysProviderContexts();\n\nexport const MonkeysLocaleContext = providerContexts.locale;\n\nexport const MonkeysThemeContext = providerContexts.theme;\n\nexport const MonkeysDirectionContext = providerContexts.direction;\n\nexport const MonkeysEnvironmentContext = providerContexts.environment;\n\nfunction mergeAppearance<T extends { slots?: object; styles?: object }>(\n inherited: T | undefined,\n explicit: T | undefined,\n): T | undefined {\n if (explicit === undefined) return inherited;\n if (inherited === undefined) return explicit;\n\n return {\n ...inherited,\n ...explicit,\n slots:\n inherited.slots || explicit.slots\n ? { ...inherited.slots, ...explicit.slots }\n : undefined,\n styles:\n inherited.styles || explicit.styles\n ? { ...inherited.styles, ...explicit.styles }\n : undefined,\n };\n}\n\nexport function useMonkeysLocale() {\n return useContext(MonkeysLocaleContext);\n}\n\nexport function useMonkeysLocaleMessages(): MonkeysLocaleMessages {\n return useContext(MonkeysLocaleContext).messages;\n}\n\nexport function useMonkeysResolvedTheme() {\n return useContext(MonkeysThemeContext).resolvedTheme;\n}\n\nexport function useMonkeysBaseAppearance(\n explicit?: BaseAppearance,\n): BaseAppearance | undefined {\n const inherited = useContext(MonkeysThemeContext).baseAppearance;\n return useMemo(\n () => mergeAppearance(inherited, explicit),\n [explicit, inherited],\n );\n}\n\nexport function useMonkeysDataExplorerAppearance(\n explicit?: DataExplorerAppearance,\n): DataExplorerAppearance | undefined {\n const inherited = useContext(MonkeysThemeContext).dataExplorerAppearance;\n return useMemo(\n () => mergeAppearance(inherited, explicit),\n [explicit, inherited],\n );\n}\n\nexport function useMonkeysDirection() {\n return useContext(MonkeysDirectionContext).direction;\n}\n\nexport function useMonkeysEnvironment() {\n return useContext(MonkeysEnvironmentContext).environment;\n}\n\nexport function useMonkeysPortalOptions() {\n return useContext(MonkeysEnvironmentContext).portal;\n}\n\nexport function useMonkeysComponentAttributes(): MonkeysComponentAttributes {\n const locale = useContext(MonkeysLocaleContext);\n const theme = useContext(MonkeysThemeContext);\n const direction = useContext(MonkeysDirectionContext);\n const providerActive = locale.provided || theme.provided || direction.provided;\n\n return useMemo(\n () =>\n providerActive\n ? {\n dir: direction.direction,\n 'data-monkeys-direction': direction.direction,\n 'data-monkeys-locale': locale.locale,\n 'data-monkeys-theme': theme.themeId,\n 'data-monkeys-theme-mode': theme.resolvedTheme?.colorMode,\n }\n : {},\n [\n direction.direction,\n locale.locale,\n providerActive,\n theme.resolvedTheme?.colorMode,\n theme.themeId,\n ],\n );\n}\n","import {\n useEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { BaseButton, BaseTooltip, type BaseAppearance } from \"../base\";\nexport { AppShellSidebar } from \"./AppShellSidebar\";\nexport type {\n AppShellSidebarClassNames,\n AppShellSidebarProps,\n} from \"./AppShellSidebar\";\nexport { UserAccountMenu } from \"./UserAccountMenu\";\nexport type {\n UserAccountMenuClassNames,\n UserAccountMenuItem,\n UserAccountMenuProps,\n UserAccountMenuRadius,\n UserAccountMenuSelectorConfig,\n UserAccountMenuSelectorOption,\n UserAccountMenuSide,\n UserAccountMenuTriggerVariant,\n UserAccountMenuUser,\n} from \"./UserAccountMenu\";\n\n// ============================================================\n// cn utility (inline clsx + tailwind-merge–lite for zero deps)\n// ============================================================\nexport function cn(...inputs: (string | undefined | null | false)[]): string {\n return inputs.filter(Boolean).join(\" \");\n}\n\n// ============================================================\n// NavButton\n// ============================================================\nexport interface NavButtonProps {\n /** 是否处于激活状态 */\n active?: boolean;\n /** 左侧图标 */\n icon?: ReactNode;\n /** 右侧附加内容(如 chevron) */\n postfix?: ReactNode;\n /** 点击回调 */\n onClick?: () => void;\n className?: string;\n children: ReactNode;\n}\n\nexport function NavButton({\n active,\n icon,\n postfix,\n onClick,\n className,\n children,\n}: NavButtonProps) {\n return (\n <div\n className={cn(\n \"flex w-full cursor-pointer select-none items-center gap-2 rounded-xl border p-2 text-xs text-[hsl(var(--foreground))] transition-colors\",\n active\n ? \"border-[hsl(var(--input))] bg-[hsl(var(--muted))] font-bold\"\n : \"border-transparent hover:border-[hsl(var(--input))]/60 hover:bg-[hsl(var(--muted))]/60\",\n className,\n )}\n onClick={onClick}\n >\n <div className=\"w-[20px] [&_svg]:h-[16px] [&_svg]:w-[16px]\">{icon}</div>\n <span className=\"text-sm\">{children}</span>\n {postfix}\n </div>\n );\n}\n\n// ============================================================\n// AppHeader\n// ============================================================\nexport interface HeaderTab {\n id: string;\n label: string;\n}\n\nexport interface AppHeaderLogo {\n /** Logo 图片 URL,若为空则显示 fallback */\n url?: string;\n /** 品牌名称 */\n title: string;\n /** 点击 Logo 回调 */\n onClick?: () => void;\n}\n\nexport interface AppHeaderUser {\n name?: string;\n email?: string;\n photo?: string;\n}\n\nexport interface AppHeaderProps {\n /** 品牌 Logo */\n logo: AppHeaderLogo;\n /** 导航 tabs */\n tabs?: HeaderTab[];\n /** 当前激活的 tab id */\n activeTab?: string;\n /** tab 切换回调 */\n onTabChange?: (tabId: string) => void;\n /** 用户信息 */\n user?: AppHeaderUser;\n /** 退出登录回调 */\n onLogout?: () => void;\n /** 退出登录文案 */\n logoutLabel?: string;\n /** 用户菜单中的额外菜单项(在退出登录按钮之前渲染) */\n userMenuItems?: ReactNode;\n /** header 右侧额外内容 */\n extra?: ReactNode;\n className?: string;\n}\n\nexport function AppHeader({\n logo,\n tabs,\n activeTab,\n onTabChange,\n user,\n onLogout,\n logoutLabel = \"退出登录\",\n userMenuItems,\n extra,\n className,\n}: AppHeaderProps) {\n const getUserInitials = (name: string) =>\n name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n\n return (\n <header\n className={cn(\n \"flex h-[72px] w-full shrink-0 items-center justify-between gap-4 rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-[var(--global-spacing,0.75rem)]\",\n className,\n )}\n >\n {/* Logo */}\n <div\n className=\"flex shrink-0 cursor-pointer items-center gap-2\"\n onClick={logo.onClick}\n >\n <div\n className={cn(\n \"flex h-8 w-8 items-center justify-center rounded-lg overflow-hidden\",\n logo.url\n ? \"bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"h-full w-full object-contain\"\n />\n ) : (\n <span className=\"text-sm font-bold\">{logo.title.charAt(0)}</span>\n )}\n </div>\n <span className=\"text-lg font-semibold whitespace-nowrap\">\n {logo.title}\n </span>\n </div>\n\n {/* Separator + Tabs */}\n {tabs && tabs.length > 0 && (\n <>\n <div className=\"h-1/2 w-px bg-[hsl(var(--border))]\" />\n <div className=\"flex flex-1 items-center\">\n <div className=\"inline-flex h-9 items-center gap-1 rounded-md bg-transparent p-1\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n className={cn(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all\",\n tab.id === activeTab\n ? \"bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--muted))]/50\",\n )}\n onClick={() => onTabChange?.(tab.id)}\n >\n {tab.label}\n </button>\n ))}\n </div>\n </div>\n </>\n )}\n {(!tabs || tabs.length === 0) && <div className=\"flex-1\" />}\n\n {/* Right side */}\n <div className=\"flex shrink-0 items-center gap-4\">\n {extra}\n {user && (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button className=\"flex h-8 w-8 items-center justify-center rounded-full hover:ring-2 hover:ring-[hsl(var(--ring))]/20 transition-all overflow-hidden focus-visible:outline-none\">\n {user.photo ? (\n <img\n src={user.photo}\n alt={user.name}\n className=\"h-8 w-8 rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-xs font-medium\">\n {user.name ? getUserInitials(user.name) : \"U\"}\n </div>\n )}\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"z-50 w-52 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-1 text-[hsl(var(--popover-foreground))] shadow-md animate-in fade-in-0 zoom-in-95\"\n sideOffset={5}\n align=\"end\"\n >\n {/* User info label */}\n <DropdownMenu.Label className=\"flex items-center gap-2 px-2 py-1.5 font-normal\">\n {user.photo ? (\n <img\n src={user.photo}\n alt={user.name}\n className=\"h-8 w-8 rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-xs font-medium\">\n {user.name ? getUserInitials(user.name) : \"U\"}\n </div>\n )}\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium leading-none\">\n {user.name}\n </span>\n {user.email && (\n <span className=\"text-xs text-[hsl(var(--muted-foreground))] leading-none mt-1\">\n {user.email}\n </span>\n )}\n </div>\n </DropdownMenu.Label>\n\n <DropdownMenu.Separator className=\"h-px bg-[hsl(var(--border))] my-1\" />\n\n <DropdownMenu.Group>\n {userMenuItems}\n\n {/* Logout */}\n <DropdownMenu.Item\n className=\"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-[hsl(var(--destructive))] outline-none transition-colors hover:bg-[hsl(var(--accent))]\"\n onSelect={() => onLogout?.()}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </svg>\n {logoutLabel}\n </DropdownMenu.Item>\n </DropdownMenu.Group>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n )}\n </div>\n </header>\n );\n}\n\n// ============================================================\n// AppSidebar\n// ============================================================\nexport interface SidebarNavItem {\n id: string;\n label: string;\n icon?: ReactNode;\n /** 如果有 children 则为分组,点击展开/折叠 */\n children?: SidebarNavItem[];\n}\n\nexport interface SidebarAccount {\n name?: string;\n photo?: string;\n}\n\nexport interface AppSidebarProps {\n /** Logo */\n logo?: AppHeaderLogo;\n /** 导航菜单 */\n navItems: SidebarNavItem[];\n /** 当前路径/激活的 item id */\n activeItemId?: string;\n /** 点击导航项回调 */\n onNavigate?: (itemId: string) => void;\n /** 账户信息 */\n account?: SidebarAccount;\n /** 退出登录回调 */\n onLogout?: () => void;\n /** 退出登录文案 */\n logoutLabel?: string;\n /** 底部额外内容(如版本号) */\n footer?: ReactNode;\n /** 默认展开的分组 id 列表 */\n defaultExpandedGroups?: string[];\n className?: string;\n}\n\nexport function AppSidebar({\n logo,\n navItems,\n activeItemId,\n onNavigate,\n account,\n onLogout,\n logoutLabel = \"退出登录\",\n footer,\n defaultExpandedGroups,\n className,\n}: AppSidebarProps) {\n return (\n <div\n className={cn(\n \"flex w-[13.7rem] shrink-0 flex-col justify-between gap-[var(--global-spacing,0.75rem)] overflow-y-hidden rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-5\",\n className,\n )}\n >\n {/* Logo */}\n {logo && (\n <div\n className=\"flex shrink-0 cursor-pointer items-center gap-2\"\n onClick={logo.onClick}\n >\n <div\n className={cn(\n \"flex h-8 w-8 items-center justify-center rounded-lg overflow-hidden\",\n logo.url\n ? \"bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"h-full w-full object-contain\"\n />\n ) : (\n <span className=\"text-sm font-bold\">{logo.title.charAt(0)}</span>\n )}\n </div>\n <span className=\"text-lg font-semibold whitespace-nowrap\">\n {logo.title}\n </span>\n </div>\n )}\n\n {/* Navigation */}\n <SidebarNavList\n items={navItems}\n activeItemId={activeItemId}\n onNavigate={onNavigate}\n defaultExpandedGroups={defaultExpandedGroups}\n />\n\n {/* Account Section */}\n {(account || footer) && (\n <div className=\"flex flex-col gap-2\">\n {account && (\n <div className=\"flex w-full flex-col gap-2 rounded-lg bg-[hsl(var(--muted))] p-2 shadow-sm\">\n <div className=\"flex w-full items-center justify-between px-3 py-1\">\n <div className=\"flex items-center gap-2\">\n {account.photo ? (\n <img\n src={account.photo}\n alt={account.name}\n className=\"h-5 w-5 rounded-full object-cover\"\n />\n ) : (\n <div className=\"flex h-5 w-5 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[10px] font-medium\">\n {account.name\n ? account.name.charAt(0).toUpperCase()\n : \"U\"}\n </div>\n )}\n <span className=\"text-xs font-medium truncate max-w-[100px]\">\n {account.name}\n </span>\n </div>\n {onLogout && (\n <button\n onClick={onLogout}\n className=\"flex items-center justify-center text-[hsl(var(--destructive))] hover:opacity-80 transition-opacity\"\n title={logoutLabel}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n )}\n {footer}\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================\n// SidebarNavList (internal accordion-style nav)\n// ============================================================\ninterface SidebarNavListProps {\n items: SidebarNavItem[];\n activeItemId?: string;\n onNavigate?: (itemId: string) => void;\n defaultExpandedGroups?: string[];\n}\n\nfunction SidebarNavList({\n items,\n activeItemId,\n onNavigate,\n defaultExpandedGroups,\n}: SidebarNavListProps) {\n const [expanded, setExpanded] = useState<Record<string, boolean>>(() => {\n const map: Record<string, boolean> = {};\n (defaultExpandedGroups ?? items.map((i) => i.id)).forEach((id) => {\n map[id] = true;\n });\n return map;\n });\n const [localActiveItemId, setLocalActiveItemId] = useState<\n string | undefined\n >(activeItemId);\n\n useEffect(() => {\n if (activeItemId !== undefined) {\n setLocalActiveItemId(activeItemId);\n }\n }, [activeItemId]);\n\n const toggle = (id: string) => {\n setExpanded((prev: Record<string, boolean>) => ({\n ...prev,\n [id]: !prev[id],\n }));\n };\n const resolvedActiveItemId = activeItemId ?? localActiveItemId;\n\n return (\n <div\n className=\"h-full flex-1 overflow-y-auto\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n <style>{`.monkeys-sidebar-nav::-webkit-scrollbar { display: none; }`}</style>\n <div className=\"monkeys-sidebar-nav flex w-full flex-col gap-2 text-xs text-[hsl(var(--foreground))]\">\n {items.map((item) => {\n if (item.children && item.children.length > 0) {\n const isExpanded = expanded[item.id] ?? true;\n return (\n <div key={item.id}>\n <NavButton\n icon={item.icon}\n onClick={() => toggle(item.id)}\n postfix={\n <div className=\"flex flex-1 justify-end\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0 text-[hsl(var(--foreground))] transition-transform duration-200\"\n style={{\n transform: isExpanded\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\",\n }}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </div>\n }\n >\n {item.label}\n </NavButton>\n {isExpanded && (\n <div className=\"flex flex-col gap-1 mt-1\">\n {item.children.map((child) => (\n <NavButton\n key={child.id}\n active={child.id === resolvedActiveItemId}\n onClick={() => {\n setLocalActiveItemId(child.id);\n onNavigate?.(child.id);\n }}\n >\n {child.label}\n </NavButton>\n ))}\n </div>\n )}\n </div>\n );\n }\n return (\n <NavButton\n key={item.id}\n icon={item.icon}\n active={item.id === resolvedActiveItemId}\n onClick={() => {\n setLocalActiveItemId(item.id);\n onNavigate?.(item.id);\n }}\n >\n {item.label}\n </NavButton>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ============================================================\n// AppLayout\n// ============================================================\nexport interface AppLayoutProps {\n /** header 组件 */\n header?: ReactNode;\n /** sidebar 组件 */\n sidebar?: ReactNode;\n /** 主内容 */\n children: ReactNode;\n /** 是否 flush 布局(无内边距) */\n flush?: boolean;\n className?: string;\n}\n\nexport function AppLayout({\n header,\n sidebar,\n children,\n flush = false,\n className,\n}: AppLayoutProps) {\n return (\n <div\n className={cn(\n \"flex h-screen flex-col gap-[var(--global-spacing,0.75rem)] overflow-hidden p-[var(--global-spacing,0.75rem)]\",\n className,\n )}\n style={{ backgroundColor: \"hsl(var(--muted))\" }}\n >\n {header ? header : null}\n <div className=\"flex flex-1 gap-[var(--global-spacing,0.75rem)] overflow-hidden min-h-0\">\n {sidebar ? sidebar : null}\n <main\n className={cn(\n \"flex-1 min-h-0 overflow-hidden rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))]\",\n !flush && \"overflow-y-auto\",\n )}\n >\n {flush ? (\n children\n ) : (\n <div className=\"h-full overflow-y-auto\">{children}</div>\n )}\n </main>\n </div>\n </div>\n );\n}\n\n// ============================================================\n// NavigationLayout\n// ============================================================\nexport type NavigationMode = \"sidebar\" | \"headbar\";\nexport type HeadbarLayoutMode = \"boxed\" | \"full-bleed\";\nexport type HeadbarMenuRadius =\n \"default\" | \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\nexport type HeadbarNavPosition = \"left\" | \"center\" | \"right\";\nexport type HeadbarSurface = \"card\" | \"glassy\" | \"ghost\";\n\nexport interface LayoutNavItem {\n id: string;\n label: ReactNode;\n headbarLabel?: ReactNode;\n icon?: ReactNode;\n children?: LayoutNavItem[];\n disabled?: boolean;\n trailing?: ReactNode;\n}\n\ninterface NavigationLayoutAction {\n id: string;\n label: ReactNode;\n title?: string;\n icon?: ReactNode;\n onClick?: () => void;\n}\n\nexport interface HeadbarLayout {\n brandTitle?: ReactNode;\n heightPx?: number;\n layoutMode?: HeadbarLayoutMode;\n menuRadius?: HeadbarMenuRadius;\n navPosition?: HeadbarNavPosition;\n surface?: HeadbarSurface;\n}\n\nexport interface NavigationLayoutProps {\n activeItemId?: string;\n activeRootId?: string;\n allowModeSwitch?: boolean;\n accountMenu?: ReactNode;\n children: ReactNode;\n className?: string;\n collapsedSidebarAccountMenu?: ReactNode;\n collapsedSidebarWidth?: string;\n defaultMode?: NavigationMode;\n defaultSidebarCollapsed?: boolean;\n expandedSidebarWidth?: string;\n expandSidebarLabel?: string;\n flush?: boolean;\n headbarActions?: ReactNode;\n headbarLayout?: HeadbarLayout;\n logo?: AppHeaderLogo;\n mode?: NavigationMode;\n navItems: LayoutNavItem[];\n onModeChange?: (mode: NavigationMode) => void;\n onNavigate?: (itemId: string) => void;\n onSidebarCollapsedChange?: (collapsed: boolean) => void;\n renderHeadbarExtra?: ReactNode;\n collapseSidebarLabel?: string;\n sidebarCollapsed?: boolean;\n sidebarAccountMenu?: ReactNode;\n sidebarFooter?: ReactNode;\n sidebarHeader?: ReactNode;\n switchToHeadbarLabel?: string;\n switchToSidebarLabel?: string;\n}\n\nconst NAVIGATION_LAYOUT_SIDEBAR_EXPANDED_WIDTH = \"13.7rem\";\nconst NAVIGATION_LAYOUT_SIDEBAR_COLLAPSED_WIDTH = \"4.25rem\";\nconst NAVIGATION_LAYOUT_TRANSITION_TIMING = \"cubic-bezier(0.22, 1, 0.36, 1)\";\nconst NAVIGATION_LAYOUT_HEADBAR_DEFAULT_HEIGHT_PX = 72;\nconst NAVIGATION_LAYOUT_HEADBAR_MIN_HEIGHT_PX = 56;\nconst NAVIGATION_LAYOUT_HEADBAR_MAX_HEIGHT_PX = 120;\nconst NAVIGATION_LAYOUT_HEADBAR_COMPACT_HEIGHT_THRESHOLD_PX = 64;\nconst NAVIGATION_LAYOUT_HEADBAR_BOXED_VERTICAL_PADDING_PX = 12;\nconst NAVIGATION_LAYOUT_HEADBAR_COMPACT_VERTICAL_PADDING_PX = 8;\nconst NAVIGATION_LAYOUT_HEADBAR_LOGO_DEFAULT_SIZE_PX = 44;\nconst NAVIGATION_LAYOUT_HEADBAR_LOGO_COMPACT_SIZE_PX = 36;\nconst NAVIGATION_LAYOUT_DEFAULT_APPEARANCE: BaseAppearance = {\n preset: \"soft\",\n density: \"compact\",\n radius: \"lg\",\n border: \"subtle\",\n background: \"soft\",\n};\n\nconst NAVIGATION_LAYOUT_MENU_RADIUS_CLASS_MAP: Record<\n Exclude<HeadbarMenuRadius, \"default\">,\n { all: string; left: string; right: string }\n> = {\n none: { all: \"rounded-none\", left: \"!rounded-none\", right: \"!rounded-none\" },\n sm: {\n all: \"rounded-sm\",\n left: \"!rounded-l-sm !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-sm\",\n },\n md: {\n all: \"rounded-md\",\n left: \"!rounded-l-md !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-md\",\n },\n lg: {\n all: \"rounded-lg\",\n left: \"!rounded-l-lg !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-lg\",\n },\n xl: {\n all: \"rounded-xl\",\n left: \"!rounded-l-xl !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-xl\",\n },\n full: {\n all: \"rounded-full\",\n left: \"!rounded-l-full !rounded-r-none\",\n right: \"!rounded-l-none !rounded-r-full\",\n },\n};\n\nfunction clampHeadbarHeight(value?: number) {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n return NAVIGATION_LAYOUT_HEADBAR_DEFAULT_HEIGHT_PX;\n return Math.min(\n NAVIGATION_LAYOUT_HEADBAR_MAX_HEIGHT_PX,\n Math.max(NAVIGATION_LAYOUT_HEADBAR_MIN_HEIGHT_PX, Math.round(value)),\n );\n}\n\nfunction getHeadbarVerticalPaddingPx(heightPx: number) {\n return heightPx <= NAVIGATION_LAYOUT_HEADBAR_COMPACT_HEIGHT_THRESHOLD_PX\n ? NAVIGATION_LAYOUT_HEADBAR_COMPACT_VERTICAL_PADDING_PX\n : NAVIGATION_LAYOUT_HEADBAR_BOXED_VERTICAL_PADDING_PX;\n}\n\nfunction getHeadbarLogoSizePx(heightPx: number) {\n return heightPx <= NAVIGATION_LAYOUT_HEADBAR_COMPACT_HEIGHT_THRESHOLD_PX\n ? NAVIGATION_LAYOUT_HEADBAR_LOGO_COMPACT_SIZE_PX\n : NAVIGATION_LAYOUT_HEADBAR_LOGO_DEFAULT_SIZE_PX;\n}\n\nfunction getHeadbarMenuRadiusClass(\n menuRadius: HeadbarMenuRadius = \"default\",\n part: \"all\" | \"left\" | \"right\" = \"all\",\n) {\n if (menuRadius === \"default\") {\n if (part === \"left\") return \"rounded-l-lg rounded-r-none\";\n if (part === \"right\") return \"rounded-l-none rounded-r-lg\";\n return \"rounded-lg\";\n }\n return NAVIGATION_LAYOUT_MENU_RADIUS_CLASS_MAP[menuRadius][part];\n}\n\nfunction getHeadbarFrameClass(\n layoutMode: HeadbarLayoutMode = \"boxed\",\n navPosition: HeadbarNavPosition = \"center\",\n) {\n const columns =\n navPosition === \"center\"\n ? \"grid-cols-[minmax(max-content,1fr)_minmax(0,max-content)_minmax(max-content,1fr)]\"\n : \"grid-cols-[max-content_minmax(0,1fr)_max-content]\";\n return layoutMode === \"full-bleed\"\n ? cn(\n \"sticky top-0 z-40 grid w-full shrink-0 items-center gap-4 rounded-none border-b border-x-0 border-t-0 border-[hsl(var(--input))] bg-[hsl(var(--background))] p-[var(--global-spacing,0.75rem)]\",\n columns,\n )\n : cn(\n \"sticky top-0 z-40 grid w-full shrink-0 items-center gap-4 rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-[var(--global-spacing,0.75rem)]\",\n columns,\n );\n}\n\nfunction getHeadbarFrameStyle(\n layoutMode: HeadbarLayoutMode = \"boxed\",\n heightPx: number,\n surface: HeadbarSurface = \"card\",\n): CSSProperties {\n const verticalPaddingPx = getHeadbarVerticalPaddingPx(heightPx);\n const fallbackBackground = \"hsl(var(--background))\";\n const style: CSSProperties = {\n height: `var(--monkeys-component-navigation-headbar-height, ${heightPx}px)`,\n minHeight: `var(--monkeys-component-navigation-headbar-height, ${heightPx}px)`,\n paddingTop: `${verticalPaddingPx}px`,\n paddingBottom: `${verticalPaddingPx}px`,\n background: `var(--monkeys-component-navigation-headbar-frame-background, ${fallbackBackground})`,\n color:\n \"var(--monkeys-component-navigation-headbar-frame-foreground, hsl(var(--foreground)))\",\n borderColor:\n surface === \"glassy\"\n ? \"var(--monkeys-component-navigation-headbar-frame-border-color, rgb(255 255 255 / 0.5))\"\n : \"var(--monkeys-component-navigation-headbar-frame-border-color, hsl(var(--input)))\",\n borderRadius:\n layoutMode === \"full-bleed\"\n ? \"0\"\n : \"var(--monkeys-component-navigation-headbar-frame-radius, var(--radius, 0.75rem))\",\n boxShadow:\n surface === \"glassy\"\n ? \"var(--monkeys-component-navigation-headbar-frame-shadow, inset 0 0 0 0 rgb(0 0 0 / 0.1))\"\n : \"var(--monkeys-component-navigation-headbar-frame-shadow, none)\",\n backdropFilter: `blur(var(--monkeys-component-navigation-headbar-frame-backdrop-blur, ${surface === \"glassy\" ? \"45px\" : \"0px\"}))`,\n };\n\n if (layoutMode === \"full-bleed\") {\n style.marginLeft = \"calc(var(--global-spacing,0.75rem) * -1)\";\n style.marginRight = \"calc(var(--global-spacing,0.75rem) * -1)\";\n style.marginTop = \"calc(var(--global-spacing,0.75rem) * -1)\";\n style.width = \"calc(100% + (var(--global-spacing,0.75rem) * 2))\";\n }\n\n return style;\n}\n\nfunction getHeadbarNavClass(navPosition: HeadbarNavPosition = \"center\") {\n if (navPosition === \"left\") return \"justify-start\";\n if (navPosition === \"right\") return \"justify-end\";\n return \"justify-center\";\n}\n\nfunction getHeadbarItemStyle(\n active: boolean,\n useTokenRadius = true,\n): CSSProperties {\n return {\n height: \"var(--monkeys-component-navigation-headbar-item-height, 2.25rem)\",\n borderRadius: useTokenRadius\n ? \"var(--monkeys-component-navigation-headbar-item-radius, var(--radius, 0.5rem))\"\n : undefined,\n paddingInline:\n \"var(--monkeys-component-navigation-headbar-item-padding-inline, 0.75rem)\",\n columnGap: \"var(--monkeys-component-navigation-headbar-item-gap, 0.375rem)\",\n color: active\n ? \"var(--monkeys-component-navigation-headbar-item-active-foreground, hsl(var(--foreground)))\"\n : \"var(--monkeys-component-navigation-headbar-item-foreground, hsl(var(--muted-foreground)))\",\n background: active\n ? \"var(--monkeys-component-navigation-headbar-item-active-background, hsl(var(--muted)))\"\n : \"transparent\",\n borderColor: active\n ? \"var(--monkeys-component-navigation-headbar-item-active-border-color, transparent)\"\n : \"transparent\",\n fontSize:\n \"var(--monkeys-component-navigation-headbar-item-font-size, 0.875rem)\",\n fontWeight:\n \"var(--monkeys-component-navigation-headbar-item-font-weight, 500)\",\n };\n}\n\nfunction findNavigationRootId(\n items: LayoutNavItem[],\n activeItemId?: string,\n): string | undefined {\n for (const item of items) {\n if (item.id === activeItemId) return item.id;\n if (item.children?.some((child) => child.id === activeItemId))\n return item.id;\n }\n return activeItemId;\n}\n\nfunction getNavigationActionTitle(action: NavigationLayoutAction) {\n return (\n action.title ||\n (typeof action.label === \"string\" ? action.label : undefined)\n );\n}\n\nfunction NavigationLayoutActionButtons({\n actions,\n compact,\n}: {\n actions: NavigationLayoutAction[];\n compact: boolean;\n}) {\n if (!actions.length) return null;\n\n if (compact) {\n return (\n <div className=\"flex flex-col items-center gap-2\">\n {actions.map((action) => {\n const title = getNavigationActionTitle(action);\n return (\n <BaseTooltip\n key={action.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n content={action.label}\n placement=\"right\"\n portal\n >\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n iconOnly\n icon={action.icon}\n onClick={action.onClick}\n title={title}\n ariaLabel={title}\n className={cn(\n \"h-10 w-10 rounded-lg border-transparent text-[hsl(var(--muted-foreground))] shadow-none\",\n \"hover:-translate-y-0.5 hover:border-[hsl(var(--input))]/80 hover:bg-[hsl(var(--muted))] hover:text-[hsl(var(--foreground))]\",\n \"active:translate-y-0 active:scale-[0.96]\",\n )}\n />\n </BaseTooltip>\n );\n })}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-2\">\n {actions.map((action) => (\n <BaseButton\n key={action.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n icon={action.icon}\n label={<span className=\"truncate\">{action.label}</span>}\n onClick={action.onClick}\n title={getNavigationActionTitle(action)}\n className={cn(\n \"h-9 w-full justify-start gap-2.5 rounded-lg border-transparent px-3 text-left text-[13px] text-[hsl(var(--muted-foreground))] shadow-none\",\n \"hover:-translate-y-0.5 hover:border-[hsl(var(--input))]/80 hover:bg-[hsl(var(--muted))]/70 hover:text-[hsl(var(--foreground))]\",\n \"active:translate-y-0 active:scale-[0.985]\",\n )}\n />\n ))}\n </div>\n );\n}\n\nfunction SidebarNavigationList({\n activeItemId,\n items,\n onNavigate,\n revealRequest,\n}: {\n activeItemId?: string;\n items: LayoutNavItem[];\n onNavigate?: (itemId: string) => void;\n revealRequest?: { id: string; nonce: number } | null;\n}) {\n const navRef = useRef<HTMLDivElement | null>(null);\n const [expandedByRoot, setExpandedByRoot] = useState<Record<string, boolean>>(\n {},\n );\n\n const toggleRoot = (id: string) => {\n setExpandedByRoot((current) => ({\n ...current,\n [id]: !current[id],\n }));\n };\n\n useEffect(() => {\n if (!revealRequest) return;\n setExpandedByRoot((current) => ({\n ...current,\n [revealRequest.id]: true,\n }));\n\n const frameId = window.requestAnimationFrame(() => {\n const targetElement = navRef.current?.querySelector(\n `[data-navigation-sidebar-root-id=\"${CSS.escape(revealRequest.id)}\"]`,\n );\n if (targetElement instanceof HTMLElement) {\n targetElement.scrollIntoView({\n behavior: \"auto\",\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n });\n\n return () => window.cancelAnimationFrame(frameId);\n }, [revealRequest]);\n\n return (\n <div\n className=\"h-full flex-1 overflow-y-auto\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n <style>{`.monkeys-navigation-sidebar-nav::-webkit-scrollbar { display: none; }`}</style>\n <div\n ref={navRef}\n className=\"monkeys-navigation-sidebar-nav flex w-full flex-col gap-2 text-xs text-[hsl(var(--foreground))]\"\n >\n {items.map((item) => {\n const isGroup = Boolean(item.children?.length);\n const isExpanded = Boolean(expandedByRoot[item.id]);\n const isActive = activeItemId === item.id;\n\n if (isGroup) {\n return (\n <div key={item.id} data-navigation-sidebar-root-id={item.id}>\n <NavButton\n icon={item.icon}\n onClick={() => toggleRoot(item.id)}\n postfix={\n <div className=\"flex flex-1 justify-end\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0 text-[hsl(var(--foreground))] transition-transform duration-200\"\n style={{\n transform: isExpanded\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\",\n }}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </div>\n }\n >\n {item.label}\n </NavButton>\n {isExpanded ? (\n <div className=\"mt-1 flex flex-col gap-1\">\n {item.children?.map((child) => (\n <NavButton\n key={child.id}\n active={activeItemId === child.id}\n onClick={() => onNavigate?.(child.id)}\n >\n {child.label}\n </NavButton>\n ))}\n </div>\n ) : null}\n </div>\n );\n }\n\n return (\n <div key={item.id} data-navigation-sidebar-root-id={item.id}>\n <NavButton\n active={isActive}\n icon={item.icon}\n onClick={() => onNavigate?.(item.id)}\n >\n {item.label}\n </NavButton>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction SidebarBrand({\n collapsed,\n logo,\n title,\n}: {\n collapsed?: boolean;\n logo?: AppHeaderLogo;\n title?: ReactNode;\n}) {\n if (!logo) return null;\n\n const brandTitle = title ?? logo.title;\n const logoMark = (\n <div\n className={cn(\n \"flex h-9 w-9 shrink-0 items-center justify-center overflow-hidden rounded-lg\",\n logo.url\n ? \"bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"h-full w-full object-contain\"\n />\n ) : (\n <span className=\"text-sm font-bold\">{logo.title.charAt(0)}</span>\n )}\n </div>\n );\n\n if (collapsed) {\n return (\n <BaseTooltip\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n content={brandTitle}\n placement=\"right\"\n portal\n >\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n ariaLabel={typeof brandTitle === \"string\" ? brandTitle : logo.title}\n className=\"h-10 w-10 rounded-lg border-transparent bg-transparent p-0 shadow-none hover:bg-[hsl(var(--muted))]/60\"\n icon={logoMark}\n iconOnly\n onClick={logo.onClick}\n title={typeof brandTitle === \"string\" ? brandTitle : logo.title}\n tone=\"muted\"\n />\n </BaseTooltip>\n );\n }\n\n return (\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n ariaLabel={logo.title}\n className=\"h-auto w-full justify-start gap-3 border-transparent bg-transparent p-0 text-left shadow-none hover:bg-transparent\"\n classNames={{ icon: \"h-9 w-9\" }}\n icon={logoMark}\n label={\n <span className=\"min-w-0 truncate text-sm font-semibold text-[hsl(var(--foreground))]\">\n {brandTitle}\n </span>\n }\n onClick={logo.onClick}\n title={typeof brandTitle === \"string\" ? brandTitle : logo.title}\n tone=\"muted\"\n />\n );\n}\n\nfunction Sidebar({\n accountMenu,\n activeItemId,\n actions = [],\n collapsed,\n collapsedAccountMenu,\n footer,\n header,\n items,\n logo,\n onCollapsedChange,\n onNavigate,\n onRevealRoot,\n revealRequest,\n title,\n}: {\n accountMenu?: ReactNode;\n activeItemId?: string;\n actions?: NavigationLayoutAction[];\n collapsed?: boolean;\n collapsedAccountMenu?: ReactNode;\n footer?: ReactNode;\n header?: ReactNode;\n items: LayoutNavItem[];\n logo?: AppHeaderLogo;\n onCollapsedChange?: (collapsed: boolean) => void;\n onNavigate?: (itemId: string) => void;\n onRevealRoot?: (rootId: string) => void;\n revealRequest?: { id: string; nonce: number } | null;\n title?: ReactNode;\n}) {\n if (collapsed) {\n const activeRootId = findNavigationRootId(items, activeItemId);\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] p-2 shadow-sm\">\n <div className=\"mb-3 flex shrink-0 justify-center\">\n {header ?? <SidebarBrand collapsed logo={logo} title={title} />}\n </div>\n <div\n className=\"flex min-h-0 flex-1 flex-col items-center gap-2 overflow-y-auto pb-3\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n {items.map((item) => {\n const isActive = activeRootId === item.id;\n return (\n <BaseTooltip\n key={item.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n content={item.label}\n placement=\"right\"\n portal\n >\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n active={isActive}\n iconOnly\n icon={item.icon}\n onClick={() => {\n onRevealRoot?.(item.id);\n onCollapsedChange?.(false);\n if (item.children?.length) return;\n onNavigate?.(item.id);\n }}\n title={\n typeof item.label === \"string\" ? item.label : undefined\n }\n ariaLabel={\n typeof item.label === \"string\" ? item.label : item.id\n }\n className={cn(\n \"h-10 w-10 rounded-lg border text-[hsl(var(--muted-foreground))] shadow-none\",\n \"hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.96]\",\n isActive\n ? \"border-[hsl(var(--input))] bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"border-transparent hover:border-[hsl(var(--input))]/80 hover:bg-[hsl(var(--muted))]/70 hover:text-[hsl(var(--foreground))]\",\n )}\n />\n </BaseTooltip>\n );\n })}\n </div>\n <div className=\"-mx-2 mt-2 border-t border-[hsl(var(--input))] bg-[hsl(var(--background))] px-2 pt-2.5 pb-0.5\">\n <NavigationLayoutActionButtons actions={actions} compact />\n {collapsedAccountMenu ? (\n <div className=\"mt-2 flex justify-center border-t border-[hsl(var(--input))] pt-2\">\n {collapsedAccountMenu}\n </div>\n ) : null}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col justify-between gap-0 overflow-y-hidden rounded-xl border border-[hsl(var(--input))] bg-[hsl(var(--background))] px-5 pt-5 pb-1.5\">\n <div className=\"mb-4 shrink-0\">\n {header ?? <SidebarBrand logo={logo} title={title} />}\n </div>\n <SidebarNavigationList\n activeItemId={activeItemId}\n items={items}\n onNavigate={onNavigate}\n revealRequest={revealRequest}\n />\n <div className=\"-mx-5 mt-2 border-t border-[hsl(var(--input))] bg-[hsl(var(--background))] px-4 pt-2.5 pb-1\">\n <NavigationLayoutActionButtons actions={actions} compact={false} />\n {footer}\n {accountMenu ? (\n <div className=\"mt-2 border-t border-[hsl(var(--input))] pt-2\">\n {accountMenu}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction HeadbarChevronIcon({ open }: { open: boolean }) {\n return (\n <svg\n aria-hidden=\"true\"\n className={cn(\n \"h-4 w-4 shrink-0 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nfunction HeadbarNavMenuItem({\n activeItemId,\n isActive,\n item,\n label,\n menuButtonRadiusClass,\n menuContentRadiusClass,\n menuItemRadiusClass,\n onNavigate,\n useTokenRadius,\n}: {\n activeItemId?: string;\n isActive: boolean;\n item: LayoutNavItem;\n label: ReactNode;\n menuButtonRadiusClass: string;\n menuContentRadiusClass: string;\n menuItemRadiusClass: string;\n onNavigate?: (itemId: string) => void;\n useTokenRadius: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearCloseTimer = () => {\n if (!closeTimerRef.current) return;\n clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n };\n\n const openMenu = () => {\n clearCloseTimer();\n setOpen(true);\n };\n\n const scheduleCloseMenu = () => {\n clearCloseTimer();\n closeTimerRef.current = setTimeout(() => {\n setOpen(false);\n closeTimerRef.current = null;\n }, 120);\n };\n\n useEffect(() => clearCloseTimer, []);\n\n return (\n <DropdownMenu.Root modal={false} open={open} onOpenChange={setOpen}>\n <DropdownMenu.Trigger asChild>\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n active={isActive || open}\n icon={item.icon}\n endIcon={<HeadbarChevronIcon open={open} />}\n label={<span className=\"truncate whitespace-nowrap\">{label}</span>}\n disabled={item.disabled}\n onClick={() => setOpen(true)}\n onMouseEnter={openMenu}\n onMouseLeave={scheduleCloseMenu}\n style={getHeadbarItemStyle(isActive || open, useTokenRadius)}\n classNames={{\n icon: \"text-[inherit] [&_*]:!text-[inherit] [&_svg]:!stroke-current\",\n label: \"text-[inherit] [&_*]:!text-[inherit]\",\n }}\n className={cn(\n \"max-w-[12rem] shrink-0 border shadow-none\",\n menuButtonRadiusClass,\n isActive || open\n ? \"\"\n : \"hover:!bg-[var(--monkeys-component-navigation-headbar-item-hover-background,hsl(var(--muted)))] hover:!text-[var(--monkeys-component-navigation-headbar-item-hover-foreground,hsl(var(--foreground)))]\",\n )}\n />\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n align=\"start\"\n sideOffset={5}\n onCloseAutoFocus={(event) => event.preventDefault()}\n onMouseEnter={openMenu}\n onMouseLeave={scheduleCloseMenu}\n className={cn(\n \"z-50 min-w-56 border p-1.5 animate-in fade-in-0 zoom-in-95\",\n menuContentRadiusClass,\n )}\n style={{\n background:\n \"var(--monkeys-component-navigation-headbar-menu-background, hsl(var(--popover)))\",\n borderColor:\n \"var(--monkeys-component-navigation-headbar-menu-border-color, hsl(var(--border)))\",\n color:\n \"var(--monkeys-component-navigation-headbar-menu-foreground, hsl(var(--popover-foreground)))\",\n boxShadow:\n \"var(--monkeys-component-navigation-headbar-menu-shadow, 0 10px 15px -3px rgb(0 0 0 / 0.1))\",\n backdropFilter:\n \"blur(var(--monkeys-component-navigation-headbar-menu-backdrop-blur, 0px))\",\n }}\n >\n {item.children?.map((child) => (\n <DropdownMenu.Item\n key={child.id}\n disabled={child.disabled}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2.5 px-3 py-2 text-sm outline-none transition-colors hover:bg-[var(--monkeys-component-navigation-headbar-item-hover-background,hsl(var(--accent)))]\",\n menuItemRadiusClass,\n )}\n style={getHeadbarItemStyle(\n child.id === activeItemId,\n useTokenRadius,\n )}\n onSelect={() => {\n if (child.disabled) return;\n setOpen(false);\n onNavigate?.(child.id);\n }}\n >\n {child.icon ? (\n <span className=\"inline-flex h-4 w-4 shrink-0 items-center justify-center text-[hsl(var(--muted-foreground))]\">\n {child.icon}\n </span>\n ) : null}\n <span className=\"min-w-0 truncate\">\n {child.headbarLabel ?? child.label}\n </span>\n {child.trailing}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n}\n\nexport interface NavigationHeadbarMenuProps {\n activeItemId?: string;\n activeRootId?: string;\n items: LayoutNavItem[];\n menuRadius?: HeadbarMenuRadius;\n onNavigate?: (itemId: string) => void;\n}\n\nexport function NavigationHeadbarMenu({\n activeItemId,\n activeRootId,\n items,\n menuRadius = \"default\",\n onNavigate,\n}: NavigationHeadbarMenuProps) {\n const menuButtonRadiusClass = getHeadbarMenuRadiusClass(menuRadius);\n const menuContentRadiusClass = getHeadbarMenuRadiusClass(menuRadius);\n const menuItemRadiusClass = getHeadbarMenuRadiusClass(menuRadius);\n const useTokenRadius = menuRadius === \"default\";\n\n return (\n <div className=\"flex w-max min-w-0 shrink-0 items-center gap-1\">\n {items.map((item) => {\n const isActive = activeRootId === item.id || activeItemId === item.id;\n const label = item.headbarLabel ?? item.label;\n\n if (item.children?.length) {\n return (\n <HeadbarNavMenuItem\n key={item.id}\n activeItemId={activeItemId}\n isActive={isActive}\n item={item}\n label={label}\n menuButtonRadiusClass={menuButtonRadiusClass}\n menuContentRadiusClass={menuContentRadiusClass}\n menuItemRadiusClass={menuItemRadiusClass}\n onNavigate={onNavigate}\n useTokenRadius={useTokenRadius}\n />\n );\n }\n\n return (\n <BaseButton\n key={item.id}\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n active={isActive}\n disabled={item.disabled}\n icon={item.icon}\n label={\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span className=\"truncate whitespace-nowrap\">{label}</span>\n {item.trailing}\n </span>\n }\n onClick={() => onNavigate?.(item.id)}\n style={getHeadbarItemStyle(isActive, useTokenRadius)}\n classNames={{\n icon: \"text-[inherit] [&_*]:!text-[inherit] [&_svg]:!stroke-current\",\n label: \"text-[inherit] [&_*]:!text-[inherit]\",\n }}\n className={cn(\n \"max-w-[12rem] shrink-0 border shadow-none\",\n menuButtonRadiusClass,\n isActive\n ? \"\"\n : \"hover:!bg-[var(--monkeys-component-navigation-headbar-item-hover-background,hsl(var(--muted)))] hover:!text-[var(--monkeys-component-navigation-headbar-item-hover-foreground,hsl(var(--foreground)))]\",\n )}\n />\n );\n })}\n </div>\n );\n}\n\nexport interface NavigationHeadbarProps {\n activeItemId?: string;\n activeRootId?: string;\n actions?: ReactNode;\n accountMenu?: ReactNode;\n className?: string;\n extra?: ReactNode;\n layout?: HeadbarLayout;\n brand?: ReactNode;\n logo?: AppHeaderLogo;\n navigation?: ReactNode;\n navItems?: LayoutNavItem[];\n onNavigate?: (itemId: string) => void;\n}\n\nexport function NavigationHeadbar({\n activeItemId,\n activeRootId,\n actions,\n accountMenu,\n className,\n extra,\n layout,\n brand,\n logo,\n navigation,\n navItems = [],\n onNavigate,\n}: NavigationHeadbarProps) {\n const heightPx = clampHeadbarHeight(layout?.heightPx);\n const layoutMode = layout?.layoutMode ?? \"boxed\";\n const menuRadius = layout?.menuRadius ?? \"default\";\n const surface = layout?.surface ?? \"card\";\n const logoHeightPx = getHeadbarLogoSizePx(heightPx);\n const frameStyle = getHeadbarFrameStyle(layoutMode, heightPx, surface);\n const showBrandTitle = Boolean(layout?.brandTitle);\n\n return (\n <header\n className={cn(\n getHeadbarFrameClass(layoutMode, layout?.navPosition),\n className,\n )}\n data-navigation-headbar=\"\"\n data-navigation-headbar-surface={surface}\n style={frameStyle}\n >\n <div className=\"flex min-w-0 items-center justify-start\">\n {brand ??\n (logo ? (\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n icon={\n <div\n className={cn(\n \"flex items-center justify-center overflow-hidden rounded-lg\",\n logo.url\n ? \"w-auto max-w-[min(22rem,30vw)] bg-transparent\"\n : \"bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]\",\n )}\n style={\n logo.url\n ? { height: logoHeightPx }\n : { width: logoHeightPx, height: logoHeightPx }\n }\n >\n {logo.url ? (\n <img\n src={logo.url}\n alt={logo.title}\n className=\"block h-full w-auto object-contain\"\n />\n ) : (\n <span className=\"text-base font-bold\">\n {logo.title.charAt(0)}\n </span>\n )}\n </div>\n }\n label={\n showBrandTitle ? (\n <span className=\"truncate whitespace-nowrap text-base font-medium text-[hsl(var(--foreground))]\">\n {layout?.brandTitle}\n </span>\n ) : null\n }\n ariaLabel={logo.title}\n title={logo.title}\n className=\"h-auto min-w-0 justify-start border-transparent bg-transparent p-0 shadow-none hover:bg-transparent\"\n classNames={\n logo.url ? { icon: \"!h-auto !w-auto shrink-0\" } : undefined\n }\n onClick={logo.onClick}\n />\n ) : null)}\n </div>\n\n <div\n className={cn(\n \"flex min-w-0 items-center\",\n getHeadbarNavClass(layout?.navPosition),\n )}\n >\n <div className=\"no-scrollbar flex max-w-full min-w-0 items-center overflow-x-auto overscroll-x-contain\">\n {navigation ?? (\n <NavigationHeadbarMenu\n activeItemId={activeItemId}\n activeRootId={activeRootId}\n items={navItems}\n menuRadius={menuRadius}\n onNavigate={onNavigate}\n />\n )}\n </div>\n </div>\n\n <div className=\"flex min-w-0 items-center justify-end gap-3\">\n {actions}\n {extra}\n {accountMenu}\n </div>\n </header>\n );\n}\n\nexport function NavigationLayout({\n activeItemId,\n activeRootId,\n allowModeSwitch = false,\n accountMenu,\n children,\n className,\n collapsedSidebarAccountMenu,\n collapsedSidebarWidth = NAVIGATION_LAYOUT_SIDEBAR_COLLAPSED_WIDTH,\n defaultMode = \"headbar\",\n defaultSidebarCollapsed = false,\n expandedSidebarWidth = NAVIGATION_LAYOUT_SIDEBAR_EXPANDED_WIDTH,\n expandSidebarLabel = \"Expand sidebar\",\n flush = false,\n headbarActions,\n headbarLayout,\n logo,\n mode,\n navItems,\n onModeChange,\n onNavigate,\n onSidebarCollapsedChange,\n renderHeadbarExtra,\n collapseSidebarLabel = \"Collapse sidebar\",\n sidebarCollapsed: controlledSidebarCollapsed,\n sidebarAccountMenu,\n sidebarFooter,\n sidebarHeader,\n switchToHeadbarLabel = \"Switch to headbar\",\n switchToSidebarLabel = \"Switch to sidebar\",\n}: NavigationLayoutProps) {\n const [uncontrolledMode, setUncontrolledMode] =\n useState<NavigationMode>(defaultMode);\n const [uncontrolledSidebarCollapsed, setUncontrolledSidebarCollapsed] =\n useState(defaultSidebarCollapsed);\n const [revealRequest, setRevealRequest] = useState<{\n id: string;\n nonce: number;\n } | null>(null);\n const isModeControlled = mode !== undefined;\n const isSidebarCollapsedControlled = controlledSidebarCollapsed !== undefined;\n const navigationMode = isModeControlled ? mode : uncontrolledMode;\n const sidebarCollapsed = isSidebarCollapsedControlled\n ? controlledSidebarCollapsed\n : uncontrolledSidebarCollapsed;\n const isHeadbarMode = navigationMode === \"headbar\";\n const sidebarWidth = sidebarCollapsed\n ? collapsedSidebarWidth\n : expandedSidebarWidth;\n\n useEffect(() => {\n if (!isModeControlled) {\n setUncontrolledMode(defaultMode);\n }\n }, [defaultMode, isModeControlled]);\n\n useEffect(() => {\n if (!isSidebarCollapsedControlled) {\n setUncontrolledSidebarCollapsed(defaultSidebarCollapsed);\n }\n }, [defaultSidebarCollapsed, isSidebarCollapsedControlled]);\n\n const setNavigationMode = (nextMode: NavigationMode) => {\n if (!isModeControlled) {\n setUncontrolledMode(nextMode);\n }\n onModeChange?.(nextMode);\n };\n\n const setCollapsed = (collapsed: boolean) => {\n if (!isSidebarCollapsedControlled) {\n setUncontrolledSidebarCollapsed(collapsed);\n }\n onSidebarCollapsedChange?.(collapsed);\n };\n\n const navigationActions: NavigationLayoutAction[] = [];\n if (allowModeSwitch) {\n navigationActions.push({\n id: \"toggle-headbar\",\n label: switchToHeadbarLabel,\n onClick: () => setNavigationMode(\"headbar\"),\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-[18px] w-[18px] rotate-180\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n </svg>\n ),\n });\n }\n navigationActions.push({\n id: \"toggle-sidebar\",\n label: sidebarCollapsed ? expandSidebarLabel : collapseSidebarLabel,\n onClick: () => setCollapsed(!sidebarCollapsed),\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-[18px] w-[18px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d={sidebarCollapsed ? \"m14 9 3 3-3 3\" : \"m16 15-3-3 3-3\"} />\n </svg>\n ),\n });\n\n const sidebar = isHeadbarMode ? null : (\n <div\n className={cn(\n \"relative h-full min-h-0 shrink-0 transition-[width] duration-260\",\n sidebarCollapsed ? \"z-20 overflow-visible\" : \"z-10 overflow-hidden\",\n )}\n style={{\n width: sidebarWidth,\n transitionTimingFunction: NAVIGATION_LAYOUT_TRANSITION_TIMING,\n }}\n >\n <Sidebar\n accountMenu={sidebarAccountMenu ?? accountMenu}\n activeItemId={activeItemId}\n actions={navigationActions}\n collapsed={sidebarCollapsed}\n collapsedAccountMenu={collapsedSidebarAccountMenu ?? accountMenu}\n footer={sidebarFooter}\n header={sidebarHeader}\n items={navItems}\n logo={logo}\n onCollapsedChange={setCollapsed}\n onNavigate={onNavigate}\n onRevealRoot={(rootId) =>\n setRevealRequest((prev) => ({\n id: rootId,\n nonce: (prev?.nonce ?? 0) + 1,\n }))\n }\n revealRequest={revealRequest}\n title={headbarLayout?.brandTitle}\n />\n </div>\n );\n\n const header = isHeadbarMode ? (\n <NavigationHeadbar\n activeItemId={activeItemId}\n activeRootId={\n activeRootId ?? findNavigationRootId(navItems, activeItemId)\n }\n actions={\n allowModeSwitch ? (\n <>\n {headbarActions}\n <BaseButton\n appearance={NAVIGATION_LAYOUT_DEFAULT_APPEARANCE}\n tone=\"muted\"\n icon={\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d=\"m14 9 3 3-3 3\" />\n </svg>\n }\n label={\n <span className=\"truncate whitespace-nowrap\">\n {switchToSidebarLabel}\n </span>\n }\n onClick={() => setNavigationMode(\"sidebar\")}\n className={cn(\n \"h-auto min-w-0 shrink px-3 py-2 text-sm font-medium text-[hsl(var(--muted-foreground))] shadow-none hover:border-[hsl(var(--input))]/70 hover:bg-[hsl(var(--muted))]/60 hover:text-[hsl(var(--foreground))]\",\n getHeadbarMenuRadiusClass(headbarLayout?.menuRadius),\n )}\n />\n </>\n ) : (\n headbarActions\n )\n }\n accountMenu={accountMenu}\n extra={renderHeadbarExtra}\n layout={headbarLayout}\n logo={logo}\n navItems={navItems}\n onNavigate={onNavigate}\n />\n ) : null;\n\n return (\n <AppLayout\n header={header}\n sidebar={sidebar}\n flush={flush}\n className={className}\n >\n {children}\n </AppLayout>\n );\n}\n","import type {\n AgentSessionCapabilities,\n AgentSessionEvent,\n AgentSessionViewModel,\n} from '@inf-monkeys-tech/monkeys';\n\ntype SessionEventType = AgentSessionEvent['eventType'];\nexport type AgentWorkbenchEventOf<Type extends SessionEventType> = Extract<\n AgentSessionEvent,\n { eventType: Type }\n>;\n\nconst EVENT_CAPABILITIES = {\n reasoning: 'reasoning',\n plan: 'plan',\n task: 'tasks',\n tool: 'tools',\n approval: 'approval',\n artifact: 'artifacts',\n usage: 'usage',\n} as const satisfies Partial<\n Record<SessionEventType, keyof AgentSessionCapabilities>\n>;\n\nexport interface AgentWorkbenchActivityModel {\n mode: AgentSessionViewModel['snapshot']['mode'];\n status: AgentSessionViewModel['status'];\n reasoning: AgentWorkbenchEventOf<'reasoning'>[];\n plans: AgentWorkbenchEventOf<'plan'>[];\n tasks: AgentWorkbenchEventOf<'task'>[];\n tools: AgentWorkbenchEventOf<'tool'>[];\n approvals: AgentWorkbenchEventOf<'approval'>[];\n artifacts: AgentWorkbenchEventOf<'artifact'>[];\n usage?: AgentWorkbenchEventOf<'usage'>;\n run?: AgentWorkbenchEventOf<'status'> & { resolvedDurationMs?: number };\n}\n\nfunction projectRun(events: AgentSessionEvent[]): AgentWorkbenchActivityModel['run'] {\n const statuses = events.filter(\n (event): event is AgentWorkbenchEventOf<'status'> => event.eventType === 'status',\n );\n const run = statuses.at(-1);\n if (!run) return undefined;\n if (run.payload.status !== 'stopped' || run.payload.durationMs !== undefined) return run;\n\n const runStatuses = run.runId\n ? statuses.filter((event) => event.runId === run.runId && event.sequence <= run.sequence)\n : statuses.filter((event) => event.sequence <= run.sequence);\n let previousStoppedIndex = -1;\n for (let index = runStatuses.length - 1; index >= 0; index -= 1) {\n const event = runStatuses[index];\n if (event.sequence < run.sequence && event.payload.status === 'stopped') {\n previousStoppedIndex = index;\n break;\n }\n }\n const started = runStatuses\n .slice(previousStoppedIndex + 1)\n .reverse()\n .find((event) => event.payload.status === 'running' || event.payload.status === 'queued');\n const startedAt = started?.payload.startedAt ?? started?.occurredAt;\n const stoppedAt = run.payload.stoppedAt ?? run.occurredAt;\n if (!startedAt || !stoppedAt) return run;\n const durationMs = Date.parse(stoppedAt) - Date.parse(startedAt);\n return Number.isFinite(durationMs) && durationMs >= 0\n ? { ...run, resolvedDurationMs: durationMs }\n : run;\n}\n\nfunction isVisible(\n event: AgentSessionEvent,\n capabilities: AgentSessionCapabilities,\n): boolean {\n const capability = EVENT_CAPABILITIES[\n event.eventType as keyof typeof EVENT_CAPABILITIES\n ];\n return capability ? capabilities[capability] === true : true;\n}\n\nfunction latestBy<Type extends SessionEventType>(\n events: AgentSessionEvent[],\n eventType: Type,\n key: (event: AgentWorkbenchEventOf<Type>) => string,\n): AgentWorkbenchEventOf<Type>[] {\n const latest = new Map<string, AgentWorkbenchEventOf<Type>>();\n for (const event of events) {\n if (event.eventType !== eventType) continue;\n const typedEvent = event as AgentWorkbenchEventOf<Type>;\n latest.set(key(typedEvent), typedEvent);\n }\n return [...latest.values()].sort(\n (left, right) => left.sequence - right.sequence,\n );\n}\n\nexport function createAgentWorkbenchActivityModel(\n viewModel: AgentSessionViewModel,\n): AgentWorkbenchActivityModel {\n const visibleEvents = viewModel.events.filter((event) =>\n isVisible(event, viewModel.snapshot.capabilities),\n );\n\n return {\n mode: viewModel.snapshot.mode,\n status: viewModel.status,\n reasoning: latestBy(\n visibleEvents,\n 'reasoning',\n (event) => event.payload.reasoningId,\n ),\n plans: latestBy(\n visibleEvents,\n 'plan',\n (event) => event.payload.planId,\n ),\n tasks: latestBy(\n visibleEvents,\n 'task',\n (event) => event.payload.taskId,\n ),\n tools: latestBy(\n visibleEvents,\n 'tool',\n (event) => event.payload.toolCallId,\n ),\n approvals: latestBy(\n visibleEvents,\n 'approval',\n (event) => event.payload.approvalId,\n ),\n artifacts: latestBy(\n visibleEvents,\n 'artifact',\n (event) => event.payload.artifactId,\n ),\n usage: [...visibleEvents]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'usage'> =>\n event.eventType === 'usage',\n ),\n run: projectRun(visibleEvents),\n };\n}\n","import { CheckCircle2, ChevronDown, Clock3, Loader2, TerminalSquare, XCircle } from 'lucide-react';\nimport { useState } from 'react';\n\nimport { useMonkeysLocaleMessages } from '../../provider';\nimport { cn } from '../layout';\nimport type { AgentWorkbenchEventOf } from './activity-model';\n\nexport interface AgentWorkbenchToolClassNames {\n root?: string;\n trigger?: string;\n content?: string;\n input?: string;\n output?: string;\n}\n\nexport interface AgentWorkbenchToolProps {\n event: AgentWorkbenchEventOf<'tool'>;\n expanded?: boolean;\n defaultExpanded?: boolean;\n className?: string;\n classNames?: AgentWorkbenchToolClassNames;\n onExpandedChange?: (expanded: boolean) => void;\n}\n\nfunction JsonValue({ value, className }: { value: unknown; className?: string }) {\n if (value === undefined) return null;\n const content = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return (\n <pre\n className={cn(\n 'max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted p-3 font-mono text-xs text-foreground',\n className,\n )}\n >\n {content}\n </pre>\n );\n}\n\nfunction ToolStatus({ status }: { status: AgentWorkbenchEventOf<'tool'>['payload']['status'] }) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.tool.status;\n const commonClassName = 'size-3.5 shrink-0';\n\n if (status === 'pending') {\n return <Clock3 className={commonClassName} aria-hidden=\"true\" />;\n }\n if (status === 'running') {\n return <Loader2 className={cn(commonClassName, 'animate-spin')} aria-hidden=\"true\" />;\n }\n if (status === 'completed') {\n return <CheckCircle2 className={cn(commonClassName, 'text-primary')} aria-hidden=\"true\" />;\n }\n return <XCircle className={cn(commonClassName, 'text-destructive-text')} aria-hidden=\"true\" />;\n}\n\nexport function AgentWorkbenchTool({\n event,\n expanded,\n defaultExpanded = event.payload.status === 'failed',\n className,\n classNames,\n onExpandedChange,\n}: AgentWorkbenchToolProps) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.tool;\n const [uncontrolledExpanded, setUncontrolledExpanded] = useState(defaultExpanded);\n const isControlled = expanded !== undefined;\n const isExpanded = expanded ?? uncontrolledExpanded;\n const status = event.payload.status;\n const setExpanded = (nextExpanded: boolean) => {\n if (!isControlled) setUncontrolledExpanded(nextExpanded);\n onExpandedChange?.(nextExpanded);\n };\n\n return (\n <details\n open={isExpanded}\n className={cn(\n 'group rounded-lg border border-border bg-card text-card-foreground',\n classNames?.root,\n className,\n )}\n data-tool-status={status}\n >\n <summary\n className={cn(\n 'flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden',\n classNames?.trigger,\n )}\n onClick={(event) => {\n event.preventDefault();\n setExpanded(!isExpanded);\n }}\n >\n <TerminalSquare className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate font-medium\">{event.payload.toolName}</span>\n <span className=\"inline-flex shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground\">\n <ToolStatus status={status} />\n {messages.status[status]}\n </span>\n <ChevronDown\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div className={cn('space-y-3 border-t border-border px-3 py-3 text-sm', classNames?.content)}>\n {event.payload.input !== undefined ? (\n <div className=\"space-y-1.5\">\n <div className=\"text-xs font-medium text-muted-foreground\">{messages.input}</div>\n <JsonValue value={event.payload.input} className={classNames?.input} />\n </div>\n ) : null}\n {event.payload.output !== undefined ? (\n <div className=\"space-y-1.5\">\n <div className=\"text-xs font-medium text-muted-foreground\">{messages.output}</div>\n <JsonValue value={event.payload.output} className={classNames?.output} />\n </div>\n ) : null}\n {event.payload.error ? (\n <p className=\"text-sm text-destructive-text\" role=\"alert\">\n {event.payload.error}\n </p>\n ) : null}\n </div>\n </details>\n );\n}\n","import type { AgentSessionViewModel } from '@inf-monkeys-tech/monkeys';\nimport {\n Check,\n CheckCircle2,\n ChevronDown,\n Circle,\n CircleStop,\n Clock3,\n Download,\n FileOutput,\n Loader2,\n X,\n XCircle,\n} from 'lucide-react';\nimport type { ComponentType, ReactNode } from 'react';\n\nimport { useMonkeysLocaleMessages } from '../../provider';\nimport { cn } from '../layout';\nimport {\n createAgentWorkbenchActivityModel,\n type AgentWorkbenchEventOf,\n} from './activity-model';\nimport { AgentWorkbenchTool } from './AgentWorkbenchTool';\n\nexport interface AgentWorkbenchApprovalIntent {\n approvalId: string;\n approved: boolean;\n}\n\nexport interface AgentWorkbenchArtifactIntent {\n artifactId: string;\n name: string;\n url: string;\n}\n\nexport interface AgentWorkbenchActivityClassNames {\n root?: string;\n item?: string;\n trigger?: string;\n content?: string;\n approval?: string;\n artifact?: string;\n usage?: string;\n}\n\nexport interface AgentWorkbenchActivityProps {\n viewModel?: AgentSessionViewModel;\n hiddenToolCallIds?: ReadonlySet<string>;\n hideReasoning?: boolean;\n hideStoppedRun?: boolean;\n className?: string;\n classNames?: AgentWorkbenchActivityClassNames;\n onApprovalDecision?: (intent: AgentWorkbenchApprovalIntent) => void;\n onArtifactOpen?: (intent: AgentWorkbenchArtifactIntent) => void;\n}\n\ninterface ActivityDetailsProps {\n icon: ComponentType<{ className?: string }>;\n title: ReactNode;\n open?: boolean;\n streaming?: boolean;\n className?: string;\n triggerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n}\n\nfunction ActivityDetails({\n icon: Icon,\n title,\n open,\n streaming,\n className,\n triggerClassName,\n contentClassName,\n children,\n}: ActivityDetailsProps) {\n return (\n <details\n className={cn(\n 'group rounded-lg border border-border bg-card text-card-foreground',\n className,\n )}\n open={open}\n >\n <summary\n className={cn(\n 'flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 text-sm font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden',\n triggerClassName,\n )}\n >\n {streaming ? (\n <Loader2 className=\"size-4 shrink-0 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <Icon className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n )}\n <span className=\"min-w-0 flex-1 truncate\">{title}</span>\n <ChevronDown\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div\n className={cn(\n 'border-t border-border px-3 py-3 text-sm',\n contentClassName,\n )}\n >\n {children}\n </div>\n </details>\n );\n}\n\nfunction StatusIcon({ status }: { status: string }) {\n if (status === 'completed' || status === 'passed') {\n return <CheckCircle2 className=\"size-4 text-primary\" aria-hidden=\"true\" />;\n }\n if (status === 'failed') {\n return <XCircle className=\"size-4 text-destructive-text\" aria-hidden=\"true\" />;\n }\n if (status === 'running') {\n return <Clock3 className=\"size-4 animate-pulse\" aria-hidden=\"true\" />;\n }\n return <Circle className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />;\n}\n\nfunction JsonValue({ value }: { value: unknown }) {\n if (value === undefined) return null;\n const content =\n typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return (\n <pre className=\"max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted p-3 font-mono text-xs text-foreground\">\n {content}\n </pre>\n );\n}\n\nfunction formatDuration(durationMs: number): string {\n if (durationMs < 1_000) return '<1s';\n const totalSeconds = Math.floor(durationMs / 1_000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;\n}\n\nfunction RunStatus({\n event,\n}: {\n event: AgentWorkbenchEventOf<'status'> & { resolvedDurationMs?: number };\n}) {\n const messages = useMonkeysLocaleMessages().agentWorkbench;\n const status = event.payload.status;\n if (status !== 'stopping' && status !== 'stopped') return null;\n\n return (\n <div\n className=\"flex items-center gap-2 text-sm text-muted-foreground\"\n role=\"status\"\n >\n {status === 'stopping' ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <CircleStop className=\"size-4\" aria-hidden=\"true\" />\n )}\n <span>\n {status === 'stopping'\n ? messages.run.stopping\n : messages.run.stoppedAfter({\n duration: formatDuration(\n event.payload.durationMs ?? event.resolvedDurationMs ?? 0,\n ),\n })}\n </span>\n </div>\n );\n}\n\nexport function AgentWorkbenchActivity({\n viewModel,\n hiddenToolCallIds,\n hideReasoning = false,\n hideStoppedRun = false,\n className,\n classNames,\n onApprovalDecision,\n onArtifactOpen,\n}: AgentWorkbenchActivityProps) {\n const messages = useMonkeysLocaleMessages().agentWorkbench;\n if (!viewModel) return null;\n\n const activity = createAgentWorkbenchActivityModel(viewModel);\n const reasoning = hideReasoning ? [] : activity.reasoning;\n const tools = activity.tools.filter(\n (event) => !hiddenToolCallIds?.has(event.payload.toolCallId),\n );\n const approvals = activity.approvals.filter(\n (event) =>\n !event.payload.toolCallId ||\n !hiddenToolCallIds?.has(event.payload.toolCallId),\n );\n const usage = activity.usage?.payload;\n const contextWindow =\n typeof usage?.contextWindow === 'number' && usage.contextWindow > 0\n ? usage.contextWindow\n : undefined;\n const showRun =\n activity.run?.payload.status === 'stopping' ||\n (activity.run?.payload.status === 'stopped' && !hideStoppedRun);\n const hasActivity =\n reasoning.length > 0 ||\n activity.plans.length > 0 ||\n activity.tasks.length > 0 ||\n tools.length > 0 ||\n approvals.length > 0 ||\n activity.artifacts.length > 0 ||\n showRun ||\n contextWindow !== undefined;\n if (!hasActivity) return null;\n\n return (\n <section\n className={cn('space-y-3', classNames?.root, className)}\n aria-label={messages.label}\n data-agent-workbench-mode={activity.mode}\n data-agent-workbench-status={activity.status}\n >\n {reasoning.map((event) => (\n <ActivityDetails\n key={event.payload.reasoningId}\n icon={Circle}\n title={messages.reasoning}\n open={event.payload.status === 'streaming'}\n streaming={event.payload.status === 'streaming'}\n className={classNames?.item}\n triggerClassName={classNames?.trigger}\n contentClassName={classNames?.content}\n >\n <div className=\"whitespace-pre-wrap text-muted-foreground\">\n {event.payload.text}\n </div>\n </ActivityDetails>\n ))}\n\n {activity.plans.map((event) => (\n <ActivityDetails\n key={event.payload.planId}\n icon={Circle}\n title={event.payload.title || messages.plan}\n open={event.payload.status === 'running'}\n streaming={event.payload.status === 'running'}\n className={classNames?.item}\n triggerClassName={classNames?.trigger}\n contentClassName={classNames?.content}\n >\n <ol className=\"space-y-2\">\n {event.payload.steps.map((step) => (\n <li key={step.id} className=\"flex items-center gap-2\">\n <StatusIcon status={step.status} />\n <span>{step.title}</span>\n </li>\n ))}\n </ol>\n </ActivityDetails>\n ))}\n\n {activity.tasks.map((event) => (\n <ActivityDetails\n key={event.payload.taskId}\n icon={Circle}\n title={event.payload.title}\n open={event.payload.status === 'running'}\n streaming={event.payload.status === 'running'}\n className={classNames?.item}\n triggerClassName={classNames?.trigger}\n contentClassName={classNames?.content}\n >\n <div className=\"flex items-start gap-2\">\n <StatusIcon status={event.payload.status} />\n <span className=\"whitespace-pre-wrap text-muted-foreground\">\n {event.payload.detail || messages.taskNoDetail}\n </span>\n </div>\n </ActivityDetails>\n ))}\n\n {tools.map((event) => (\n <AgentWorkbenchTool\n key={event.payload.toolCallId}\n event={event}\n defaultExpanded={event.payload.status === 'failed'}\n classNames={{\n root: classNames?.item,\n trigger: classNames?.trigger,\n content: classNames?.content,\n }}\n />\n ))}\n\n {approvals.map((event) => {\n const requested = event.payload.status === 'requested';\n const approved = event.payload.status === 'approved';\n return (\n <article\n key={event.payload.approvalId}\n className={cn(\n 'rounded-lg border border-border bg-card p-3 text-card-foreground',\n classNames?.approval,\n )}\n >\n <div className=\"flex items-start gap-3\">\n {requested ? (\n <Clock3 className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n ) : approved ? (\n <Check className=\"mt-0.5 size-4 shrink-0 text-primary\" aria-hidden=\"true\" />\n ) : (\n <X className=\"mt-0.5 size-4 shrink-0 text-destructive-text\" aria-hidden=\"true\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"text-sm font-medium\">{event.payload.title}</h3>\n {event.payload.description ? (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {event.payload.description}\n </p>\n ) : null}\n {event.payload.requestedAction !== undefined ? (\n <div className=\"mt-3\">\n <JsonValue value={event.payload.requestedAction} />\n </div>\n ) : null}\n {requested ? (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <button\n type=\"button\"\n className=\"rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground outline-none hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={!onApprovalDecision}\n onClick={() =>\n onApprovalDecision?.({\n approvalId: event.payload.approvalId,\n approved: true,\n })\n }\n >\n {messages.approval.approve}\n </button>\n <button\n type=\"button\"\n className=\"rounded-md border border-border bg-background px-3 py-1.5 text-sm font-medium text-foreground outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n disabled={!onApprovalDecision}\n onClick={() =>\n onApprovalDecision?.({\n approvalId: event.payload.approvalId,\n approved: false,\n })\n }\n >\n {messages.approval.reject}\n </button>\n </div>\n ) : (\n <p className=\"mt-2 text-xs text-muted-foreground\">\n {approved\n ? messages.approval.approved\n : messages.approval.rejected}\n </p>\n )}\n </div>\n </div>\n </article>\n );\n })}\n\n {activity.artifacts.map((event) => {\n const canOpen = Boolean(event.payload.url && onArtifactOpen);\n return (\n <article\n key={event.payload.artifactId}\n className={cn(\n 'flex items-center gap-3 rounded-lg border border-border bg-card p-3 text-card-foreground',\n classNames?.artifact,\n )}\n >\n <FileOutput className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium\">\n {event.payload.name}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {messages.artifact[event.payload.status]}\n </div>\n </div>\n {event.payload.url ? (\n <button\n type=\"button\"\n className=\"rounded-md p-2 text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={messages.artifact.open({\n name: event.payload.name,\n })}\n disabled={!canOpen}\n onClick={() => {\n if (!event.payload.url) return;\n onArtifactOpen?.({\n artifactId: event.payload.artifactId,\n name: event.payload.name,\n url: event.payload.url,\n });\n }}\n >\n <Download className=\"size-4\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </article>\n );\n })}\n\n {showRun && activity.run ? <RunStatus event={activity.run} /> : null}\n\n {usage && contextWindow !== undefined ? (\n <div\n className={cn('flex justify-end', classNames?.usage)}\n aria-label={messages.usage.label}\n >\n <span className=\"rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-muted-foreground\">\n {messages.usage.context({\n used: usage.contextTokens ?? usage.totalTokens ?? 0,\n total: contextWindow,\n })}\n </span>\n </div>\n ) : null}\n </section>\n );\n}\n","import type {\n AgentSessionCapabilities,\n AgentSessionEvent,\n AgentSessionViewModel,\n} from '@inf-monkeys-tech/monkeys';\n\nimport type { AgentWorkbenchEventOf } from './activity-model';\n\nconst WORKSPACE_CAPABILITIES = {\n diff: 'diff',\n 'workspace-file': 'workspaceFiles',\n terminal: 'terminal',\n 'test-result': 'testResults',\n artifact: 'artifacts',\n} as const satisfies Partial<\n Record<AgentSessionEvent['eventType'], keyof AgentSessionCapabilities>\n>;\n\nexport interface AgentWorkbenchTerminalModel {\n terminalId: string;\n stdin: string;\n stdout: string;\n stderr: string;\n status: string;\n exitCode?: number;\n sequence: number;\n}\n\nexport interface AgentWorkbenchDetailsModel {\n mode: AgentSessionViewModel['snapshot']['mode'];\n status: AgentSessionViewModel['status'];\n sessionId: string;\n resumable: boolean;\n summary?: AgentWorkbenchEventOf<'summary'>;\n error?: AgentWorkbenchEventOf<'error'>;\n run?: AgentWorkbenchEventOf<'status'>;\n workspace: {\n diffs: AgentWorkbenchEventOf<'diff'>[];\n files: AgentWorkbenchEventOf<'workspace-file'>[];\n terminals: AgentWorkbenchTerminalModel[];\n tests: AgentWorkbenchEventOf<'test-result'>[];\n artifacts: AgentWorkbenchEventOf<'artifact'>[];\n };\n}\n\nfunction latestBy<Type extends AgentSessionEvent['eventType']>(\n events: AgentSessionEvent[],\n eventType: Type,\n key: (event: AgentWorkbenchEventOf<Type>) => string,\n): AgentWorkbenchEventOf<Type>[] {\n const latest = new Map<string, AgentWorkbenchEventOf<Type>>();\n for (const event of events) {\n if (event.eventType !== eventType) continue;\n const typedEvent = event as AgentWorkbenchEventOf<Type>;\n latest.set(key(typedEvent), typedEvent);\n }\n return [...latest.values()].sort(\n (left, right) => left.sequence - right.sequence,\n );\n}\n\nfunction projectTerminals(\n events: AgentWorkbenchEventOf<'terminal'>[],\n): AgentWorkbenchTerminalModel[] {\n const terminals = new Map<string, AgentWorkbenchTerminalModel>();\n for (const event of events) {\n const current = terminals.get(event.payload.terminalId) ?? {\n terminalId: event.payload.terminalId,\n stdin: '',\n stdout: '',\n stderr: '',\n status: '',\n sequence: event.sequence,\n };\n const stream = event.payload.stream;\n terminals.set(event.payload.terminalId, {\n ...current,\n ...(stream === 'status'\n ? { status: event.payload.chunk }\n : { [stream]: `${current[stream]}${event.payload.chunk}` }),\n ...(event.payload.exitCode === undefined\n ? {}\n : { exitCode: event.payload.exitCode }),\n sequence: event.sequence,\n });\n }\n return [...terminals.values()].sort(\n (left, right) => left.sequence - right.sequence,\n );\n}\n\nexport function createAgentWorkbenchDetailsModel(\n viewModel: AgentSessionViewModel,\n): AgentWorkbenchDetailsModel {\n const capabilities = viewModel.snapshot.capabilities;\n const workspaceEvents = viewModel.events.filter((event) => {\n const capability = WORKSPACE_CAPABILITIES[\n event.eventType as keyof typeof WORKSPACE_CAPABILITIES\n ];\n return capability ? capabilities[capability] === true : false;\n });\n const run = [...viewModel.events]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'status'> =>\n event.eventType === 'status',\n );\n const currentRunId = run?.runId;\n const summary = [...viewModel.events]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'summary'> =>\n event.eventType === 'summary' &&\n capabilities.summary === true &&\n (!currentRunId || event.runId === currentRunId),\n );\n\n return {\n mode: viewModel.snapshot.mode,\n status: viewModel.status,\n sessionId: viewModel.sessionId,\n resumable: capabilities.resume === true && viewModel.resumable,\n summary,\n error: [...viewModel.events]\n .reverse()\n .find(\n (event): event is AgentWorkbenchEventOf<'error'> =>\n event.eventType === 'error',\n ),\n run,\n workspace: {\n diffs: latestBy(workspaceEvents, 'diff', (event) => event.payload.path),\n files: latestBy(\n workspaceEvents,\n 'workspace-file',\n (event) => event.payload.path,\n ),\n terminals: projectTerminals(\n workspaceEvents.filter(\n (event): event is AgentWorkbenchEventOf<'terminal'> =>\n event.eventType === 'terminal',\n ),\n ),\n tests: latestBy(\n workspaceEvents,\n 'test-result',\n (event) => event.payload.testId,\n ),\n artifacts: latestBy(\n workspaceEvents,\n 'artifact',\n (event) => event.payload.artifactId,\n ),\n },\n };\n}\n","import type { AgentSessionViewModel } from '@inf-monkeys-tech/monkeys';\nimport {\n AlertCircle,\n CheckCircle2,\n ChevronDown,\n Circle,\n Clock3,\n Copy,\n FileCode2,\n FileOutput,\n Files,\n RefreshCw,\n RotateCcw,\n TerminalSquare,\n TestTube2,\n X,\n XCircle,\n} from 'lucide-react';\nimport type { ComponentType, KeyboardEvent, ReactNode } from 'react';\n\nimport { useMonkeysLocale, useMonkeysLocaleMessages } from '../../provider';\nimport { cn } from '../layout';\nimport {\n createAgentWorkbenchDetailsModel,\n type AgentWorkbenchDetailsModel,\n} from './details-model';\n\nexport type AgentWorkbenchDetailsTab = 'summary' | 'workspace';\nexport type AgentWorkbenchDetailsState =\n | 'ready'\n | 'loading'\n | 'empty'\n | 'error';\n\nexport type AgentWorkbenchDetailsIntent =\n | { type: 'close' }\n | { type: 'copy-summary'; summaryId: string; text: string }\n | { type: 'retry'; eventId: string }\n | { type: 'retry-summary'; eventId: string }\n | { type: 'resume'; sessionId: string };\n\nexport interface AgentWorkbenchTaskDetailsClassNames {\n root?: string;\n header?: string;\n tabs?: string;\n body?: string;\n section?: string;\n code?: string;\n}\n\nexport interface AgentWorkbenchTaskDetailsProps {\n viewModel?: AgentSessionViewModel;\n state?: AgentWorkbenchDetailsState;\n activeTab?: AgentWorkbenchDetailsTab;\n className?: string;\n classNames?: AgentWorkbenchTaskDetailsClassNames;\n onActiveTabChange?: (tab: AgentWorkbenchDetailsTab) => void;\n onIntent?: (intent: AgentWorkbenchDetailsIntent) => void;\n}\n\nfunction formatDuration(durationMs: number | undefined): string {\n if (durationMs === undefined) return '-';\n const seconds = Math.max(0, Math.round(durationMs / 1_000));\n if (seconds < 60) return `${seconds}s`;\n return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;\n}\n\nfunction formatDate(value: string | undefined, locale: string): string {\n if (!value) return '-';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return '-';\n return new Intl.DateTimeFormat(locale, {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n\nfunction Count({ value }: { value: number }) {\n return (\n <span className=\"rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-semibold text-muted-foreground\">\n {value}\n </span>\n );\n}\n\nfunction DetailsSection({\n title,\n count,\n icon: Icon,\n className,\n children,\n}: {\n title: string;\n count: number;\n icon: ComponentType<{ className?: string }>;\n className?: string;\n children: ReactNode;\n}) {\n if (count === 0) return null;\n return (\n <details\n className={cn(\n 'group rounded-lg border border-border bg-card text-card-foreground',\n className,\n )}\n open\n >\n <summary className=\"flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 text-sm font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden\">\n <Icon className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate\">{title}</span>\n <Count value={count} />\n <ChevronDown\n className=\"size-4 text-muted-foreground transition-transform group-open:rotate-180\"\n aria-hidden=\"true\"\n />\n </summary>\n <div className=\"border-t border-border p-3\">{children}</div>\n </details>\n );\n}\n\nfunction StatusIcon({ status }: { status: string }) {\n if (status === 'completed' || status === 'passed') {\n return <CheckCircle2 className=\"size-4 text-primary\" aria-hidden=\"true\" />;\n }\n if (status === 'failed') {\n return <XCircle className=\"size-4 text-destructive-text\" aria-hidden=\"true\" />;\n }\n if (status === 'running') {\n return <Clock3 className=\"size-4 animate-pulse\" aria-hidden=\"true\" />;\n }\n return <Circle className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />;\n}\n\nfunction StateContent({ state }: { state: Exclude<AgentWorkbenchDetailsState, 'ready'> }) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details;\n const error = state === 'error';\n return (\n <div\n className=\"flex min-h-48 flex-col items-center justify-center gap-2 px-6 text-center\"\n role={error ? 'alert' : state === 'loading' ? 'status' : undefined}\n aria-busy={state === 'loading' || undefined}\n >\n {state === 'loading' ? (\n <RefreshCw className=\"size-5 animate-spin text-muted-foreground\" aria-hidden=\"true\" />\n ) : error ? (\n <AlertCircle className=\"size-5 text-destructive-text\" aria-hidden=\"true\" />\n ) : (\n <FileOutput className=\"size-5 text-muted-foreground\" aria-hidden=\"true\" />\n )}\n <div className=\"text-sm font-medium\">{messages.state[state].title}</div>\n <div className=\"text-xs text-muted-foreground\">\n {messages.state[state].description}\n </div>\n </div>\n );\n}\n\nfunction SummaryPanel({\n model,\n onIntent,\n}: {\n model: AgentWorkbenchDetailsModel;\n onIntent?: (intent: AgentWorkbenchDetailsIntent) => void;\n}) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details;\n const locale = useMonkeysLocale().locale;\n const summary = model.summary;\n const run = model.run?.payload;\n const error = model.error;\n const retryable = model.status === 'failed' && error?.payload.retryable;\n const canResume =\n model.resumable && ['stopped', 'completed', 'failed'].includes(model.status);\n\n return (\n <div className=\"space-y-3\">\n <section className=\"rounded-lg border border-border bg-muted/40 p-3\">\n <div className=\"flex items-center gap-2\">\n <StatusIcon status={model.status} />\n <span className=\"text-sm font-semibold\">\n {messages.status[model.status]}\n </span>\n </div>\n <dl className=\"mt-3 grid grid-cols-2 gap-3 text-xs\">\n <div>\n <dt className=\"text-muted-foreground\">{messages.duration}</dt>\n <dd className=\"mt-0.5 font-medium\">\n {formatDuration(run?.durationMs)}\n </dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground\">{messages.updated}</dt>\n <dd className=\"mt-0.5 truncate font-medium\">\n {formatDate(\n run?.stoppedAt ?? run?.completedAt ?? run?.failedAt,\n locale,\n )}\n </dd>\n </div>\n </dl>\n {error ? (\n <div className=\"mt-3 rounded-md border border-destructive/30 bg-destructive/5 p-2.5 text-sm text-destructive-text\" role=\"alert\">\n {error.payload.message}\n </div>\n ) : null}\n {retryable || canResume ? (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n {retryable ? (\n <button\n type=\"button\"\n className=\"rounded-md border border-border bg-background px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={!onIntent}\n onClick={() => onIntent?.({ type: 'retry', eventId: error.eventId })}\n >\n {messages.actions.retry}\n </button>\n ) : null}\n {canResume ? (\n <button\n type=\"button\"\n className=\"rounded-md bg-primary px-2.5 py-1.5 text-xs font-medium text-primary-foreground outline-none hover:bg-primary/90 focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={!onIntent}\n onClick={() =>\n onIntent?.({ type: 'resume', sessionId: model.sessionId })\n }\n >\n {messages.actions.resume}\n </button>\n ) : null}\n </div>\n ) : null}\n </section>\n\n <section className=\"rounded-lg border border-border bg-card p-3 text-card-foreground\">\n <div className=\"flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">{messages.summary}</h3>\n {summary?.payload.text ? (\n <button\n type=\"button\"\n className=\"rounded-md p-1.5 text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={messages.actions.copySummary}\n disabled={!onIntent}\n onClick={() =>\n onIntent?.({\n type: 'copy-summary',\n summaryId: summary.payload.summaryId,\n text: summary.payload.text,\n })\n }\n >\n <Copy className=\"size-4\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n {summary?.payload.status === 'failed' ? (\n <div className=\"mt-3 space-y-2\">\n <p className=\"text-sm text-destructive-text\" role=\"alert\">\n {messages.summaryFailed}\n </p>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n disabled={!onIntent}\n onClick={() =>\n onIntent?.({ type: 'retry-summary', eventId: summary.eventId })\n }\n >\n <RotateCcw className=\"size-3.5\" aria-hidden=\"true\" />\n {messages.actions.retrySummary}\n </button>\n </div>\n ) : summary?.payload.text ? (\n <div className=\"mt-3 space-y-3 text-sm\">\n <p className=\"whitespace-pre-wrap text-muted-foreground\">\n {summary.payload.text}\n </p>\n {summary.payload.highlights.length > 0 ? (\n <div>\n <h4 className=\"text-xs font-medium\">{messages.highlights}</h4>\n <ul className=\"mt-1 list-disc space-y-1 pl-5 text-muted-foreground\">\n {summary.payload.highlights.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n </div>\n ) : null}\n {summary.payload.pendingItems.length > 0 ? (\n <div>\n <h4 className=\"text-xs font-medium\">{messages.pendingItems}</h4>\n <ul className=\"mt-1 list-disc space-y-1 pl-5 text-muted-foreground\">\n {summary.payload.pendingItems.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n ) : (\n <p className=\"mt-3 text-sm text-muted-foreground\">\n {messages.summaryEmpty}\n </p>\n )}\n </section>\n </div>\n );\n}\n\nfunction WorkspacePanel({\n model,\n sectionClassName,\n codeClassName,\n}: {\n model: AgentWorkbenchDetailsModel;\n sectionClassName?: string;\n codeClassName?: string;\n}) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details.workspace;\n const workspace = model.workspace;\n return (\n <div className=\"space-y-3\">\n <DetailsSection\n title={messages.diffs}\n count={workspace.diffs.length}\n icon={FileCode2}\n className={sectionClassName}\n >\n <div className=\"space-y-3\">\n {workspace.diffs.map((event) => (\n <div key={event.payload.path} className=\"min-w-0\">\n <div className=\"flex items-center justify-between gap-2 text-xs\">\n <span className=\"truncate font-medium\">{event.payload.path}</span>\n <span className=\"shrink-0 text-muted-foreground\">\n {messages.diffStatus[event.payload.status]}\n </span>\n </div>\n {event.payload.patch ? (\n <pre className={cn('mt-2 max-h-72 overflow-auto whitespace-pre-wrap rounded-md bg-muted p-3 font-mono text-xs', codeClassName)}>\n {event.payload.patch}\n </pre>\n ) : null}\n </div>\n ))}\n </div>\n </DetailsSection>\n\n <DetailsSection\n title={messages.files}\n count={workspace.files.length}\n icon={Files}\n className={sectionClassName}\n >\n <ul className=\"space-y-2 text-xs\">\n {workspace.files.map((event) => (\n <li key={event.payload.path} className=\"flex items-center gap-2\">\n <FileOutput className=\"size-3.5 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate\">{event.payload.path}</span>\n <span className=\"text-muted-foreground\">\n {messages.fileOperation[event.payload.operation]}\n </span>\n </li>\n ))}\n </ul>\n </DetailsSection>\n\n <DetailsSection\n title={messages.terminals}\n count={workspace.terminals.length}\n icon={TerminalSquare}\n className={sectionClassName}\n >\n <div className=\"space-y-3\">\n {workspace.terminals.map((terminal) => (\n <div key={terminal.terminalId}>\n <div className=\"flex justify-between gap-2 text-xs font-medium\">\n <span>{terminal.terminalId}</span>\n <span className=\"text-muted-foreground\">\n {terminal.exitCode === undefined\n ? terminal.status\n : messages.exitCode({ code: terminal.exitCode })}\n </span>\n </div>\n <pre className={cn('mt-2 max-h-72 overflow-auto whitespace-pre-wrap rounded-md bg-muted p-3 font-mono text-xs', codeClassName)}>\n {[terminal.stdin, terminal.stdout, terminal.stderr]\n .filter(Boolean)\n .join('\\n')}\n </pre>\n </div>\n ))}\n </div>\n </DetailsSection>\n\n <DetailsSection\n title={messages.tests}\n count={workspace.tests.length}\n icon={TestTube2}\n className={sectionClassName}\n >\n <ul className=\"space-y-2 text-xs\">\n {workspace.tests.map((event) => (\n <li key={event.payload.testId}>\n <div className=\"flex items-center gap-2\">\n <StatusIcon status={event.payload.status} />\n <span className=\"min-w-0 flex-1 truncate\">{event.payload.name}</span>\n {event.payload.durationMs === undefined ? null : (\n <span className=\"text-muted-foreground\">\n {formatDuration(event.payload.durationMs)}\n </span>\n )}\n </div>\n {event.payload.output ? (\n <pre className={cn('mt-2 max-h-48 overflow-auto whitespace-pre-wrap rounded-md bg-muted p-3 font-mono text-xs', codeClassName)}>\n {event.payload.output}\n </pre>\n ) : null}\n </li>\n ))}\n </ul>\n </DetailsSection>\n\n <DetailsSection\n title={messages.artifacts}\n count={workspace.artifacts.length}\n icon={FileOutput}\n className={sectionClassName}\n >\n <ul className=\"space-y-2 text-xs\">\n {workspace.artifacts.map((event) => (\n <li key={event.payload.artifactId} className=\"flex items-center gap-2\">\n <FileOutput className=\"size-3.5 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1 truncate\">{event.payload.name}</span>\n <span className=\"text-muted-foreground\">\n {event.payload.kind}\n </span>\n </li>\n ))}\n </ul>\n </DetailsSection>\n </div>\n );\n}\n\nexport function AgentWorkbenchTaskDetails({\n viewModel,\n state = 'ready',\n activeTab = 'summary',\n className,\n classNames,\n onActiveTabChange,\n onIntent,\n}: AgentWorkbenchTaskDetailsProps) {\n const messages = useMonkeysLocaleMessages().agentWorkbench.details;\n if (state !== 'ready') {\n return (\n <aside className={cn('flex h-full min-h-0 flex-col border-l border-border bg-background', classNames?.root, className)}>\n <StateContent state={state} />\n </aside>\n );\n }\n if (!viewModel) {\n return (\n <aside className={cn('flex h-full min-h-0 flex-col border-l border-border bg-background', classNames?.root, className)}>\n <StateContent state=\"empty\" />\n </aside>\n );\n }\n\n const model = createAgentWorkbenchDetailsModel(viewModel);\n const workspaceCount = Object.values(model.workspace).reduce(\n (total, items) => total + items.length,\n 0,\n );\n const workspaceAvailable = workspaceCount > 0;\n const resolvedTab = activeTab === 'workspace' && !workspaceAvailable ? 'summary' : activeTab;\n const tabs: Array<{ id: AgentWorkbenchDetailsTab; label: string; count: number }> = [\n { id: 'summary', label: messages.tabs.summary, count: model.summary ? 1 : 0 },\n ...(workspaceAvailable\n ? [{ id: 'workspace' as const, label: messages.tabs.workspace, count: workspaceCount }]\n : []),\n ];\n const tabId = (tab: AgentWorkbenchDetailsTab) =>\n `agent-workbench-details-${viewModel.sessionId}-${tab}`.replace(\n /[^a-zA-Z0-9_-]/g,\n '-',\n );\n const onTabKeyDown = (\n event: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;\n event.preventDefault();\n const nextIndex =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? tabs.length - 1\n : (index + (event.key === 'ArrowRight' ? 1 : -1) + tabs.length) %\n tabs.length;\n onActiveTabChange?.(tabs[nextIndex].id);\n };\n\n return (\n <aside\n className={cn(\n 'flex h-full min-h-0 min-w-0 flex-col border-l border-border bg-background text-foreground',\n classNames?.root,\n className,\n )}\n data-agent-workbench-mode={model.mode}\n >\n <header className={cn('flex shrink-0 items-center gap-2 border-b border-border px-4 py-3', classNames?.header)}>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"truncate text-sm font-semibold\">{messages.title}</h2>\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {messages.description}\n </p>\n </div>\n {onIntent ? (\n <button\n type=\"button\"\n className=\"rounded-md p-2 text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={messages.actions.close}\n onClick={() => onIntent({ type: 'close' })}\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </header>\n\n <div className={cn('flex shrink-0 gap-1 border-b border-border px-3 py-2', classNames?.tabs)} role=\"tablist\" aria-label={messages.tabs.label}>\n {tabs.map((tab, index) => (\n <button\n key={tab.id}\n id={tabId(tab.id)}\n type=\"button\"\n role=\"tab\"\n aria-selected={resolvedTab === tab.id}\n aria-controls={`${tabId(tab.id)}-panel`}\n tabIndex={resolvedTab === tab.id ? 0 : -1}\n className={cn(\n 'inline-flex min-w-0 flex-1 items-center justify-center gap-1 rounded-md px-2 py-1.5 text-xs font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring',\n resolvedTab === tab.id\n ? 'bg-primary/10 text-primary'\n : 'text-muted-foreground hover:bg-muted hover:text-foreground',\n )}\n onClick={() => onActiveTabChange?.(tab.id)}\n onKeyDown={(event) => onTabKeyDown(event, index)}\n >\n <span className=\"truncate\">{tab.label}</span>\n <Count value={tab.count} />\n </button>\n ))}\n </div>\n\n <div\n id={`${tabId(resolvedTab)}-panel`}\n role=\"tabpanel\"\n aria-labelledby={tabId(resolvedTab)}\n tabIndex={0}\n className={cn('min-h-0 flex-1 overflow-y-auto p-3 outline-none', classNames?.body)}\n >\n {resolvedTab === 'summary' ? (\n <SummaryPanel model={model} onIntent={onIntent} />\n ) : (\n <WorkspacePanel\n model={model}\n sectionClassName={classNames?.section}\n codeClassName={classNames?.code}\n />\n )}\n </div>\n </aside>\n );\n}\n"]}
|