@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.2
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/CHANGELOG.md +20 -0
- package/README.md +7 -0
- package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-637HQUXD.js} +7 -7
- package/dist/AgentMetricChart-4FYECRIN.js +15 -0
- package/dist/{AgentOverview-EEBHJC32.js → AgentOverview-3FJ5EE6N.js} +7 -7
- package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-VELWUYPR.js} +18 -9
- package/dist/AgentSessionEventTimeline-VELWUYPR.js.map +1 -0
- package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-CUKETHWM.js} +140 -53
- package/dist/AgentSessionEventTimelineChart-CUKETHWM.js.map +1 -0
- package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-T7MOGOTZ.js} +8 -8
- package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-ESZ2RSRG.js} +18 -22
- package/dist/ConnectorSettings-ESZ2RSRG.js.map +1 -0
- package/dist/{DockLayout-LM4AFMFY.js → DockLayout-NLFNU6F2.js} +10 -10
- package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-PR3SMKA6.js} +12 -12
- package/dist/DrawerLayout-PR3SMKA6.js.map +1 -0
- package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-LYW64IRR.js} +19 -25
- package/dist/ModelSettings-LYW64IRR.js.map +1 -0
- package/dist/OpenUiFenceBlock-JEPNPJ7U.js +9 -0
- package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-DF64LHYI.js} +15 -19
- package/dist/SandboxSettings-DF64LHYI.js.map +1 -0
- package/dist/SchedulesPage-WQU4H25F.js +15 -0
- package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-LSXK2VN4.js} +8 -8
- package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-B22IAV2W.js} +19 -9
- package/dist/ShellRouteSync-B22IAV2W.js.map +1 -0
- package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-XW6LXB7R.js} +17 -16
- package/dist/SidebarLayout-XW6LXB7R.js.map +1 -0
- package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-64VXUO6J.js} +13 -16
- package/dist/SkillSettings-64VXUO6J.js.map +1 -0
- package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-3TSLV22Q.js} +9 -9
- package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-Q5P7PYSJ.js} +10 -10
- package/dist/{chunk-ZKNUMH2M.js → chunk-5I2COQNL.js} +2 -2
- package/dist/chunk-BWHOZFIV.js +587 -0
- package/dist/chunk-BWHOZFIV.js.map +1 -0
- package/dist/{chunk-U7KURWW3.js → chunk-FQK2XVVE.js} +66 -26
- package/dist/chunk-FQK2XVVE.js.map +1 -0
- package/dist/{chunk-M62XY4NC.js → chunk-G2TUAD65.js} +6 -6
- package/dist/{chunk-M62XY4NC.js.map → chunk-G2TUAD65.js.map} +1 -1
- package/dist/{chunk-6O6FWUDW.js → chunk-GXYAOAK5.js} +23 -42
- package/dist/chunk-GXYAOAK5.js.map +1 -0
- package/dist/{chunk-XAU7QFG3.js → chunk-H6WTY5PM.js} +60 -38
- package/dist/chunk-H6WTY5PM.js.map +1 -0
- package/dist/{chunk-FJW36PD7.js → chunk-I3AL54MA.js} +10 -10
- package/dist/{chunk-FJW36PD7.js.map → chunk-I3AL54MA.js.map} +1 -1
- package/dist/{chunk-CYHJDKFB.js → chunk-LGRHHFHN.js} +16 -11
- package/dist/{chunk-CYHJDKFB.js.map → chunk-LGRHHFHN.js.map} +1 -1
- package/dist/{chunk-2XPPBEYF.js → chunk-NHHSZB5N.js} +2 -2
- package/dist/{chunk-WVE3F724.js → chunk-SQGT43Z3.js} +3 -3
- package/dist/{chunk-MPNSO7E6.js → chunk-VJ7BZGAF.js} +2 -2
- package/dist/{chunk-DMMZSZTN.js → chunk-VUMGMGKZ.js} +13 -13
- package/dist/chunk-VUMGMGKZ.js.map +1 -0
- package/dist/{chunk-ZTMKFZQ3.js → chunk-YQO2NMJ3.js} +447 -320
- package/dist/chunk-YQO2NMJ3.js.map +1 -0
- package/dist/index.d.ts +27 -7
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.js +2 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -3
- package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
- package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
- package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
- package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
- package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
- package/dist/SchedulesPage-KKLUDO6B.js +0 -15
- package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
- package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
- package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
- package/dist/chunk-6O6FWUDW.js.map +0 -1
- package/dist/chunk-7Z2C2K7F.js +0 -578
- package/dist/chunk-7Z2C2K7F.js.map +0 -1
- package/dist/chunk-DMMZSZTN.js.map +0 -1
- package/dist/chunk-U7KURWW3.js.map +0 -1
- package/dist/chunk-XAU7QFG3.js.map +0 -1
- package/dist/chunk-ZTMKFZQ3.js.map +0 -1
- /package/dist/{AgentCodeSnippets-NZOFJE57.js.map → AgentCodeSnippets-637HQUXD.js.map} +0 -0
- /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-4FYECRIN.js.map} +0 -0
- /package/dist/{AgentOverview-EEBHJC32.js.map → AgentOverview-3FJ5EE6N.js.map} +0 -0
- /package/dist/{AgentSessions-3MPDZASK.js.map → AgentSessions-T7MOGOTZ.js.map} +0 -0
- /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-NLFNU6F2.js.map} +0 -0
- /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-JEPNPJ7U.js.map} +0 -0
- /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-WQU4H25F.js.map} +0 -0
- /package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-LSXK2VN4.js.map} +0 -0
- /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-3TSLV22Q.js.map} +0 -0
- /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-Q5P7PYSJ.js.map} +0 -0
- /package/dist/{chunk-ZKNUMH2M.js.map → chunk-5I2COQNL.js.map} +0 -0
- /package/dist/{chunk-2XPPBEYF.js.map → chunk-NHHSZB5N.js.map} +0 -0
- /package/dist/{chunk-WVE3F724.js.map → chunk-SQGT43Z3.js.map} +0 -0
- /package/dist/{chunk-MPNSO7E6.js.map → chunk-VJ7BZGAF.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/containers/SettingsBuilder/SandboxSettings.tsx","../src/containers/SettingsBuilder/ConfigureSandboxForm.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { Spinner } from '@/atoms/primitives/Spinner.js';\nimport { Button } from '../../atoms/primitives/Button.js';\nimport { Tooltip } from '../../atoms/primitives/Tooltip.js';\nimport { Icon } from '../../icons/Icon.js';\nimport { useCatalogServer } from '../../server/ServerContext.js';\nimport type {\n SandboxProviderBase,\n SandboxProviderCatalogEntry,\n SandboxProviderConfig,\n SandboxProviderListEntry,\n SandboxSnapshotSyncStatus,\n} from '../../server/types.js';\nimport { getErrorMessage } from '../../utils/getErrorMessage.js';\nimport { useToasterOptional } from '../ToasterContainer.js';\nimport ConfigureSandboxForm, { type SandboxConfigDraft } from './ConfigureSandboxForm.js';\n\nconst SNAPSHOT_STATUS_POLL_INTERVAL_MS = 10000;\n\nconst configFrom = ({\n execTimeoutMs,\n autoStopIntervalInMinutes,\n autoArchiveIntervalInMinutes,\n autoDeleteIntervalInMinutes,\n}: SandboxProviderConfig): SandboxProviderConfig => ({\n execTimeoutMs,\n autoStopIntervalInMinutes,\n autoArchiveIntervalInMinutes,\n autoDeleteIntervalInMinutes,\n});\n\nconst statusPresentation = (status: SandboxSnapshotSyncStatus['status']): { label: string; className: string } => {\n switch (status) {\n case 'pending':\n return {\n label: 'Syncing image...',\n className: 'text-warning-bg',\n };\n case 'ready':\n return {\n label: 'Connected',\n className: 'text-success-bg',\n };\n case 'failed':\n return {\n label: 'Sync failed',\n className: 'text-failure-bg',\n };\n default:\n return {\n label: status,\n className: 'text-text-secondary',\n };\n }\n};\n\nconst SandboxSettings = () => {\n const { sandboxCatalog } = useCatalogServer();\n const toaster = useToasterOptional();\n\n const [providers, setProviders] = useState<SandboxProviderListEntry[]>([]);\n const [catalog, setCatalog] = useState<SandboxProviderCatalogEntry[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n\n const [createEntry, setCreateEntry] = useState<SandboxProviderCatalogEntry | null>(null);\n const [updateProvider, setUpdateProvider] = useState<SandboxProviderBase | null>(null);\n\n const refresh = useCallback(\n async ({ quiet = false }: { quiet?: boolean } = {}) => {\n if (!sandboxCatalog) return;\n if (!quiet) setLoading(true);\n setError(null);\n try {\n const [listed, available] = await Promise.all([\n sandboxCatalog.listSandboxProviders(),\n sandboxCatalog.getSandboxProviderCatalog(),\n ]);\n setProviders(listed);\n setCatalog(available);\n } catch (err) {\n setError(getErrorMessage(err, 'Failed to load sandbox providers'));\n } finally {\n if (!quiet) setLoading(false);\n }\n },\n [sandboxCatalog],\n );\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const hasPendingProvider = providers.some(entry => entry.snapshotSyncStatus.status === 'pending');\n\n useEffect(() => {\n if (!sandboxCatalog || !hasPendingProvider) return;\n const activeSandboxCatalog = sandboxCatalog;\n\n let cancelled = false;\n let timeoutId: number | undefined;\n\n function schedulePoll() {\n timeoutId = window.setTimeout(() => {\n void poll();\n }, SNAPSHOT_STATUS_POLL_INTERVAL_MS);\n }\n\n async function poll() {\n try {\n const listed = await activeSandboxCatalog.listSandboxProviders();\n if (cancelled) return;\n setProviders(listed);\n setError(null);\n if (listed.some(entry => entry.snapshotSyncStatus.status === 'pending')) {\n schedulePoll();\n }\n } catch (err) {\n if (cancelled) return;\n setError(getErrorMessage(err, 'Failed to refresh sandbox providers'));\n schedulePoll();\n }\n }\n\n schedulePoll();\n return () => {\n cancelled = true;\n if (timeoutId !== undefined) {\n window.clearTimeout(timeoutId);\n }\n };\n }, [sandboxCatalog, hasPendingProvider]);\n\n // Tenant/UI-wide: only one sandbox provider may be configured at a time.\n const hasConfiguredProvider = providers.length > 0;\n const availableEntries = useMemo(() => {\n if (hasConfiguredProvider) return [];\n const connectedCatalogIds = new Set(providers.map(provider => provider.data.catalogId));\n return catalog.filter(entry => !connectedCatalogIds.has(entry.id));\n }, [catalog, providers, hasConfiguredProvider]);\n\n const formInitialConfig = useMemo(\n () => (updateProvider ? configFrom(updateProvider) : createEntry ? configFrom(createEntry) : null),\n [updateProvider, createEntry],\n );\n\n if (!sandboxCatalog) {\n return <p className=\"text-sm text-text-secondary\">Sandbox provider catalog is not available.</p>;\n }\n\n const runMutation = async (fn: () => Promise<void>, setMutationError = setError) => {\n setBusy(true);\n setError(null);\n try {\n await fn();\n await refresh({ quiet: true });\n } catch (err) {\n setMutationError(getErrorMessage(err, 'Request failed'));\n throw err;\n } finally {\n setBusy(false);\n }\n };\n\n const handleCreate = async (draft: SandboxConfigDraft) => {\n if (!createEntry) return;\n setFormError(null);\n await runMutation(async () => {\n await sandboxCatalog.createSandboxProvider({\n catalogId: createEntry.id,\n name: createEntry.name,\n type: createEntry.type,\n ...configFrom(draft),\n apiKey: draft.apiKey,\n });\n }, setFormError);\n setCreateEntry(null);\n setTimeout(() => {\n toaster?.showSuccess({ title: `${createEntry.name} configured` });\n }, 0);\n };\n\n const handleUpdate = async (draft: SandboxConfigDraft) => {\n if (!updateProvider) return;\n setFormError(null);\n await runMutation(async () => {\n await sandboxCatalog.updateSandboxProvider({\n id: updateProvider.id,\n ...configFrom(draft),\n ...(draft.apiKey ? { apiKey: draft.apiKey } : {}),\n });\n }, setFormError);\n setUpdateProvider(null);\n setTimeout(() => {\n toaster?.showSuccess({ title: `${updateProvider.name} updated` });\n }, 0);\n };\n\n const handleRetry = (provider: SandboxProviderBase) => {\n void runMutation(async () => {\n await sandboxCatalog.updateSandboxProvider({\n id: provider.id,\n ...configFrom(provider),\n });\n }).catch(() => {});\n };\n\n const handleRemove = (provider: SandboxProviderBase) => {\n const deleteSandboxProvider = sandboxCatalog.deleteSandboxProvider;\n if (!deleteSandboxProvider) return;\n void runMutation(async () => {\n await deleteSandboxProvider({ id: provider.id });\n }).catch(() => {});\n };\n\n const formOpen = createEntry != null || updateProvider != null;\n const isUpdate = updateProvider != null;\n const formTitle = updateProvider\n ? `Update ${updateProvider.name}`\n : createEntry\n ? `Configure ${createEntry.name}`\n : 'Configure sandbox provider';\n\n return (\n <>\n <h3 className=\"text-xl font-semibold tracking-tight text-text-primary\">Sandbox providers</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Choose a provider that runs sandboxes for code, files and shell commands. Only one can be active at a time.\n </p>\n\n {error ? (\n <p className=\"mt-3 rounded-md border border-failure-bg/30 bg-failure-bg/10 px-3 py-2 text-sm text-failure-bg\">\n {error}\n </p>\n ) : null}\n\n <div className=\"mt-4 flex-1 overflow-y-auto\">\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading sandbox providers…</p>\n ) : (\n <div className=\"space-y-6\">\n {providers.length > 0 ? (\n <section>\n <h4 className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Configured · {providers.length}\n </h4>\n <div className=\"overflow-hidden rounded-xl border border-border bg-card-bg\">\n {providers.map(entry => {\n const provider = entry.data;\n const status = statusPresentation(entry.snapshotSyncStatus.status);\n const statusReason = entry.snapshotSyncStatus.statusReason;\n const statusIndicator = (\n <span className={`inline-flex items-center gap-1.5 text-sm font-medium ${status.className}`}>\n {entry.snapshotSyncStatus.status === 'pending' ? (\n <Spinner size={16} aria-label=\"Syncing snapshot image\" />\n ) : entry.snapshotSyncStatus.status === 'ready' ? (\n <span className=\"size-2 rounded-full bg-success-bg\" aria-hidden />\n ) : entry.snapshotSyncStatus.status === 'failed' ? (\n <Icon name=\"triangle-exclamation\" className=\"size-4\" />\n ) : null}\n {status.label}\n </span>\n );\n return (\n <article\n key={provider.id}\n className=\"flex flex-col gap-3 border-b border-border p-3 last:border-b-0 sm:flex-row sm:items-center\"\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <span\n className=\"flex size-9 shrink-0 items-center justify-center rounded-lg border border-border bg-secondary-bg text-text-primary\"\n aria-hidden\n >\n <Icon name=\"cube\" className=\"size-4.5\" />\n </span>\n <div className=\"min-w-0\">\n <h5 className=\"truncate text-sm font-medium text-text-primary\">{provider.name}</h5>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2.5 sm:justify-end\">\n {statusIndicator}\n {statusReason ? (\n <Tooltip content={statusReason}>\n <button\n type=\"button\"\n aria-label=\"Snapshot sync status details\"\n className=\"inline-flex text-text-secondary transition-colors hover:text-text-primary\"\n >\n <Icon name=\"info\" className=\"size-4\" />\n </button>\n </Tooltip>\n ) : null}\n {entry.snapshotSyncStatus.status === 'failed' ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n type=\"button\"\n disabled={busy}\n onClick={() => {\n handleRetry(provider);\n }}\n >\n Retry\n </Button>\n ) : null}\n <Button\n variant=\"secondary\"\n size=\"sm\"\n type=\"button\"\n disabled={busy}\n onClick={() => {\n setFormError(null);\n setCreateEntry(null);\n setUpdateProvider(provider);\n }}\n >\n Update\n </Button>\n\n {sandboxCatalog.deleteSandboxProvider ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-text-secondary\"\n type=\"button\"\n disabled={busy}\n onClick={() => {\n handleRemove(provider);\n }}\n >\n Remove\n </Button>\n ) : null}\n </div>\n </article>\n );\n })}\n </div>\n </section>\n ) : null}\n\n {!hasConfiguredProvider ? (\n <section>\n <h4 className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Available · {availableEntries.length}\n </h4>\n {availableEntries.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">\n {catalog.length > 0\n ? 'All catalog providers are configured.'\n : 'No sandbox providers in the catalog.'}\n </p>\n ) : (\n <div className=\"overflow-hidden rounded-xl border border-border bg-card-bg\">\n {availableEntries.map(entry => (\n <article\n key={entry.id}\n className=\"flex flex-col gap-3 border-b border-border p-3 last:border-b-0 sm:flex-row sm:items-center\"\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n <span\n className=\"flex size-9 shrink-0 items-center justify-center rounded-lg border border-border bg-secondary-bg text-text-primary\"\n aria-hidden\n >\n <Icon name=\"cube\" className=\"size-4.5\" />\n </span>\n <div className=\"min-w-0\">\n <h5 className=\"truncate text-sm font-medium text-text-primary\">{entry.name}</h5>\n </div>\n </div>\n\n <Button\n variant=\"secondary\"\n type=\"button\"\n disabled={busy}\n onClick={() => {\n setFormError(null);\n setUpdateProvider(null);\n setCreateEntry(entry);\n }}\n >\n Configure\n </Button>\n </article>\n ))}\n </div>\n )}\n </section>\n ) : null}\n </div>\n )}\n </div>\n\n <ConfigureSandboxForm\n open={formOpen}\n onOpenChange={open => {\n if (!open) {\n setFormError(null);\n setCreateEntry(null);\n setUpdateProvider(null);\n }\n }}\n onSave={isUpdate ? handleUpdate : handleCreate}\n title={formTitle}\n description={\n isUpdate\n ? 'Update this sandbox provider. Leave API key blank to keep the existing key.'\n : 'Configure this sandbox provider. API key is never stored in the catalog.'\n }\n initialConfig={formInitialConfig}\n requireApiKey={!isUpdate}\n busy={busy}\n error={formError}\n />\n </>\n );\n};\n\nexport default SandboxSettings;\n","'use client';\n\nimport { useEffect, useState, type FormEvent } from 'react';\n\nimport { cn } from '../../atoms/lib/cn.js';\nimport { auiInputClass } from '../../atoms/lib/inputClasses.js';\nimport { Accordion, AccordionDetails, AccordionSummary } from '../../atoms/primitives/Accordion.js';\nimport { Button } from '../../atoms/primitives/Button.js';\nimport { CenteredModal } from '../../atoms/primitives/CenteredModal.js';\nimport { Icon } from '../../icons/Icon.js';\nimport type { SandboxProviderConfig } from '../../server/types.js';\n\nexport type SandboxConfigDraft = SandboxProviderConfig & {\n apiKey: string;\n};\n\ntype ConfigureSandboxFormProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSave: (draft: SandboxConfigDraft) => void | Promise<void>;\n title: string;\n description?: string;\n /** Prefills config fields; apiKey is never autofilled. */\n initialConfig?: SandboxProviderConfig | null;\n /** When false (updates), empty apiKey means keep the existing key. */\n requireApiKey?: boolean;\n busy?: boolean;\n error?: string | null;\n};\n\n/** Sensible defaults so the advanced fields are never blank, even without a catalog preset. */\nconst EMPTY_CONFIG: SandboxProviderConfig = {\n // Snapshot/image is release-owned now; kept only to satisfy the external SandboxProviderConfig type.\n execTimeoutMs: 300000,\n autoStopIntervalInMinutes: 15,\n autoArchiveIntervalInMinutes: 10080,\n autoDeleteIntervalInMinutes: 43200,\n};\n\nconst inputClassName = auiInputClass('h-11 shadow-sm');\n\nfunction parseNonNegInt(raw: string): number | null {\n if (raw.trim() === '') return null;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 0) return null;\n return n;\n}\n\nconst ConfigureSandboxForm = ({\n open,\n onOpenChange,\n onSave,\n title,\n description,\n initialConfig = null,\n requireApiKey = true,\n busy = false,\n error,\n}: ConfigureSandboxFormProps) => {\n const [execTimeoutMs, setExecTimeoutMs] = useState('');\n const [autoStopIntervalInMinutes, setAutoStopIntervalInMinutes] = useState('');\n const [autoArchiveIntervalInMinutes, setAutoArchiveIntervalInMinutes] = useState('');\n const [autoDeleteIntervalInMinutes, setAutoDeleteIntervalInMinutes] = useState('');\n const [apiKey, setApiKey] = useState('');\n const [advancedOpen, setAdvancedOpen] = useState(false);\n\n const resetForm = () => {\n setExecTimeoutMs('');\n setAutoStopIntervalInMinutes('');\n setAutoArchiveIntervalInMinutes('');\n setAutoDeleteIntervalInMinutes('');\n setApiKey('');\n setAdvancedOpen(false);\n };\n\n useEffect(() => {\n if (!open) return;\n const config = initialConfig ?? EMPTY_CONFIG;\n setExecTimeoutMs(String(config.execTimeoutMs));\n setAutoStopIntervalInMinutes(String(config.autoStopIntervalInMinutes));\n setAutoArchiveIntervalInMinutes(String(config.autoArchiveIntervalInMinutes));\n setAutoDeleteIntervalInMinutes(String(config.autoDeleteIntervalInMinutes));\n setApiKey('');\n setAdvancedOpen(false);\n }, [open, initialConfig]);\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (!nextOpen) resetForm();\n onOpenChange(nextOpen);\n };\n\n const execTimeout = parseNonNegInt(execTimeoutMs);\n const autoStop = parseNonNegInt(autoStopIntervalInMinutes);\n const autoArchive = parseNonNegInt(autoArchiveIntervalInMinutes);\n const autoDelete = parseNonNegInt(autoDeleteIntervalInMinutes);\n const trimmedKey = apiKey.trim();\n\n const isValid =\n (!requireApiKey || !!trimmedKey) &&\n execTimeout != null &&\n autoStop != null &&\n autoArchive != null &&\n autoDelete != null;\n\n const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!isValid || busy || execTimeout == null || autoStop == null || autoArchive == null || autoDelete == null) {\n return;\n }\n\n try {\n await onSave({\n // Snapshot/image is release-owned; the field is retained only for the external type.\n execTimeoutMs: execTimeout,\n autoStopIntervalInMinutes: autoStop,\n autoArchiveIntervalInMinutes: autoArchive,\n autoDeleteIntervalInMinutes: autoDelete,\n apiKey: trimmedKey,\n });\n resetForm();\n onOpenChange(false);\n } catch {\n // Parent surfaces error; keep form open.\n }\n };\n\n return (\n <CenteredModal\n open={open}\n onOpenChange={handleOpenChange}\n title={title}\n description={description}\n contentSized\n headerIcon={\n <span\n className=\"flex size-11 shrink-0 items-center justify-center rounded-lg border border-border bg-secondary-bg text-text-primary\"\n aria-hidden\n >\n <Icon name=\"cube\" className=\"size-6\" />\n </span>\n }\n >\n <form className=\"flex flex-col overflow-y-auto p-5 md:p-6\" onSubmit={handleSubmit}>\n <div className=\"space-y-4\">\n <div>\n <label htmlFor=\"sandbox-api-key\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n API key\n {!requireApiKey ? <span className=\"font-normal text-text-secondary\"> (optional)</span> : null}\n </label>\n <input\n id=\"sandbox-api-key\"\n type=\"password\"\n required={requireApiKey}\n value={apiKey}\n onChange={event => {\n setApiKey(event.target.value);\n }}\n placeholder={requireApiKey ? 'dtn_...' : 'Leave blank to keep existing'}\n autoFocus\n className={inputClassName}\n />\n </div>\n\n <Accordion\n expanded={advancedOpen}\n onChange={(_event, next) => setAdvancedOpen(next)}\n className=\"rounded-md border border-border\"\n >\n <AccordionSummary className=\"px-3 py-2.5\">\n <span className=\"flex w-full items-center justify-between text-sm font-medium text-text-primary\">\n Advanced settings\n <Icon\n name=\"chevron-down\"\n className={cn(\n 'size-4 shrink-0 text-text-secondary transition-transform duration-200',\n advancedOpen ? 'rotate-0' : '-rotate-90',\n )}\n />\n </span>\n </AccordionSummary>\n <AccordionDetails className=\"space-y-4 border-t border-border px-3 pb-3 pt-4\">\n <div>\n <label htmlFor=\"sandbox-exec-timeout\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Exec timeout (ms)\n </label>\n <input\n id=\"sandbox-exec-timeout\"\n type=\"number\"\n min={0}\n required\n value={execTimeoutMs}\n onChange={event => {\n setExecTimeoutMs(event.target.value);\n }}\n placeholder=\"300000\"\n className={inputClassName}\n />\n </div>\n\n <div>\n <label htmlFor=\"sandbox-auto-stop\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Auto-stop interval (minutes)\n </label>\n <input\n id=\"sandbox-auto-stop\"\n type=\"number\"\n min={0}\n required\n value={autoStopIntervalInMinutes}\n onChange={event => {\n setAutoStopIntervalInMinutes(event.target.value);\n }}\n placeholder=\"15\"\n className={inputClassName}\n />\n </div>\n\n <div>\n <label htmlFor=\"sandbox-auto-archive\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Auto-archive interval (minutes)\n </label>\n <input\n id=\"sandbox-auto-archive\"\n type=\"number\"\n min={0}\n required\n value={autoArchiveIntervalInMinutes}\n onChange={event => {\n setAutoArchiveIntervalInMinutes(event.target.value);\n }}\n placeholder=\"10080\"\n className={inputClassName}\n />\n </div>\n\n <div>\n <label htmlFor=\"sandbox-auto-delete\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Auto-delete interval (minutes)\n </label>\n <input\n id=\"sandbox-auto-delete\"\n type=\"number\"\n min={0}\n required\n value={autoDeleteIntervalInMinutes}\n onChange={event => {\n setAutoDeleteIntervalInMinutes(event.target.value);\n }}\n placeholder=\"43200\"\n className={inputClassName}\n />\n </div>\n </AccordionDetails>\n </Accordion>\n </div>\n\n <div className=\"mt-6 space-y-3\">\n {error ? <p className=\"text-failure-bg text-sm\">{error}</p> : null}\n <Button type=\"submit\" size=\"lg\" disabled={!isValid || busy} className=\"w-full shrink-0\">\n Save\n </Button>\n </div>\n </form>\n </CenteredModal>\n );\n};\n\nexport default ConfigureSandboxForm;\n"],"mappings":"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","names":["useEffect","useState","jsx","jsxs","useState","useEffect"]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import {
|
|
3
|
-
SchedulesPage
|
|
4
|
-
} from "./chunk-6O6FWUDW.js";
|
|
5
|
-
import "./chunk-ZTMKFZQ3.js";
|
|
6
|
-
import "./chunk-2XPPBEYF.js";
|
|
7
|
-
import "./chunk-XAU7QFG3.js";
|
|
8
|
-
import "./chunk-U7KURWW3.js";
|
|
9
|
-
import "./chunk-M6MHLVSO.js";
|
|
10
|
-
import "./chunk-MPNSO7E6.js";
|
|
11
|
-
import "./chunk-7Z2C2K7F.js";
|
|
12
|
-
export {
|
|
13
|
-
SchedulesPage
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=SchedulesPage-KKLUDO6B.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routing/ShellRouteSync.tsx","../src/routing/derivePlace.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nimport { sessionIsCreateAgent } from '../atoms/lib/sessionCreateAgent.js';\nimport { useOptionalCatalogServer, useOptionalServer, useServerCapabilities } from '../server/ServerContext.js';\nimport { useShellMode } from '../server/ShellModeContext.js';\nimport { isSettingsChromeEnabled } from '../server/settingsChrome.js';\nimport { deriveChatPlace, derivePlace } from './derivePlace.js';\nimport { buildPath, matchLocation, placesEqual, sanitizeSearchForPlace } from './paths.js';\nimport type { ResolvedRoutes, RoutePlace, ShellSnapshot } from './types.js';\n\n/**\n * Single bidirectional bridge between shell state and the URL. Mounted under\n * `ShellModeProvider` but outside the keyed chat runtime so boot applies once.\n */\nexport function ShellRouteSync({\n routes,\n activeRemoteId,\n initialSettingsOpen,\n}: {\n routes: ResolvedRoutes;\n activeRemoteId: string | undefined;\n initialSettingsOpen: boolean;\n}) {\n const shell = useShellMode();\n const server = useOptionalServer();\n const catalog = useOptionalCatalogServer();\n const capabilities = useServerCapabilities();\n const navigate = useNavigate();\n const location = useLocation();\n // Same gate as the Settings sidebar button: no catalog / settings capability\n // off → `/settings` is unregistered (match + build return null).\n const settingsChromeEnabled = isSettingsChromeEnabled({ catalog, capabilities });\n const effectiveRoutes = useMemo(\n () => (settingsChromeEnabled ? routes : { ...routes, settings: null }),\n [routes, settingsChromeEnabled],\n );\n\n const snapshot: ShellSnapshot = {\n settingsOpen: shell.settingsOpen,\n libraryOpen: shell.libraryOpen,\n sessionsOpen: shell.sessionsOpen,\n libraryAgentId: shell.libraryAgentId,\n schedulesOpen: shell.schedulesOpen,\n pendingSessionId: shell.pendingSessionId,\n activeRemoteId,\n mode: shell.mode,\n agentConfigMode: shell.agentConfigMode,\n };\n\n const place = derivePlace(snapshot);\n const placeKey = JSON.stringify(place);\n\n // Guards. `selfNavPathRef` marks a path we navigated to ourselves so the\n // URL->shell effect does not re-apply it. `prevPlaceRef` powers push/replace.\n const selfNavPathRef = useRef<string | null>(null);\n const prevPlaceRef = useRef<RoutePlace | null>(null);\n const bootedRef = useRef(false);\n // Latest session id the URL asked for, so slower lookups cannot bind over it.\n const requestedSessionRef = useRef<string | null>(null);\n // Boot owns the first URL; the ongoing effects skip their initial commit so\n // they do not fight boot with the stale first-render place.\n const shellSyncStartedRef = useRef(false);\n const urlSyncStartedRef = useRef(false);\n\n /**\n * A URL carries only the id, so ask the server whether it names a mutable\n * draft or an agent chat; guessing \"mutable\" opens an agent session as a\n * blank draft. `requestedSessionRef` drops replies a later place superseded.\n */\n const openSession = useCallback(\n (sessionId: string) => {\n requestedSessionRef.current = sessionId;\n if (server == null) {\n shell.openHistorySession({ sessionId });\n return;\n }\n void server\n .getSession({ sessionId })\n .then(session => {\n if (requestedSessionRef.current !== sessionId) return;\n shell.openHistorySession({\n sessionId,\n isMutable: session.isMutable,\n isCreateAgent: sessionIsCreateAgent(session),\n ...(session.agentName != null ? { agentName: session.agentName } : {}),\n });\n })\n .catch(() => {\n if (requestedSessionRef.current !== sessionId) return;\n // Unreachable session: bind by id alone rather than stranding the shell.\n shell.openHistorySession({ sessionId });\n });\n },\n [server, shell],\n );\n\n const applyPlace = useCallback(\n (target: RoutePlace) => {\n switch (target.type) {\n case 'settings':\n shell.setSettingsOpen(true);\n return;\n case 'library':\n shell.setLibraryOpen(true);\n return;\n case 'sessionsBrowser':\n shell.setSessionsOpen(true);\n return;\n case 'libraryAgent':\n shell.openLibraryAgent(target.agentId);\n return;\n case 'schedules':\n shell.setSchedulesOpen(true);\n return;\n case 'session':\n shell.setLibraryOpen(false);\n if (shell.pendingSessionId === target.sessionId || activeRemoteId === target.sessionId) return;\n openSession(target.sessionId);\n return;\n case 'agent':\n shell.setLibraryOpen(false);\n shell.selectLibraryAgent({ isMutable: false, agentName: target.agentName });\n return;\n case 'root':\n shell.setSettingsOpen(false);\n shell.setLibraryOpen(false);\n shell.setSchedulesOpen(false);\n switch (shell.agentConfigMode) {\n case 'AgentLibrary':\n shell.openLibraryHome();\n return;\n case 'AgentComposer':\n case 'AgentLibraryWithComposer':\n shell.openDraft();\n return;\n case 'SingleAgent':\n shell.clearChat();\n return;\n }\n }\n },\n [shell, activeRemoteId, openSession],\n );\n\n // Boot: URL wins, except an explicit `initialSettingsOpen` overlay. Boot is the\n // sole authority for the first commit and sets the final URL + `prevPlaceRef`.\n useEffect(() => {\n if (bootedRef.current) return;\n bootedRef.current = true;\n\n const urlPlace = matchLocation({\n pathname: location.pathname,\n search: location.search,\n routes: effectiveRoutes,\n }) ?? { type: 'root' };\n const settingsOnBoot = settingsChromeEnabled && (initialSettingsOpen || urlPlace.type === 'settings');\n\n if (urlPlace.type === 'settings') {\n if (settingsChromeEnabled) shell.setSettingsOpen(true);\n } else if (urlPlace.type === 'library') {\n shell.setLibraryOpen(true);\n } else if (urlPlace.type === 'sessionsBrowser') {\n shell.setSessionsOpen(true);\n } else if (urlPlace.type === 'libraryAgent') {\n shell.openLibraryAgent(urlPlace.agentId);\n } else if (urlPlace.type === 'schedules') {\n shell.setSchedulesOpen(true);\n } else {\n const chatPlace = deriveChatPlace(snapshot);\n if (!placesEqual(chatPlace, urlPlace)) applyPlace(urlPlace);\n if (settingsOnBoot) shell.setSettingsOpen(true);\n }\n\n const desiredPlace: RoutePlace = settingsOnBoot ? { type: 'settings' } : urlPlace;\n const desiredPath = buildPath(desiredPlace, effectiveRoutes);\n const desiredSearch = sanitizeSearchForPlace(desiredPlace, location.search);\n prevPlaceRef.current = desiredPlace;\n if (desiredPath != null && (desiredPath !== location.pathname || desiredSearch !== location.search)) {\n selfNavPathRef.current = desiredPath !== location.pathname ? desiredPath : null;\n navigate({ pathname: desiredPath, search: desiredSearch, hash: location.hash }, { replace: true });\n }\n // Boot runs once; snapshot is read imperatively here.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Shell -> URL: mirror the derived place. Skip the first commit (boot owns it).\n useEffect(() => {\n if (!bootedRef.current) return;\n if (!shellSyncStartedRef.current) {\n shellSyncStartedRef.current = true;\n return;\n }\n const target = buildPath(place, effectiveRoutes);\n if (target == null) return; // place has no configured URL (e.g. settings disabled)\n const basename = effectiveRoutes.basename.endsWith('/')\n ? effectiveRoutes.basename.slice(0, -1)\n : effectiveRoutes.basename;\n const browserPathname = `${basename}${location.pathname}` || '/';\n const latestSearch = window.location.pathname === browserPathname ? window.location.search : location.search;\n const targetSearch = sanitizeSearchForPlace(place, latestSearch);\n\n const prev = prevPlaceRef.current;\n prevPlaceRef.current = place;\n\n if (target === location.pathname && targetSearch === location.search) return;\n\n // Replace when a fresh chat just acquired its session id (same place, new id).\n const replace =\n place.type === 'session' && shell.pendingSessionId == null && prev != null && prev.type !== 'session';\n\n selfNavPathRef.current = target !== location.pathname ? target : null;\n // Query keys owned by other shell places are removed; host keys and hash survive.\n navigate({ pathname: target, search: targetSearch, hash: location.hash }, { replace });\n // location.pathname intentionally excluded: only react to shell-derived place changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [placeKey, settingsChromeEnabled]);\n\n // URL -> shell: apply on genuine location changes (Back/Forward, manual edits).\n useEffect(() => {\n if (!bootedRef.current) return;\n if (!urlSyncStartedRef.current) {\n urlSyncStartedRef.current = true;\n return;\n }\n if (selfNavPathRef.current === location.pathname) {\n selfNavPathRef.current = null;\n return;\n }\n const urlPlace = matchLocation({\n pathname: location.pathname,\n search: location.search,\n routes: effectiveRoutes,\n });\n if (urlPlace == null) {\n // Unknown path: normalize to root.\n const rootPath = effectiveRoutes.root;\n const rootSearch = sanitizeSearchForPlace({ type: 'root' }, location.search);\n selfNavPathRef.current = rootPath;\n navigate({ pathname: rootPath, search: rootSearch, hash: location.hash }, { replace: true });\n applyPlace({ type: 'root' });\n return;\n }\n if (urlPlace.type !== 'settings' && shell.settingsOpen) {\n // Leaving settings via Back to a chat place.\n shell.setSettingsOpen(false);\n }\n if (urlPlace.type !== 'library' && urlPlace.type !== 'libraryAgent' && shell.libraryOpen) {\n shell.setLibraryOpen(false);\n }\n if (urlPlace.type !== 'sessionsBrowser' && shell.sessionsOpen) {\n shell.setSessionsOpen(false);\n }\n if (urlPlace.type !== 'schedules' && shell.schedulesOpen) {\n // Leaving schedules via Back to a chat place.\n shell.setSchedulesOpen(false);\n }\n applyPlace(urlPlace);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\n\n return null;\n}\n","import type { RoutePlace, ShellSnapshot } from './types.js';\n\n/**\n * The chat place implied by shell state, ignoring settings, schedules,\n * sessions-browser, and library overlays.\n * SingleAgent canonicalizes to `root` so `/` and `/agents/{name}` alias.\n */\nexport function deriveChatPlace(snapshot: ShellSnapshot): RoutePlace {\n // The live thread wins: reusing a mutable shell switches thread without a\n // remount, leaving `pendingSessionId` on the session the shell last opened.\n // It only leads while a requested session has not reported its thread yet.\n const sessionId = snapshot.activeRemoteId ?? snapshot.pendingSessionId;\n if (sessionId != null) return { type: 'session', sessionId };\n\n const { mode, agentConfigMode } = snapshot;\n if (mode.status === 'active' && !mode.isMutable && agentConfigMode !== 'SingleAgent') {\n const agentName = mode.agentName ?? mode.agentId;\n if (agentName != null) return { type: 'agent', agentName };\n }\n return { type: 'root' };\n}\n\n/** Full place with overlay priority: settings, schedules, sessions, library, chat. */\nexport function derivePlace(snapshot: ShellSnapshot): RoutePlace {\n if (snapshot.settingsOpen) return { type: 'settings' };\n if (snapshot.schedulesOpen) return { type: 'schedules' };\n if (snapshot.sessionsOpen) return { type: 'sessionsBrowser' };\n if (snapshot.libraryOpen && snapshot.libraryAgentId != null) {\n return { type: 'libraryAgent', agentId: snapshot.libraryAgentId };\n }\n if (snapshot.libraryOpen) return { type: 'library' };\n return deriveChatPlace(snapshot);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/layouts/SidebarLayout.tsx"],"sourcesContent":["'use client';\n\nimport {\n lazy,\n Suspense,\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { useAui } from '../assistant-ui.js';\nimport { auiButtonClass } from '../atoms/lib/buttonClasses.js';\nimport { cn } from '../atoms/lib/cn.js';\nimport { useIsMobile } from '../atoms/lib/useIsMobile.js';\nimport { NamedAgentHeaderLabel } from '../atoms/NamedAgentHeaderLabel.js';\nimport { PageHeader } from '../atoms/PageHeader.js';\nimport { Spinner } from '../atoms/primitives/Spinner.js';\nimport { ShellActions } from '../atoms/ShellActions.js';\nimport { AgentConfigDrawerContainer } from '../containers/AgentConfigDrawerContainer.js';\nimport { Thread } from '../containers/Thread.js';\nimport { useChatHeaderContentVisible } from '../hooks/useChatChromeActionsVisible.js';\nimport { Icon } from '../icons/Icon.js';\nimport { shellIsCreateAgent, useOptionalShellMode } from '../server/ShellModeContext.js';\nimport { resolveBrandChrome } from '../theme/brand.js';\nimport { useSlot } from '../theme/SlotsProvider.js';\nimport { useBrand } from '../theme/ThemeProvider.js';\n\nconst TruefoundrySettingsBuilder = lazy(() => import('../containers/SettingsBuilder/index.js'));\nconst SchedulesPage = lazy(() =>\n import('../atoms/schedules/SchedulesPage.js').then(m => ({ default: m.SchedulesPage })),\n);\n\nconst brandLogoClassName = 'h-5 w-5 max-w-40 shrink-0 object-contain';\nconst railWidthClassName = 'w-18';\n\nconst railActionButtonClassName =\n 'h-auto w-full flex-col gap-1.5 whitespace-normal px-1 py-3 text-[0.625rem] leading-tight !justify-center text-text-primary shadow-none hover:bg-secondary-button-hover hover:text-ghost-button-text';\n\nconst railSelectedClassName =\n 'bg-primary-button-bg text-primary-button-text hover:bg-primary-button-hover hover:text-primary-button-text';\n\nfunction SidebarNav(): ReactNode {\n const aui = useAui();\n const shell = useOptionalShellMode();\n const AgentsLibraryButton = useSlot('AgentsLibraryButton');\n const SessionsBrowserButton = useSlot('SessionsBrowserButton');\n const SchedulesButton = useSlot('SchedulesButton');\n const showNewActions = shell?.isNewChatEnabled !== false;\n const overlayOpen =\n shell?.settingsOpen === true ||\n shell?.libraryOpen === true ||\n shell?.sessionsOpen === true ||\n shell?.schedulesOpen === true;\n const mode = shell?.mode;\n const newChatSelected = !overlayOpen && mode?.status === 'active' && mode.isMutable && !mode.isCreateAgent;\n const newAgentSelected = !overlayOpen && mode != null && shellIsCreateAgent(mode);\n\n const handleNewChat = () => {\n shell?.setLibraryOpen(false);\n shell?.setSessionsOpen(false);\n if (shell?.isComposerEnabled) {\n shell.openDraft();\n return;\n }\n shell?.setSettingsOpen(false);\n shell?.setSchedulesOpen(false);\n void Promise.resolve(aui.threads().switchToNewThread()).catch(() => undefined);\n };\n\n const handleNewAgent = () => {\n shell?.setLibraryOpen(false);\n shell?.setSessionsOpen(false);\n if (shell?.isComposerEnabled) {\n shell.openAgentBuilder();\n }\n };\n\n return (\n <nav className=\"flex min-h-0 flex-1 flex-col items-center gap-1 p-1\" aria-label=\"Sidebar\">\n {showNewActions ? (\n <button\n type=\"button\"\n aria-label=\"Start new chat\"\n title=\"New chat\"\n aria-current={newChatSelected ? 'page' : undefined}\n className={auiButtonClass({\n variant: 'ghost',\n className: cn(railActionButtonClassName, newChatSelected && railSelectedClassName),\n })}\n onClick={handleNewChat}\n >\n <Icon name=\"square-pen\" size={16} />\n <span className=\"text-center\">New Chat</span>\n </button>\n ) : null}\n {showNewActions && shell?.isComposerEnabled ? (\n <button\n type=\"button\"\n aria-label=\"Start new agent\"\n title=\"New Agent\"\n aria-current={newAgentSelected ? 'page' : undefined}\n className={auiButtonClass({\n variant: 'ghost',\n className: cn(railActionButtonClassName, newAgentSelected && railSelectedClassName),\n })}\n onClick={handleNewAgent}\n >\n <Icon name=\"agent-2\" size={16} />\n <span className=\"text-center\">New Agent</span>\n </button>\n ) : null}\n <AgentsLibraryButton compact />\n <SessionsBrowserButton compact />\n <SchedulesButton compact />\n </nav>\n );\n}\n\n/** Shared desktop + mobile icon+label rail (brand, nav, footer actions). */\nfunction SidebarRail({\n onNavigate,\n className,\n railRef,\n ...dialogProps\n}: {\n onNavigate?: () => void;\n className?: string;\n railRef?: Ref<HTMLElement>;\n} & Omit<ComponentPropsWithoutRef<'aside'>, 'children' | 'className'>): ReactNode {\n const brand = useBrand();\n const chrome = resolveBrandChrome(brand);\n const BrandLogo = useSlot('BrandLogo');\n\n return (\n <aside\n ref={railRef}\n className={cn(\n railWidthClassName,\n 'flex min-h-0 shrink-0 flex-col border-r border-border bg-sidebar-bg',\n className,\n )}\n onClick={event => {\n if (onNavigate == null) return;\n const target = event.target;\n if (!(target instanceof Element)) return;\n if (target.closest('button') != null) onNavigate();\n }}\n {...dialogProps}\n >\n <div className=\"flex h-14 w-full shrink-0 items-center justify-center text-text-primary\">\n <BrandLogo variant={chrome.collapsedVariant} className={brandLogoClassName} />\n </div>\n <SidebarNav />\n <footer className=\"flex shrink-0 flex-col items-center border-border p-2\">\n <ShellActions labeled className=\"flex-col\" />\n </footer>\n </aside>\n );\n}\n\nexport function SidebarLayout({ className }: { className?: string }) {\n const shell = useOptionalShellMode();\n const isMobile = useIsMobile();\n const AgentDetailsPage = useSlot('AgentDetailsPage');\n const AgentsLibrary = useSlot('AgentsLibrary');\n const SessionsPage = useSlot('SessionsPage');\n const ClearChatButton = useSlot('ClearChatButton');\n const SaveAgentButton = useSlot('SaveAgentButton');\n const SelectAgentEmptyState = useSlot('SelectAgentEmptyState');\n const [mobileNavOpen, setMobileNavOpen] = useState(false);\n const menuBtnRef = useRef<HTMLButtonElement>(null);\n const dialogRef = useRef<HTMLElement>(null);\n const mainRef = useRef<HTMLDivElement>(null);\n const wasOpen = useRef(false);\n const isIdle = shell?.mode.status === 'idle';\n const settingsOpen = shell?.settingsOpen === true;\n const libraryOpen = shell?.libraryOpen === true;\n const sessionsOpen = shell?.sessionsOpen === true;\n const schedulesOpen = shell?.schedulesOpen === true;\n const overlayOpen = settingsOpen || libraryOpen || sessionsOpen || schedulesOpen;\n const showAgentConfig =\n shell != null && shellIsCreateAgent(shell.mode) && !overlayOpen && (!isMobile || shell.agentConfigOpen);\n const hasChatHeaderContent = useChatHeaderContentVisible();\n\n useEffect(() => {\n if (!mobileNavOpen) return;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setMobileNavOpen(false);\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [mobileNavOpen]);\n\n useEffect(() => {\n const main = mainRef.current;\n if (mobileNavOpen) {\n wasOpen.current = true;\n if (main) main.inert = true;\n dialogRef.current?.focus();\n return;\n }\n if (wasOpen.current) {\n if (main) main.inert = false;\n menuBtnRef.current?.focus();\n wasOpen.current = false;\n }\n }, [mobileNavOpen]);\n\n return (\n <div className={cn('relative flex h-full min-h-0 w-full min-w-0', className)}>\n <SidebarRail className=\"hidden md:flex\" />\n\n {showAgentConfig ? (\n <aside\n role=\"dialog\"\n aria-label=\"Agent Config\"\n className=\"absolute inset-y-0 left-0 z-20 w-full max-w-sm border-r border-border shadow-xl md:static md:z-auto md:w-88 md:max-w-none md:shrink-0 md:shadow-none\"\n >\n <AgentConfigDrawerContainer showClose={isMobile} />\n </aside>\n ) : null}\n\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col bg-primary-bg\">\n {/* Desktop keeps shell chrome in the rail footer (always mounted, including\n when visually hidden on small screens so host action-slot state persists).\n Mobile reaches theme/settings via the nav drawer rail. */}\n <PageHeader\n className={cn(\n 'bg-topbar-bg',\n // Desktop: hide when settings/idle or the thread header has nothing to show\n // (empty untitled draft). Mobile still needs the menu button.\n // Builder mode keeps New Agent and its actions beside the persistent config.\n (overlayOpen || isIdle || !hasChatHeaderContent) && 'md:hidden',\n )}\n start={\n !overlayOpen ? (\n <button\n ref={menuBtnRef}\n type=\"button\"\n aria-label=\"Navigation\"\n aria-expanded={mobileNavOpen}\n className={cn(auiButtonClass({ variant: 'ghost', size: 'icon' }), 'md:hidden')}\n onClick={() => setMobileNavOpen(true)}\n >\n <Icon name=\"bars\" />\n </button>\n ) : null\n }\n title={!overlayOpen ? <NamedAgentHeaderLabel /> : null}\n end={\n !overlayOpen ? (\n <>\n <ClearChatButton />\n <SaveAgentButton />\n </>\n ) : null\n }\n />\n\n <div ref={mainRef} className=\"min-h-0 min-w-0 flex-1\">\n {settingsOpen ? (\n <Suspense\n fallback={\n <div\n className=\"flex h-full items-center justify-center\"\n role=\"status\"\n aria-live=\"polite\"\n aria-busy=\"true\"\n >\n <Spinner size={28} className=\"text-text-primary\" />\n <span className=\"sr-only\">Loading</span>\n </div>\n }\n >\n <TruefoundrySettingsBuilder />\n </Suspense>\n ) : sessionsOpen ? (\n <SessionsPage />\n ) : libraryOpen && shell?.libraryAgentId != null ? (\n <AgentDetailsPage key={shell.libraryAgentId} agentId={shell.libraryAgentId} />\n ) : libraryOpen ? (\n <AgentsLibrary onSelectAgent={() => setMobileNavOpen(false)} />\n ) : schedulesOpen ? (\n <Suspense\n fallback={\n <div\n className=\"flex h-full items-center justify-center\"\n role=\"status\"\n aria-live=\"polite\"\n aria-busy=\"true\"\n >\n <Spinner size={28} className=\"text-text-primary\" />\n <span className=\"sr-only\">Loading</span>\n </div>\n }\n >\n <SchedulesPage />\n </Suspense>\n ) : isIdle ? (\n <SelectAgentEmptyState />\n ) : (\n <Thread />\n )}\n </div>\n </div>\n\n {/* Mobile: same narrow rail as desktop */}\n {mobileNavOpen ? (\n <>\n <button\n type=\"button\"\n aria-label=\"Close navigation\"\n className=\"absolute inset-0 z-[9] cursor-pointer bg-[var(--overlay)] md:hidden\"\n onClick={() => setMobileNavOpen(false)}\n />\n <SidebarRail\n railRef={dialogRef}\n role=\"dialog\"\n aria-label=\"Navigation\"\n tabIndex={-1}\n onNavigate={() => setMobileNavOpen(false)}\n className=\"absolute inset-y-0 left-0 z-10 shadow-lg outline-none md:hidden\"\n />\n </>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/containers/SettingsBuilder/SkillSettings.tsx","../src/containers/SettingsBuilder/ImportGithubSkillForm.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport { Button } from '@/atoms/primitives/Button.js';\nimport SearchInput from '@/atoms/primitives/SearchInput.js';\nimport { Icon } from '@/icons/Icon.js';\nimport { useCatalogServer } from '../../server/ServerContext.js';\nimport type { RegistrySkill, SkillBase, SkillCatalogEntry, SkillConfigBase } from '../../server/types.js';\nimport { getErrorMessage } from '../../utils/getErrorMessage.js';\nimport { useToasterOptional } from '../ToasterContainer.js';\nimport ImportGithubSkillForm from './ImportGithubSkillForm.js';\n\nconst matchesQuery = (query: string, name: string, description: string) =>\n !query || name.toLowerCase().includes(query) || description.toLowerCase().includes(query);\n\nconst isRegistrySkill = (skill: SkillBase): skill is RegistrySkill => 'catalogId' in skill;\n\nconst SkillSettings = () => {\n const { skillCatalog } = useCatalogServer();\n const toaster = useToasterOptional();\n\n const [query, setQuery] = useState('');\n const [skills, setSkills] = useState<SkillBase[]>([]);\n const [catalog, setCatalog] = useState<SkillCatalogEntry[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const [importOpen, setImportOpen] = useState(false);\n\n const refresh = useCallback(async () => {\n if (!skillCatalog) return;\n setLoading(true);\n setError(null);\n try {\n const [defined, available] = await Promise.all([skillCatalog.listSkills(), skillCatalog.getSkillCatalog()]);\n setSkills(defined);\n setCatalog(available);\n } catch (err) {\n setError(getErrorMessage(err, 'Failed to load skills'));\n } finally {\n setLoading(false);\n }\n }, [skillCatalog]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const normalizedQuery = query.trim().toLowerCase();\n\n const selectedSkills = useMemo(\n () => skills.filter(skill => matchesQuery(normalizedQuery, skill.name, skill.description)),\n [skills, normalizedQuery],\n );\n\n const availableSkills = useMemo(() => {\n const selectedCatalogIds = new Set(skills.flatMap(skill => (isRegistrySkill(skill) ? [skill.catalogId] : [])));\n return catalog.filter(\n entry => !selectedCatalogIds.has(entry.id) && matchesQuery(normalizedQuery, entry.name, entry.description),\n );\n }, [catalog, skills, normalizedQuery]);\n\n const runMutation = async (fn: () => Promise<void>, setMutationError = setError) => {\n setBusy(true);\n setError(null);\n try {\n await fn();\n await refresh();\n } catch (err) {\n setMutationError(getErrorMessage(err, 'Request failed'));\n throw err;\n } finally {\n setBusy(false);\n }\n };\n\n if (!skillCatalog) {\n return <p className=\"text-sm text-text-secondary\">Skills catalog is not available.</p>;\n }\n\n const handleSelect = (entry: SkillCatalogEntry) => {\n void runMutation(async () => {\n await skillCatalog.createSkill({\n catalogId: entry.id,\n name: entry.name,\n description: entry.description,\n repoURL: entry.repoURL,\n path: entry.path,\n ref: entry.ref,\n });\n }).catch(() => {});\n };\n\n const handleRemove = (skill: SkillBase) => {\n const deleteSkill = skillCatalog.deleteSkill;\n if (!deleteSkill) return;\n void runMutation(async () => {\n await deleteSkill({ id: skill.id });\n }).catch(() => {});\n };\n\n const handleImport = async (draft: SkillConfigBase) => {\n setFormError(null);\n await runMutation(async () => {\n await skillCatalog.createSkill(draft);\n }, setFormError);\n setTimeout(() => {\n toaster?.showSuccess({ title: `${draft.name} imported` });\n }, 0);\n };\n\n const renderRow = ({\n key,\n name,\n description,\n action,\n }: {\n key: string;\n name: string;\n description: string;\n action: ReactNode;\n }) => (\n <article key={key} className=\"flex min-h-16 items-center gap-3 border-b border-border p-3 last:border-b-0\">\n <span\n className=\"flex size-9 shrink-0 items-center justify-center rounded-lg border border-border bg-secondary-bg\"\n aria-hidden\n >\n <Icon name=\"lightbulb\" className=\"size-4.5 text-text-primary\" />\n </span>\n\n <div className=\"min-w-0 flex-1\">\n <h5 className=\"truncate text-sm font-medium text-text-primary\">{name}</h5>\n {description ? <p className=\"mt-0.5 truncate text-sm text-text-secondary\">{description}</p> : null}\n </div>\n\n {action}\n </article>\n );\n\n const hasMatches = selectedSkills.length > 0 || availableSkills.length > 0;\n\n return (\n <>\n <h3 className=\"text-xl font-semibold tracking-tight text-text-primary\">Skills</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">Use built-in skills or import custom skills from GitHub.</p>\n\n {error ? (\n <p className=\"mt-3 rounded-md border border-failure-bg/30 bg-failure-bg/10 px-3 py-2 text-sm text-failure-bg\">\n {error}\n </p>\n ) : null}\n\n <div className=\"mt-4 flex min-h-0 flex-1 flex-col gap-3\">\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <div className=\"min-w-0 flex-1\">\n <SearchInput query={query} setQuery={setQuery} placeholder=\"Search skills\" />\n </div>\n <Button\n variant=\"secondary\"\n type=\"button\"\n className=\"shrink-0\"\n disabled={busy}\n onClick={() => {\n setFormError(null);\n setImportOpen(true);\n }}\n >\n <Icon name=\"github\" className=\"size-4\" />\n Import from GitHub\n </Button>\n </div>\n\n <div className=\"flex flex-1 flex-col gap-5 overflow-y-auto pb-1\">\n {loading ? <p className=\"py-8 text-center text-sm text-text-secondary\">Loading…</p> : null}\n\n {!loading && selectedSkills.length > 0 ? (\n <section aria-labelledby=\"enabled-skills-heading\">\n <h4\n id=\"enabled-skills-heading\"\n className=\"mb-2 text-[0.8125rem] font-semibold uppercase text-text-secondary\"\n >\n Enabled · {selectedSkills.length}\n </h4>\n <div className=\"overflow-hidden rounded-xl border border-border bg-card-bg\">\n {selectedSkills.map(skill =>\n renderRow({\n key: skill.id,\n name: skill.name,\n description: skill.description,\n action: skillCatalog.deleteSkill ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n disabled={busy}\n aria-label={`Remove ${skill.name}`}\n onClick={() => {\n handleRemove(skill);\n }}\n >\n Remove\n </Button>\n ) : null,\n }),\n )}\n </div>\n </section>\n ) : null}\n\n {!loading && availableSkills.length > 0 ? (\n <section aria-labelledby=\"available-skills-heading\">\n <h4\n id=\"available-skills-heading\"\n className=\"mb-2 text-[0.8125rem] font-semibold uppercase text-text-secondary\"\n >\n Available · {availableSkills.length}\n </h4>\n <div className=\"overflow-hidden rounded-xl border border-border bg-card-bg\">\n {availableSkills.map(entry =>\n renderRow({\n key: entry.id,\n name: entry.name,\n description: entry.description,\n action: (\n <Button\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n disabled={busy}\n aria-label={`Enable ${entry.name}`}\n onClick={() => {\n handleSelect(entry);\n }}\n >\n Enable\n </Button>\n ),\n }),\n )}\n </div>\n </section>\n ) : null}\n\n {!loading && !hasMatches ? (\n <div className=\"flex flex-1 items-center justify-center rounded-xl border border-dashed border-border p-8 text-center text-sm text-text-secondary\">\n {normalizedQuery ? `No skills match “${query.trim()}”.` : 'No skills yet.'}\n </div>\n ) : null}\n </div>\n </div>\n\n <ImportGithubSkillForm\n open={importOpen}\n onOpenChange={open => {\n setImportOpen(open);\n if (!open) setFormError(null);\n }}\n onImport={handleImport}\n busy={busy}\n error={formError}\n />\n </>\n );\n};\n\nexport default SkillSettings;\n","'use client';\n\nimport { useState, type SyntheticEvent } from 'react';\n\nimport { auiInputClass } from '@/atoms/lib/inputClasses.js';\nimport { Button } from '@/atoms/primitives/Button.js';\nimport { CenteredModal } from '@/atoms/primitives/CenteredModal.js';\nimport { Icon } from '@/icons/Icon.js';\nimport type { SkillConfigBase } from '../../server/types.js';\n\ntype ImportGithubSkillFormProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onImport: (draft: SkillConfigBase) => void | Promise<void>;\n busy?: boolean;\n error?: string | null;\n};\n\nconst ImportGithubSkillForm = ({ open, onOpenChange, onImport, busy = false, error }: ImportGithubSkillFormProps) => {\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [repoURL, setRepoURL] = useState('');\n const [path, setPath] = useState('');\n const [ref, setRef] = useState('');\n\n const reset = () => {\n setName('');\n setDescription('');\n setRepoURL('');\n setPath('');\n setRef('');\n };\n\n const close = () => {\n reset();\n onOpenChange(false);\n };\n\n const handleSubmit = async (event: SyntheticEvent<HTMLFormElement, SubmitEvent>) => {\n event.preventDefault();\n if (!name.trim() || !description.trim() || !repoURL.trim() || !path.trim() || !ref.trim() || busy) return;\n\n try {\n await onImport({\n name: name.trim(),\n description: description.trim(),\n repoURL: repoURL.trim(),\n path: path.trim(),\n ref: ref.trim(),\n });\n close();\n } catch {\n // Parent surfaces error; keep form open.\n }\n };\n\n const canImport = Boolean(name.trim() && description.trim() && repoURL.trim() && path.trim() && ref.trim()) && !busy;\n\n return (\n <CenteredModal\n open={open}\n onOpenChange={nextOpen => {\n if (!nextOpen) close();\n }}\n title=\"Import from GitHub\"\n description=\"Import a skill from a SKILL.md file in a GitHub repository.\"\n headerIcon={\n <span className=\"flex size-11 shrink-0 items-center justify-center rounded-lg border border-border bg-secondary-bg text-text-primary\">\n <Icon name=\"github\" className=\"size-5\" />\n </span>\n }\n contentSized\n className=\"md:max-w-2xl\"\n >\n <form onSubmit={e => void handleSubmit(e)}>\n <div className=\"space-y-5 px-5 py-5 md:px-6\">\n <div>\n <label htmlFor=\"skill-name\" className=\"mb-2 block text-sm font-semibold text-text-primary\">\n Name\n </label>\n <input\n id=\"skill-name\"\n value={name}\n onChange={event => {\n setName(event.target.value);\n }}\n placeholder=\"release-notes\"\n autoFocus\n required\n className={auiInputClass('h-11')}\n />\n </div>\n\n <div>\n <label htmlFor=\"skill-description\" className=\"mb-2 block text-sm font-semibold text-text-primary\">\n Description\n </label>\n <textarea\n id=\"skill-description\"\n value={description}\n onChange={event => {\n setDescription(event.target.value);\n }}\n placeholder=\"Generate release notes from merged pull requests\"\n required\n rows={3}\n className={auiInputClass('resize-y py-2.5')}\n />\n </div>\n\n <div>\n <label htmlFor=\"skill-repo-url\" className=\"mb-2 block text-sm font-semibold text-text-primary\">\n Repository URL\n </label>\n <input\n id=\"skill-repo-url\"\n type=\"url\"\n value={repoURL}\n onChange={event => {\n setRepoURL(event.target.value);\n }}\n placeholder=\"https://github.com/org/repo\"\n required\n className={auiInputClass('h-11')}\n />\n </div>\n\n <div>\n <label htmlFor=\"skill-path\" className=\"mb-2 block text-sm font-semibold text-text-primary\">\n Folder containing the SKILL.md\n </label>\n <input\n id=\"skill-path\"\n value={path}\n onChange={event => {\n setPath(event.target.value);\n }}\n placeholder=\"skills/release-notes\"\n required\n className={auiInputClass('h-11')}\n />\n </div>\n\n <div>\n <label htmlFor=\"skill-ref\" className=\"mb-2 block text-sm font-semibold text-text-primary\">\n Branch\n </label>\n <input\n id=\"skill-ref\"\n value={ref}\n onChange={event => {\n setRef(event.target.value);\n }}\n placeholder=\"main\"\n required\n className={auiInputClass('h-11')}\n />\n </div>\n\n <div className=\"space-y-3\">\n {error ? <p className=\"text-failure-bg text-sm\">{error}</p> : null}\n <Button type=\"submit\" disabled={!canImport} className=\"w-full\">\n Import\n </Button>\n </div>\n </div>\n </form>\n </CenteredModal>\n );\n};\n\nexport default ImportGithubSkillForm;\n"],"mappings":"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","names":["useState","jsx","jsxs","useState"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/atoms/schedules/SchedulesPage.tsx","../src/atoms/schedules/cadence.ts","../src/atoms/schedules/ScheduleFormDrawer.tsx","../src/atoms/schedules/ScheduleFormFields.tsx","../src/atoms/schedules/TestScheduleScreen.tsx","../src/atoms/schedules/scheduleRuns.ts","../src/atoms/schedules/ScheduleRunTooltip.tsx","../src/atoms/schedules/ScheduleRunChip.tsx","../src/atoms/schedules/ScheduleStatusBadge.tsx","../src/atoms/schedules/ScheduleLastRunsCell.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useToasterOptional } from '../../containers/ToasterContainer.js';\nimport { Icon } from '../../icons/Icon.js';\nimport { useScheduleServer, useServer } from '../../server/ServerContext.js';\nimport { libraryAgentId } from '../../server/ShellModeContext.js';\nimport type { Schedule, ScheduleRun, ScheduleStatus } from '../../server/types.js';\nimport { readScheduleShareSearch, replaceScheduleShareSearch } from '../../utils/scheduleShareUrl.js';\nimport { EmptyScreen } from '../EmptyScreen.js';\nimport { auiButtonClass } from '../lib/buttonClasses.js';\nimport { cn } from '../lib/cn.js';\nimport { searchAllAgents } from '../lib/useSearchAgentsList.js';\nimport { PageHeader } from '../PageHeader.js';\nimport { Button } from '../primitives/Button.js';\nimport { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '../primitives/Dialog.js';\nimport { DropdownMenu, DropdownMenuItem } from '../primitives/DropdownMenu.js';\nimport { PopoverSelect } from '../primitives/PopoverSelect.js';\nimport SearchInput from '../primitives/SearchInput.js';\nimport { Skeleton } from '../primitives/Skeleton.js';\nimport {\n DEFAULT_TABLE_PAGE_SIZE,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n TableTokenPagination,\n} from '../primitives/Table.js';\nimport { formatCadenceSummary } from './cadence.js';\nimport { ScheduleFormDrawer } from './ScheduleFormDrawer.js';\nimport { ScheduleLastRunsCell } from './ScheduleLastRunsCell.js';\nimport { ScheduleStatusBadge } from './ScheduleStatusBadge.js';\n\ntype AgentOption = { agentId: string; name: string };\n\ntype DrawerState = { kind: 'closed' } | { kind: 'create'; agentId?: string } | { kind: 'edit'; schedule: Schedule };\n\nconst STATUS_FILTER_OPTIONS: Array<{ value: 'all' | ScheduleStatus; label: string }> = [\n { value: 'all', label: 'All statuses' },\n { value: 'active', label: 'Active' },\n { value: 'paused', label: 'Paused' },\n];\n\n/** API max page size for schedules list. */\nconst SCHEDULES_PAGE_SIZE_OPTIONS = [10, 25] as const;\n\nfunction clampPageSize(size: number): number {\n return Math.min(Math.max(size, 1), 25);\n}\n\nfunction filtersFromSearch(search: string): {\n nameQuery: string;\n statusFilter: 'all' | ScheduleStatus;\n agentFilter: string;\n} {\n const share = readScheduleShareSearch(search);\n return {\n nameQuery: share.q ?? '',\n statusFilter: share.status ?? 'all',\n agentFilter: share.agent ?? 'all',\n };\n}\n\nfunction ScheduleRowActions({\n schedule,\n running,\n onRunNow,\n onEdit,\n onTogglePause,\n onDelete,\n}: {\n schedule: Schedule;\n running: boolean;\n onRunNow: () => void;\n onEdit: () => void;\n onTogglePause: () => void;\n onDelete: () => void;\n}) {\n return (\n <div className=\"inline-flex items-center justify-end gap-1.5\">\n <button\n type=\"button\"\n disabled={running}\n aria-label={`Run now ${schedule.name}`}\n className={auiButtonClass({ variant: 'outline', size: 'sm' })}\n onClick={onRunNow}\n >\n <Icon name={running ? 'loader' : 'play'} className={cn('size-3.5', running && 'animate-spin')} />\n Run now\n </button>\n <DropdownMenu\n align=\"end\"\n trigger={\n <button\n type=\"button\"\n className={auiButtonClass({ variant: 'ghost', size: 'icon' })}\n aria-label={`Actions for ${schedule.name}`}\n >\n <Icon name=\"ellipsis\" className=\"size-4\" />\n </button>\n }\n >\n <DropdownMenuItem onClick={onEdit}>\n <Icon name=\"pencil\" className=\"size-3.5\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onTogglePause}>\n <Icon name={schedule.status === 'active' ? 'pause' : 'play'} className=\"size-3.5\" />\n {schedule.status === 'active' ? 'Pause' : 'Resume'}\n </DropdownMenuItem>\n <DropdownMenuItem className=\"text-failure-bg focus:text-failure-bg\" onClick={onDelete}>\n <Icon name=\"trash\" className=\"size-3.5\" />\n Delete\n </DropdownMenuItem>\n </DropdownMenu>\n </div>\n );\n}\n\nexport function SchedulesPage() {\n const scheduleServer = useScheduleServer();\n const server = useServer();\n const toaster = useToasterOptional();\n\n const [schedules, setSchedules] = useState<Schedule[]>([]);\n const [runsByScheduleId, setRunsByScheduleId] = useState<Record<string, ScheduleRun[]>>({});\n const [runsLoading, setRunsLoading] = useState(false);\n const [runningScheduleIds, setRunningScheduleIds] = useState<ReadonlySet<string>>(() => new Set());\n const [agentOptions, setAgentOptions] = useState<AgentOption[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [nameQuery, setNameQuery] = useState(() => filtersFromSearch(window.location.search).nameQuery);\n const [statusFilter, setStatusFilter] = useState<'all' | ScheduleStatus>(\n () => filtersFromSearch(window.location.search).statusFilter,\n );\n const [agentFilter, setAgentFilter] = useState(() => filtersFromSearch(window.location.search).agentFilter);\n const [drawer, setDrawer] = useState<DrawerState>({ kind: 'closed' });\n const [pendingDelete, setPendingDelete] = useState<Schedule | null>(null);\n const [pageSize, setPageSize] = useState(() => clampPageSize(DEFAULT_TABLE_PAGE_SIZE));\n const [pageToken, setPageToken] = useState<string | undefined>(undefined);\n const [nextPageToken, setNextPageToken] = useState<string | undefined>(undefined);\n const [prevTokenStack, setPrevTokenStack] = useState<string[]>([]);\n const loadGenRef = useRef(0);\n const didConsumeIsNewRef = useRef(false);\n\n const loadRunsForSchedules = useCallback(\n async ({ rows, gen }: { rows: Schedule[]; gen: number }) => {\n if (rows.length === 0) {\n if (gen === loadGenRef.current) setRunsByScheduleId({});\n return;\n }\n setRunsLoading(true);\n try {\n const results = await Promise.allSettled(\n rows.map(schedule => scheduleServer.listScheduleRuns({ scheduleId: schedule.id })),\n );\n if (gen !== loadGenRef.current) return;\n setRunsByScheduleId(\n Object.fromEntries(\n rows.map((schedule, index) => {\n const result = results[index];\n const runs = result?.status === 'fulfilled' ? result.value : [];\n return [schedule.id, runs] as const;\n }),\n ),\n );\n } finally {\n if (gen === loadGenRef.current) setRunsLoading(false);\n }\n },\n [scheduleServer],\n );\n\n const loadSchedules = useCallback(\n async ({ token, size, agentId }: { token: string | undefined; size: number; agentId: string }) => {\n const gen = ++loadGenRef.current;\n setLoading(true);\n setError(null);\n try {\n const page = await scheduleServer.listSchedules({\n limit: clampPageSize(size),\n ...(token === undefined || token === '' ? {} : { pageToken: token }),\n ...(agentId === 'all' ? {} : { agentIds: [agentId] }),\n });\n if (gen !== loadGenRef.current) return;\n setSchedules(page.data);\n setNextPageToken(page.nextPageToken);\n void loadRunsForSchedules({ rows: page.data, gen });\n } catch (caught) {\n if (gen !== loadGenRef.current) return;\n const message = caught instanceof Error ? caught.message : 'Failed to load schedules';\n setError(message);\n setSchedules([]);\n setRunsByScheduleId({});\n setNextPageToken(undefined);\n } finally {\n if (gen === loadGenRef.current) setLoading(false);\n }\n },\n [scheduleServer, loadRunsForSchedules],\n );\n\n const resetToFirstPage = useCallback(\n (next?: { size?: number; agentId?: string }) => {\n const size = next?.size ?? pageSize;\n const agentId = next?.agentId ?? agentFilter;\n setPageToken(undefined);\n setPrevTokenStack([]);\n void loadSchedules({ token: undefined, size, agentId });\n },\n [agentFilter, loadSchedules, pageSize],\n );\n\n // Keep filters in the URL so deep links and Agents → Schedules work.\n useEffect(() => {\n replaceScheduleShareSearch({\n agent: agentFilter === 'all' ? null : agentFilter,\n status: statusFilter === 'all' ? null : statusFilter,\n q: nameQuery.trim().length === 0 ? null : nameQuery,\n });\n }, [agentFilter, statusFilter, nameQuery]);\n\n // One-shot: Agents \"+ Schedule\" lands with isNew=true; open create then strip the flag.\n useEffect(() => {\n if (didConsumeIsNewRef.current) return;\n const share = readScheduleShareSearch(window.location.search);\n if (!share.isNew) return;\n didConsumeIsNewRef.current = true;\n setDrawer({\n kind: 'create',\n ...(share.agent != null ? { agentId: share.agent } : {}),\n });\n replaceScheduleShareSearch({ isNew: null });\n }, []);\n\n useEffect(() => {\n const syncFromUrl = () => {\n const next = filtersFromSearch(window.location.search);\n setNameQuery(next.nameQuery);\n setStatusFilter(next.statusFilter);\n setAgentFilter(current => {\n if (current === next.agentFilter) return current;\n setPageToken(undefined);\n setPrevTokenStack([]);\n return next.agentFilter;\n });\n };\n window.addEventListener('popstate', syncFromUrl);\n return () => {\n window.removeEventListener('popstate', syncFromUrl);\n };\n }, []);\n\n useEffect(() => {\n void loadSchedules({ token: pageToken, size: pageSize, agentId: agentFilter });\n }, [agentFilter, pageSize, pageToken, loadSchedules]);\n\n useEffect(() => {\n let cancelled = false;\n void searchAllAgents(server)\n .then(rows => {\n if (cancelled) return;\n setAgentOptions(rows.map(agent => ({ agentId: libraryAgentId(agent), name: agent.name })));\n })\n .catch(() => undefined);\n return () => {\n cancelled = true;\n };\n }, [server]);\n\n const agentNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const agent of agentOptions) {\n map.set(agent.agentId, agent.name);\n }\n return map;\n }, [agentOptions]);\n\n // Name + status are client-side on the current server page only.\n const filtered = useMemo(() => {\n const q = nameQuery.trim().toLowerCase();\n return schedules.filter(schedule => {\n if (statusFilter !== 'all' && schedule.status !== statusFilter) return false;\n if (q.length > 0 && !schedule.name.toLowerCase().includes(q)) return false;\n return true;\n });\n }, [schedules, nameQuery, statusFilter]);\n\n const hasPageNav = prevTokenStack.length > 0 || nextPageToken != null;\n\n const handleTogglePause = async (schedule: Schedule) => {\n const nextStatus: ScheduleStatus = schedule.status === 'active' ? 'paused' : 'active';\n try {\n await scheduleServer.updateSchedule({ ...schedule, status: nextStatus });\n await loadSchedules({ token: pageToken, size: pageSize, agentId: agentFilter });\n } catch (caught) {\n toaster?.showError(caught);\n }\n };\n\n const handleRunNow = async (schedule: Schedule) => {\n setRunningScheduleIds(prev => new Set(prev).add(schedule.id));\n try {\n await scheduleServer.createScheduleRun({ scheduleId: schedule.id });\n toaster?.showSuccess({ title: 'Run started' });\n const runs = await scheduleServer.listScheduleRuns({ scheduleId: schedule.id });\n setRunsByScheduleId(prev => ({ ...prev, [schedule.id]: runs }));\n } catch (caught) {\n toaster?.showError(caught);\n } finally {\n setRunningScheduleIds(prev => {\n const next = new Set(prev);\n next.delete(schedule.id);\n return next;\n });\n }\n };\n\n const handleDelete = async (schedule: Schedule) => {\n setPendingDelete(null);\n try {\n await scheduleServer.deleteSchedule({ id: schedule.id });\n resetToFirstPage();\n } catch (caught) {\n toaster?.showError(caught);\n }\n };\n\n const goNext = () => {\n if (nextPageToken == null) return;\n setPrevTokenStack(stack => [...stack, pageToken ?? '']);\n setPageToken(nextPageToken);\n };\n\n const goPrev = () => {\n if (prevTokenStack.length === 0) return;\n const stack = [...prevTokenStack];\n const prev = stack.pop();\n setPrevTokenStack(stack);\n setPageToken(prev === '' ? undefined : prev);\n };\n\n return (\n <div className=\"flex h-full min-h-0 flex-col bg-primary-bg\">\n <PageHeader\n title=\"Scheduled Agents\"\n end={\n <>\n <div className=\"w-full sm:w-56\">\n <SearchInput query={nameQuery} setQuery={setNameQuery} placeholder=\"Search schedules by name\" />\n </div>\n <PopoverSelect\n value={statusFilter}\n onValueChange={setStatusFilter}\n options={STATUS_FILTER_OPTIONS}\n className=\"sm:w-40\"\n aria-label=\"Filter by status\"\n />\n <PopoverSelect\n value={agentFilter}\n onValueChange={value => {\n setAgentFilter(value);\n setPageToken(undefined);\n setPrevTokenStack([]);\n }}\n options={[\n { value: 'all', label: 'All agents' },\n ...agentOptions.map(agent => ({ value: agent.agentId, label: agent.name })),\n ]}\n className=\"sm:w-40\"\n aria-label=\"Filter by agent\"\n />\n <Button\n type=\"button\"\n onClick={() =>\n setDrawer({\n kind: 'create',\n agentId: agentFilter !== 'all' ? agentFilter : undefined,\n })\n }\n >\n <Icon name=\"plus\" className=\"size-3.5\" />\n Create Schedule\n </Button>\n </>\n }\n />\n\n <div className=\"min-h-0 flex-1 overflow-auto px-4 py-4 md:px-6\">\n {loading ? (\n <div className=\"flex flex-col gap-2\" role=\"status\" aria-label=\"Loading schedules\">\n {Array.from({ length: 5 }, (_, i) => (\n <Skeleton key={i} className=\"h-12 w-full rounded-md\" />\n ))}\n </div>\n ) : error != null ? (\n <p className=\"text-failure-bg px-3 py-8 text-center text-sm\">{error}</p>\n ) : schedules.length === 0 ? (\n <EmptyScreen title=\"No Schedules Found\" description=\"Create one to get started.\" className=\"min-h-full\" />\n ) : filtered.length === 0 ? (\n <div className=\"flex min-h-full flex-col\">\n <EmptyScreen title=\"No Schedules Found\" description=\"No schedules match your filters.\" className=\"flex-1\" />\n {hasPageNav ? (\n <TableTokenPagination\n pageSize={pageSize}\n rowCount={0}\n canPrev={prevTokenStack.length > 0}\n canNext={nextPageToken != null}\n onPrev={goPrev}\n onNext={goNext}\n pageSizeOptions={SCHEDULES_PAGE_SIZE_OPTIONS}\n onPageSizeChange={size => {\n const next = clampPageSize(size);\n setPageSize(next);\n setPageToken(undefined);\n setPrevTokenStack([]);\n }}\n />\n ) : null}\n </div>\n ) : (\n <div className=\"rounded-lg border border-border\">\n <Table className=\"min-w-[48rem]\">\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead>Name</TableHead>\n <TableHead>Agent</TableHead>\n <TableHead>Cadence</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Last 5 runs</TableHead>\n <TableHead>\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {filtered.map(schedule => {\n const cadence = formatCadenceSummary({ cron: schedule.cron, timezone: schedule.timezone });\n const agentLabel = schedule.agentName ?? agentNameById.get(schedule.agentId) ?? schedule.agentId;\n return (\n <TableRow key={schedule.id}>\n <TableCell className=\"text-text-primary font-medium\">\n <button\n type=\"button\"\n className=\"text-primary-button-bg hover:underline text-left\"\n onClick={() => setDrawer({ kind: 'edit', schedule })}\n >\n {schedule.name}\n </button>\n </TableCell>\n <TableCell>{agentLabel}</TableCell>\n <TableCell>{cadence}</TableCell>\n <TableCell>\n <ScheduleStatusBadge status={schedule.status} />\n </TableCell>\n <TableCell>\n {runsLoading ? (\n <span className=\"text-text-secondary text-sm\">…</span>\n ) : (\n <ScheduleLastRunsCell runs={runsByScheduleId[schedule.id] ?? []} />\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n <ScheduleRowActions\n schedule={schedule}\n running={runningScheduleIds.has(schedule.id)}\n onRunNow={() => void handleRunNow(schedule)}\n onEdit={() => setDrawer({ kind: 'edit', schedule })}\n onTogglePause={() => void handleTogglePause(schedule)}\n onDelete={() => setPendingDelete(schedule)}\n />\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n {(filtered.length > 0 || hasPageNav) && (\n <TableTokenPagination\n pageSize={pageSize}\n rowCount={filtered.length}\n canPrev={prevTokenStack.length > 0}\n canNext={nextPageToken != null}\n onPrev={goPrev}\n onNext={goNext}\n pageSizeOptions={SCHEDULES_PAGE_SIZE_OPTIONS}\n onPageSizeChange={size => {\n const next = clampPageSize(size);\n setPageSize(next);\n setPageToken(undefined);\n setPrevTokenStack([]);\n }}\n />\n )}\n </div>\n )}\n </div>\n\n {drawer.kind === 'create' ? (\n <ScheduleFormDrawer\n open\n mode=\"create\"\n initialAgentId={drawer.agentId ?? ''}\n onOpenChange={open => {\n if (!open) setDrawer({ kind: 'closed' });\n }}\n onSaved={() => resetToFirstPage()}\n />\n ) : null}\n {drawer.kind === 'edit' ? (\n <ScheduleFormDrawer\n open\n mode=\"edit\"\n schedule={drawer.schedule}\n onOpenChange={open => {\n if (!open) setDrawer({ kind: 'closed' });\n }}\n onSaved={() => void loadSchedules({ token: pageToken, size: pageSize, agentId: agentFilter })}\n />\n ) : null}\n {pendingDelete != null ? (\n <Dialog\n open\n onOpenChange={open => {\n if (!open) setPendingDelete(null);\n }}\n aria-label=\"Delete schedule\"\n className=\"max-w-md\"\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete schedule</DialogTitle>\n <p className=\"text-text-secondary text-sm\">\n “{pendingDelete.name}” will stop running. This cannot be undone.\n </p>\n </DialogHeader>\n </DialogContent>\n <DialogFooter>\n <Button type=\"button\" variant=\"secondary\" onClick={() => setPendingDelete(null)}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={() => void handleDelete(pendingDelete)}>\n Delete\n </Button>\n </DialogFooter>\n </Dialog>\n ) : null}\n </div>\n );\n}\n","export type RecurrenceKind = 'hourly' | 'daily' | 'weekly' | 'custom';\n\nexport type ScheduleFormValues = {\n name: string;\n task: string;\n recurrence: RecurrenceKind;\n hour: number;\n minute: number;\n /** Cron DOW: 0=Sun … 6=Sat. Used when recurrence is weekly. */\n weekdays: number[];\n customCron: string;\n timezone: string;\n};\n\nexport const TIMEZONE_OPTIONS = [\n { value: 'America/New_York', label: 'America/New_York (ET)' },\n { value: 'America/Chicago', label: 'America/Chicago (CT)' },\n { value: 'America/Denver', label: 'America/Denver (MT)' },\n { value: 'America/Los_Angeles', label: 'America/Los_Angeles (PT)' },\n { value: 'UTC', label: 'UTC' },\n { value: 'Europe/London', label: 'Europe/London (GMT/BST)' },\n { value: 'Europe/Berlin', label: 'Europe/Berlin (CET)' },\n { value: 'Asia/Kolkata', label: 'Asia/Kolkata (IST)' },\n { value: 'Asia/Tokyo', label: 'Asia/Tokyo (JST)' },\n] as const;\n\nexport function resolveLocalTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n } catch {\n return 'UTC';\n }\n}\n\nexport function getTimezoneOptions(selectedTimezone?: string): Array<{ value: string; label: string }> {\n const localTimezone = resolveLocalTimezone();\n const knownTimezones = new Set<string>(TIMEZONE_OPTIONS.map(option => option.value));\n // Keep both browser-local and persisted zones selectable even when they are\n // outside the curated common-timezone list.\n const additionalTimezones = [localTimezone, selectedTimezone].flatMap(timezone => {\n if (timezone == null || timezone.length === 0 || knownTimezones.has(timezone)) return [];\n knownTimezones.add(timezone);\n return [{ value: timezone, label: timezone === localTimezone ? `${timezone} (Local)` : timezone }];\n });\n return [...additionalTimezones, ...TIMEZONE_OPTIONS];\n}\n\nexport const WEEKDAY_OPTIONS = [\n { value: 1, label: 'Mon' },\n { value: 2, label: 'Tue' },\n { value: 3, label: 'Wed' },\n { value: 4, label: 'Thu' },\n { value: 5, label: 'Fri' },\n { value: 6, label: 'Sat' },\n { value: 0, label: 'Sun' },\n] as const;\n\nconst TZ_ABBR: Record<string, string> = {\n 'America/New_York': 'ET',\n 'America/Chicago': 'CT',\n 'America/Denver': 'MT',\n 'America/Los_Angeles': 'PT',\n UTC: 'UTC',\n 'Europe/London': 'GMT',\n 'Europe/Berlin': 'CET',\n 'Asia/Kolkata': 'IST',\n 'Asia/Tokyo': 'JST',\n};\n\nexport function defaultScheduleFormValues(): ScheduleFormValues {\n return {\n name: '',\n task: '',\n recurrence: 'daily',\n hour: 9,\n minute: 0,\n weekdays: [1],\n customCron: '0 9 * * *',\n timezone: resolveLocalTimezone(),\n };\n}\n\nexport function timezoneAbbrev(timezone: string): string {\n return TZ_ABBR[timezone] ?? timezone.split('/').pop() ?? timezone;\n}\n\nfunction pad2(n: number): string {\n return n.toString().padStart(2, '0');\n}\n\nfunction formatClock({ hour, minute }: { hour: number; minute: number }): string {\n const period = hour >= 12 ? 'PM' : 'AM';\n const h12 = hour % 12 === 0 ? 12 : hour % 12;\n return `${String(h12)}:${pad2(minute)} ${period}`;\n}\n\nexport function valuesToCron(values: ScheduleFormValues): string {\n const minute = values.minute;\n const hour = values.hour;\n switch (values.recurrence) {\n case 'hourly':\n return `${String(minute)} * * * *`;\n case 'daily':\n return `${String(minute)} ${String(hour)} * * *`;\n case 'weekly': {\n const days = [...values.weekdays].sort((a, b) => a - b);\n const dow = days.length > 0 ? days.join(',') : '*';\n return `${String(minute)} ${String(hour)} * * ${dow}`;\n }\n case 'custom':\n return values.customCron.trim();\n }\n}\n\nexport function formatCadenceSummary(input: { cron: string; timezone: string }): string {\n const abbr = timezoneAbbrev(input.timezone);\n const parts = input.cron.trim().split(/\\s+/);\n if (parts.length !== 5) return input.cron;\n\n const [minuteRaw, hourRaw, dayOfMonthRaw, monthRaw, dowRaw] = parts;\n if (dayOfMonthRaw !== '*' || monthRaw !== '*') return input.cron;\n\n const minute = Number(minuteRaw);\n const hour = Number(hourRaw);\n\n if (hourRaw === '*' && dowRaw === '*' && minuteRaw !== undefined && !Number.isNaN(minute)) {\n return `Hourly at :${pad2(minute)} ${abbr}`;\n }\n\n if (\n dowRaw === '*' &&\n hourRaw !== undefined &&\n minuteRaw !== undefined &&\n !Number.isNaN(hour) &&\n !Number.isNaN(minute)\n ) {\n return `Daily ${formatClock({ hour, minute })} ${abbr}`;\n }\n\n if (\n dowRaw === '1-5' &&\n hourRaw !== undefined &&\n minuteRaw !== undefined &&\n !Number.isNaN(hour) &&\n !Number.isNaN(minute)\n ) {\n return `Weekdays ${formatClock({ hour, minute })} ${abbr}`;\n }\n\n if (\n dowRaw != null &&\n /^\\d(?:,\\d)*$/.test(dowRaw) &&\n hourRaw !== undefined &&\n minuteRaw !== undefined &&\n !Number.isNaN(hour) &&\n !Number.isNaN(minute)\n ) {\n const labels = dowRaw.split(',').map(d => WEEKDAY_OPTIONS.find(w => w.value === Number(d))?.label ?? d);\n if (labels.length === 1) {\n const day = labels[0] === 'Mon' ? 'Monday' : labels[0];\n return `Every ${day} ${formatClock({ hour, minute })} ${abbr}`;\n }\n return `${labels.join(', ')} ${formatClock({ hour, minute })} ${abbr}`;\n }\n\n return input.cron;\n}\n\n/** Best-effort parse of known patterns into form values for edit. */\nexport function cronToFormValues(input: {\n name: string;\n task: string;\n cron: string;\n timezone: string;\n}): ScheduleFormValues {\n const base = defaultScheduleFormValues();\n const parts = input.cron.trim().split(/\\s+/);\n if (parts.length !== 5) {\n return {\n ...base,\n name: input.name,\n task: input.task,\n timezone: input.timezone,\n recurrence: 'custom',\n customCron: input.cron,\n };\n }\n\n const [minuteRaw, hourRaw, dom, month, dowRaw] = parts;\n const minute = Number(minuteRaw);\n const hour = Number(hourRaw);\n\n if (dom !== '*' || month !== '*') {\n return {\n ...base,\n name: input.name,\n task: input.task,\n timezone: input.timezone,\n recurrence: 'custom',\n customCron: input.cron,\n };\n }\n\n if (hourRaw === '*' && dowRaw === '*' && !Number.isNaN(minute)) {\n return {\n ...base,\n name: input.name,\n task: input.task,\n timezone: input.timezone,\n recurrence: 'hourly',\n minute,\n customCron: input.cron,\n };\n }\n\n if (dowRaw === '*' && !Number.isNaN(hour) && !Number.isNaN(minute)) {\n return {\n ...base,\n name: input.name,\n task: input.task,\n timezone: input.timezone,\n recurrence: 'daily',\n hour,\n minute,\n customCron: input.cron,\n };\n }\n\n if (dowRaw != null && /^\\d(?:,\\d)*$/.test(dowRaw) && !Number.isNaN(hour) && !Number.isNaN(minute)) {\n return {\n ...base,\n name: input.name,\n task: input.task,\n timezone: input.timezone,\n recurrence: 'weekly',\n hour,\n minute,\n weekdays: dowRaw.split(',').map(Number),\n customCron: input.cron,\n };\n }\n\n // Weekdays 1-5 → treat as custom so the cron string is preserved on save.\n return {\n ...base,\n name: input.name,\n task: input.task,\n timezone: input.timezone,\n recurrence: 'custom',\n customCron: input.cron,\n hour: Number.isNaN(hour) ? base.hour : hour,\n minute: Number.isNaN(minute) ? base.minute : minute,\n };\n}\n\nexport function formatRelativeTime(iso: string | null, nowMs = Date.now()): string {\n if (iso == null) return 'Never';\n const then = Date.parse(iso);\n if (Number.isNaN(then)) return 'Never';\n const deltaSec = Math.round((nowMs - then) / 1000);\n if (deltaSec < 60) return 'just now';\n const mins = Math.round(deltaSec / 60);\n if (mins < 60) return `${String(mins)} min ago`;\n const hours = Math.round(mins / 60);\n if (hours < 48) return `${String(hours)} hour${hours === 1 ? '' : 's'} ago`;\n const days = Math.round(hours / 24);\n return `${String(days)} day${days === 1 ? '' : 's'} ago`;\n}\n","'use client';\n\nimport { useEffect, useMemo, useState, type FormEvent, type ReactNode } from 'react';\n\nimport { useToasterOptional } from '../../containers/ToasterContainer.js';\nimport { Icon } from '../../icons/Icon.js';\nimport { useScheduleServer, useServer } from '../../server/ServerContext.js';\nimport { libraryAgentId } from '../../server/ShellModeContext.js';\nimport type { AgentLibraryEntry, Schedule } from '../../server/types.js';\nimport { DraftCatalogProvider } from '../draft/DraftCatalogProvider.js';\nimport { mountName } from '../lib/mountName.js';\nimport { searchAllAgents } from '../lib/useSearchAgentsList.js';\nimport { Button } from '../primitives/Button.js';\nimport { SideDrawer } from '../primitives/SideDrawer.js';\nimport {\n cronToFormValues,\n defaultScheduleFormValues,\n formatCadenceSummary,\n valuesToCron,\n type ScheduleFormValues,\n} from './cadence.js';\nimport { ScheduleFormFields } from './ScheduleFormFields.js';\nimport { TestScheduleScreen } from './TestScheduleScreen.js';\n\nexport type ScheduleFormDrawerProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n mode: 'create' | 'edit';\n schedule?: Schedule;\n initialAgentId?: string;\n onSaved?: () => void;\n};\n\ntype DrawerView = { kind: 'form'; saved?: Schedule } | { kind: 'test'; schedule: Schedule };\n\nfunction ScheduleFormDrawerBody({\n open,\n onOpenChange,\n mode,\n schedule,\n initialAgentId = '',\n onSaved,\n}: ScheduleFormDrawerProps) {\n const scheduleServer = useScheduleServer();\n const server = useServer();\n const toaster = useToasterOptional();\n const [form, setForm] = useState<ScheduleFormValues>(defaultScheduleFormValues);\n const [agentId, setAgentId] = useState(initialAgentId);\n const [agents, setAgents] = useState<AgentLibraryEntry[]>([]);\n const [view, setView] = useState<DrawerView>({ kind: 'form' });\n const [saving, setSaving] = useState(false);\n const [activating, setActivating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const savedFromCreate = view.kind === 'form' ? view.saved : view.schedule;\n const isExternalEdit = mode === 'edit' && view.kind === 'form' && view.saved == null && schedule != null;\n const isCreatedEdit = view.kind === 'form' && view.saved != null;\n\n useEffect(() => {\n if (!open) return;\n let cancelled = false;\n void searchAllAgents(server)\n .then(rows => {\n if (cancelled) return;\n setAgents(rows);\n })\n .catch(() => undefined);\n return () => {\n cancelled = true;\n };\n }, [open, server]);\n\n useEffect(() => {\n if (!open) {\n setForm(defaultScheduleFormValues());\n setAgentId(initialAgentId);\n setError(null);\n setView({ kind: 'form' });\n setActivating(false);\n return;\n }\n if (mode === 'edit' && schedule != null) {\n setForm(\n cronToFormValues({\n name: schedule.name,\n task: schedule.task,\n cron: schedule.cron,\n timezone: schedule.timezone,\n }),\n );\n setAgentId(schedule.agentId);\n setView({ kind: 'form' });\n return;\n }\n setForm(defaultScheduleFormValues());\n setAgentId(initialAgentId);\n setView({ kind: 'form' });\n }, [open, mode, schedule, initialAgentId]);\n\n const agentOptions = useMemo(\n () => agents.map(agent => ({ agentId: libraryAgentId(agent), name: agent.name })),\n [agents],\n );\n\n const selectedAgent = useMemo(\n () => agents.find(agent => libraryAgentId(agent) === agentId) ?? null,\n [agents, agentId],\n );\n\n const agentLabel =\n selectedAgent?.name ??\n savedFromCreate?.agentName ??\n schedule?.agentName ??\n agentOptions.find(option => option.agentId === agentId)?.name ??\n agentId;\n\n const mcpMounts = useMemo(() => {\n const mounts = selectedAgent?.agentSpec?.mcpServers ?? [];\n return mounts\n .map(mountName)\n .filter((name: string | null): name is string => name != null)\n .map(name => ({ name }));\n }, [selectedAgent]);\n\n const canSubmit = useMemo(() => {\n const cron = valuesToCron(form);\n return form.name.trim().length > 0 && form.task.trim().length > 0 && cron.length > 0 && agentId.length > 0;\n }, [form, agentId]);\n\n const enterTestView = (saved: Schedule) => {\n setView({ kind: 'test', schedule: saved });\n setForm(\n cronToFormValues({\n name: saved.name,\n task: saved.task,\n cron: saved.cron,\n timezone: saved.timezone,\n }),\n );\n setAgentId(saved.agentId);\n };\n\n const handleSave = async (event: FormEvent) => {\n event.preventDefault();\n if (!canSubmit) return;\n const cron = valuesToCron(form);\n setSaving(true);\n setError(null);\n try {\n if (isExternalEdit && schedule != null) {\n await scheduleServer.updateSchedule({\n id: schedule.id,\n name: form.name.trim(),\n task: form.task.trim(),\n cron,\n timezone: form.timezone,\n status: schedule.status,\n });\n onSaved?.();\n onOpenChange(false);\n return;\n }\n\n if (isCreatedEdit && view.kind === 'form' && view.saved != null) {\n const saved = await scheduleServer.updateSchedule({\n id: view.saved.id,\n name: form.name.trim(),\n task: form.task.trim(),\n cron,\n timezone: form.timezone,\n status: 'paused',\n });\n onSaved?.();\n enterTestView(saved);\n toaster?.showSuccess({\n title: 'Schedule saved as paused',\n description: formatCadenceSummary({ cron: saved.cron, timezone: saved.timezone }),\n });\n return;\n }\n\n const saved = await scheduleServer.createSchedule({\n agentId,\n name: form.name.trim(),\n task: form.task.trim(),\n cron,\n timezone: form.timezone,\n status: 'paused',\n });\n onSaved?.();\n enterTestView(saved);\n toaster?.showSuccess({\n title: 'Schedule saved as paused',\n description: formatCadenceSummary({ cron: saved.cron, timezone: saved.timezone }),\n });\n } catch (caught) {\n const message = caught instanceof Error ? caught.message : 'Failed to save schedule';\n setError(message);\n } finally {\n setSaving(false);\n }\n };\n\n const handleActivate = async () => {\n if (view.kind !== 'test') return;\n setActivating(true);\n setError(null);\n try {\n await scheduleServer.updateSchedule({\n id: view.schedule.id,\n name: view.schedule.name,\n task: view.schedule.task,\n cron: view.schedule.cron,\n timezone: view.schedule.timezone,\n status: 'active',\n });\n onSaved?.();\n toaster?.showSuccess({ title: 'Schedule activated' });\n onOpenChange(false);\n } catch (caught) {\n const message = caught instanceof Error ? caught.message : 'Failed to activate schedule';\n setError(message);\n toaster?.showError(caught);\n } finally {\n setActivating(false);\n }\n };\n\n const title =\n view.kind === 'test' ? 'Test Schedule' : isExternalEdit || isCreatedEdit ? 'Edit Schedule' : 'New Schedule';\n const description =\n view.kind === 'test'\n ? `Recurring unattended runs of ${agentLabel}.`\n : isExternalEdit || isCreatedEdit\n ? 'Update cadence and task for this schedule.'\n : 'Create a recurring unattended run for an agent.';\n\n let footer: ReactNode;\n if (view.kind === 'test') {\n footer = (\n <div className=\"flex flex-col gap-2\">\n {error != null ? <p className=\"text-failure-bg text-sm\">{error}</p> : null}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"w-full\"\n disabled={activating}\n onClick={() => void handleActivate()}\n >\n Activate Anyway\n </Button>\n </div>\n );\n } else {\n footer = (\n <div className=\"flex flex-col gap-2\">\n {error != null ? <p className=\"text-failure-bg text-sm\">{error}</p> : null}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)} disabled={saving}>\n Cancel\n </Button>\n <Button type=\"submit\" form=\"schedule-form\" disabled={!canSubmit || saving}>\n Save\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <SideDrawer\n open={open}\n onOpenChange={onOpenChange}\n title={title}\n description={description}\n anchor=\"right\"\n size=\"lg\"\n headerIcon={\n <span className=\"text-primary-button-bg inline-flex size-8 items-center justify-center\">\n <Icon\n name={view.kind === 'test' || isExternalEdit || isCreatedEdit ? 'calendar' : 'calendar-plus'}\n className=\"size-5\"\n />\n </span>\n }\n footer={footer}\n >\n {view.kind === 'test' ? (\n <TestScheduleScreen\n schedule={view.schedule}\n agentName={agentLabel}\n mcpMounts={mcpMounts}\n onEditConfiguration={() => {\n setError(null);\n setView({ kind: 'form', saved: view.schedule });\n }}\n />\n ) : (\n <form id=\"schedule-form\" onSubmit={event => void handleSave(event)}>\n <ScheduleFormFields\n values={form}\n onChange={setForm}\n agentId={agentId}\n onAgentIdChange={isExternalEdit || isCreatedEdit ? undefined : setAgentId}\n agentOptions={agentOptions}\n agentPickerDisabled={isExternalEdit || isCreatedEdit}\n />\n </form>\n )}\n </SideDrawer>\n );\n}\n\nexport function ScheduleFormDrawer(props: ScheduleFormDrawerProps) {\n return (\n <DraftCatalogProvider>\n <ScheduleFormDrawerBody {...props} />\n </DraftCatalogProvider>\n );\n}\n","'use client';\n\nimport { cn } from '../lib/cn.js';\nimport { auiInputClass } from '../lib/inputClasses.js';\nimport { PopoverSelect } from '../primitives/PopoverSelect.js';\nimport {\n WEEKDAY_OPTIONS,\n formatCadenceSummary,\n getTimezoneOptions,\n valuesToCron,\n type RecurrenceKind,\n type ScheduleFormValues,\n} from './cadence.js';\n\nexport const RECURRENCE_OPTIONS: Array<{ value: RecurrenceKind; label: string }> = [\n { value: 'hourly', label: 'Hourly' },\n { value: 'daily', label: 'Daily' },\n { value: 'weekly', label: 'Weekly' },\n];\n\nconst HOUR_OPTIONS = Array.from({ length: 24 }, (_, hour) => ({\n value: String(hour),\n label: hour.toString().padStart(2, '0'),\n}));\nconst MINUTE_OPTIONS = [0, 15, 30, 45].map(minute => ({\n value: String(minute),\n label: `:${minute.toString().padStart(2, '0')}`,\n}));\n\nexport type ScheduleFormFieldsProps = {\n values: ScheduleFormValues;\n onChange: (next: ScheduleFormValues) => void;\n agentId: string;\n onAgentIdChange?: (agentId: string) => void;\n agentOptions: Array<{ agentId: string; name: string }>;\n agentPickerDisabled?: boolean;\n};\n\nexport function ScheduleFormFields({\n values,\n onChange,\n agentId,\n onAgentIdChange,\n agentOptions,\n agentPickerDisabled = false,\n}: ScheduleFormFieldsProps) {\n const cron = valuesToCron(values);\n const cadence = formatCadenceSummary({ cron, timezone: values.timezone });\n const timezoneOptions = getTimezoneOptions(values.timezone);\n\n const set = <K extends keyof ScheduleFormValues>(key: K, value: ScheduleFormValues[K]) => {\n onChange({ ...values, [key]: value });\n };\n\n const toggleWeekday = (day: number) => {\n const has = values.weekdays.includes(day);\n const weekdays = has ? values.weekdays.filter(d => d !== day) : [...values.weekdays, day];\n onChange({ ...values, weekdays: weekdays.length > 0 ? weekdays : [day] });\n };\n\n return (\n <div className=\"flex flex-col gap-4 px-5 py-4\">\n <div className=\"block\">\n <span className=\"mb-1.5 block text-sm font-medium\">Agent</span>\n <PopoverSelect\n aria-label=\"Agent\"\n placeholder=\"Select an agent\"\n value={agentId}\n options={agentOptions.map(agent => ({ value: agent.agentId, label: agent.name }))}\n onValueChange={value => onAgentIdChange?.(value)}\n disabled={agentPickerDisabled || onAgentIdChange == null}\n />\n </div>\n\n <label className=\"block\">\n <span className=\"mb-1.5 block text-sm font-medium\">Name</span>\n <input\n value={values.name}\n onChange={e => set('name', e.target.value)}\n placeholder=\"harness-daily-digest\"\n className={auiInputClass('h-9')}\n required\n />\n </label>\n\n <label className=\"block\">\n <span className=\"mb-1.5 block text-sm font-medium\">Task</span>\n <textarea\n value={values.task}\n onChange={e => set('task', e.target.value)}\n rows={3}\n placeholder=\"Summarise yesterday's harness runs and post the digest…\"\n className={auiInputClass('resize-y py-2')}\n required\n />\n </label>\n\n <fieldset>\n <legend className=\"mb-1.5 text-sm font-medium\">Recurrence</legend>\n <div className=\"grid grid-cols-3 gap-1 rounded-lg border border-border p-1\">\n {RECURRENCE_OPTIONS.map(opt => {\n const selected = values.recurrence === opt.value;\n return (\n <button\n key={opt.value}\n type=\"button\"\n className={cn(\n 'rounded-md px-2 py-1.5 text-xs font-medium transition-colors',\n selected\n ? 'border border-primary-button-bg/40 bg-primary-button-bg/10 text-primary-button-bg'\n : 'text-text-secondary hover:bg-ghost-button-hover border border-transparent',\n )}\n aria-pressed={selected}\n onClick={() => set('recurrence', opt.value)}\n >\n {opt.label}\n </button>\n );\n })}\n </div>\n </fieldset>\n\n {values.recurrence === 'hourly' ? (\n <div className=\"block max-w-[8rem]\">\n <span className=\"mb-1.5 block text-sm font-medium\">Minute</span>\n <PopoverSelect\n aria-label=\"Minute\"\n value={String(values.minute)}\n options={MINUTE_OPTIONS}\n onValueChange={value => set('minute', Number(value))}\n />\n </div>\n ) : null}\n\n {values.recurrence === 'daily' || values.recurrence === 'weekly' ? (\n <div className=\"flex flex-wrap gap-3\">\n <div className=\"block min-w-[7rem] flex-1\">\n <span className=\"mb-1.5 block text-sm font-medium\">Hour</span>\n <PopoverSelect\n aria-label=\"Hour\"\n value={String(values.hour)}\n options={HOUR_OPTIONS}\n onValueChange={value => set('hour', Number(value))}\n />\n </div>\n <div className=\"block min-w-[7rem] flex-1\">\n <span className=\"mb-1.5 block text-sm font-medium\">Minute</span>\n <PopoverSelect\n aria-label=\"Minute\"\n value={String(values.minute)}\n options={MINUTE_OPTIONS}\n onValueChange={value => set('minute', Number(value))}\n />\n </div>\n </div>\n ) : null}\n\n {values.recurrence === 'weekly' ? (\n <fieldset>\n <legend className=\"mb-1.5 text-sm font-medium\">Days</legend>\n <div className=\"flex flex-wrap gap-1.5\">\n {WEEKDAY_OPTIONS.map(day => {\n const selected = values.weekdays.includes(day.value);\n return (\n <button\n key={day.value}\n type=\"button\"\n className={cn(\n 'rounded-md border px-2.5 py-1 text-xs font-medium',\n selected\n ? 'border-primary-button-bg/40 bg-primary-button-bg/10 text-primary-button-bg'\n : 'border-border text-text-secondary hover:bg-ghost-button-hover',\n )}\n aria-pressed={selected}\n onClick={() => toggleWeekday(day.value)}\n >\n {day.label}\n </button>\n );\n })}\n </div>\n </fieldset>\n ) : null}\n\n {values.recurrence === 'custom' ? (\n <div className=\"rounded-md border border-border bg-secondary-bg/40 px-3 py-2\">\n <span className=\"text-text-secondary block text-xs\">Existing custom schedule</span>\n <code className=\"text-text-primary mt-1 block font-mono text-sm\">{values.customCron}</code>\n <span className=\"text-text-secondary mt-1 block text-xs\">\n Select Hourly, Daily, or Weekly to replace this schedule.\n </span>\n </div>\n ) : null}\n\n <div className=\"block\">\n <span className=\"mb-1.5 block text-sm font-medium\">Timezone</span>\n <PopoverSelect\n aria-label=\"Timezone\"\n value={values.timezone}\n options={timezoneOptions}\n onValueChange={value => set('timezone', value)}\n menuPlacement=\"top\"\n />\n </div>\n\n <div className=\"rounded-lg border border-border bg-secondary-bg/40 px-3 py-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <span className=\"text-text-secondary text-[10px] font-semibold tracking-wide uppercase\">Frequency</span>\n <code className=\"text-text-secondary font-mono text-xs\">{cron || '—'}</code>\n </div>\n <p className=\"text-text-primary mt-1 text-sm font-semibold\">{cadence || '—'}</p>\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useState, type ReactNode } from 'react';\n\nimport { useToasterOptional } from '../../containers/ToasterContainer.js';\nimport { Icon } from '../../icons/Icon.js';\nimport { useOptionalCatalogServer, useScheduleServer } from '../../server/ServerContext.js';\nimport type { ConnectorState, Schedule, ScheduleRun } from '../../server/types.js';\nimport { useDraftCatalog } from '../draft/DraftCatalogProvider.js';\nimport { ConnectorConnectButton } from '../draft/DraftCompositeSelector.js';\nimport { auiButtonClass } from '../lib/buttonClasses.js';\nimport { cn } from '../lib/cn.js';\nimport { Button } from '../primitives/Button.js';\nimport { formatCadenceSummary, formatRelativeTime } from './cadence.js';\nimport { ScheduleRunChip } from './ScheduleRunChip.js';\nimport { runTypeLabel } from './scheduleRuns.js';\nimport { ScheduleStatusBadge } from './ScheduleStatusBadge.js';\n\nexport type ScheduleMcpMount = {\n name: string;\n};\n\nexport type TestScheduleScreenProps = {\n schedule: Schedule;\n agentName: string;\n mcpMounts: readonly ScheduleMcpMount[];\n onEditConfiguration: () => void;\n};\n\nfunction mountConnector(connectors: ConnectorState[], name: string): ConnectorState | null {\n return connectors.find(connector => connector.name === name || connector.id === name) ?? null;\n}\n\nfunction ScheduleMcpConnect({\n connector,\n onConnected,\n}: {\n connector: ConnectorState;\n onConnected: () => Promise<void>;\n}) {\n const catalog = useOptionalCatalogServer();\n if (catalog == null) return null;\n return <ConnectorConnectButton connector={connector} onConnected={onConnected} />;\n}\n\nfunction DetailRow({ label, children }: { label: string; children: ReactNode }) {\n return (\n <div className=\"flex items-start justify-between gap-3 border-b border-border px-3 py-2.5 last:border-b-0\">\n <span className=\"text-text-secondary shrink-0 text-[10px] font-semibold tracking-wide uppercase\">{label}</span>\n <div className=\"min-w-0 text-right text-sm text-text-primary\">{children}</div>\n </div>\n );\n}\n\nexport function TestScheduleScreen({ schedule, agentName, mcpMounts, onEditConfiguration }: TestScheduleScreenProps) {\n const scheduleServer = useScheduleServer();\n const toaster = useToasterOptional();\n const { connectors, ensureLoaded, refreshConnectors, loading, error } = useDraftCatalog();\n const [running, setRunning] = useState(false);\n const [lastTestRun, setLastTestRun] = useState<ScheduleRun | null>(null);\n const cadence = formatCadenceSummary({ cron: schedule.cron, timezone: schedule.timezone });\n\n const handleRunTest = async () => {\n setRunning(true);\n try {\n const run = await scheduleServer.createScheduleRun({ scheduleId: schedule.id });\n setLastTestRun(run);\n toaster?.showSuccess({ title: 'Test run started' });\n } catch (caught) {\n toaster?.showError(caught);\n } finally {\n setRunning(false);\n }\n };\n\n useEffect(() => {\n ensureLoaded();\n }, [ensureLoaded]);\n\n useEffect(() => {\n if (error != null) toaster?.showError(error);\n }, [error, toaster]);\n\n return (\n <div className=\"flex flex-col gap-4 px-5 py-4\">\n <section className=\"overflow-hidden rounded-lg border border-border bg-card-bg\">\n <DetailRow label=\"Agent\">{agentName}</DetailRow>\n <DetailRow label=\"Name\">{schedule.name}</DetailRow>\n <DetailRow label=\"Task\">\n <span className=\"whitespace-pre-wrap break-words\">{schedule.task}</span>\n </DetailRow>\n <DetailRow label=\"Cadence\">\n <div className=\"flex flex-wrap items-center justify-end gap-1.5\">\n <span>{cadence}</span>\n <code className=\"text-text-secondary font-mono text-xs\">{schedule.cron}</code>\n </div>\n </DetailRow>\n <DetailRow label=\"Status\">\n <ScheduleStatusBadge status={schedule.status} />\n </DetailRow>\n <div className=\"flex justify-end px-3 py-2.5\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onEditConfiguration}>\n <Icon name=\"pencil\" className=\"size-3.5\" />\n Edit Configuration\n </Button>\n </div>\n </section>\n\n <section className=\"overflow-hidden rounded-lg border border-border bg-card-bg\">\n <div className=\"border-b border-border px-3 py-2\">\n <h3 className=\"text-text-secondary text-[10px] font-semibold tracking-wide uppercase\">Tool Authorization</h3>\n </div>\n {mcpMounts.length === 0 ? (\n <p className=\"text-text-secondary px-3 py-3 text-sm\">No MCP connectors configured for this agent.</p>\n ) : (\n <ul className=\"divide-y divide-border\">\n {mcpMounts.map(mount => {\n const connector = mountConnector(connectors, mount.name);\n const authenticated = connector?.authenticated === true;\n const unavailable = connector == null && !loading;\n return (\n <li key={mount.name} className=\"flex items-center gap-2 px-3 py-2.5\">\n <span\n className={cn(\n 'inline-flex size-4 shrink-0 items-center justify-center rounded-full border',\n authenticated\n ? 'border-emerald-600/40 bg-emerald-500/15 text-emerald-700 dark:text-emerald-300'\n : 'border-border text-transparent',\n )}\n aria-hidden\n >\n {authenticated ? <Icon name=\"check\" className=\"size-3\" /> : null}\n </span>\n <span className=\"text-text-primary min-w-0 flex-1 truncate text-sm\">{mount.name}</span>\n {authenticated ? (\n <span className=\"text-success-bg text-xs font-medium\">Connected</span>\n ) : unavailable ? (\n <span className=\"text-text-secondary text-xs\">Unavailable</span>\n ) : connector != null && connector.authenticated === false ? (\n <ScheduleMcpConnect connector={connector} onConnected={refreshConnectors} />\n ) : loading ? (\n <span className=\"text-text-secondary text-xs\">Loading…</span>\n ) : null}\n </li>\n );\n })}\n </ul>\n )}\n </section>\n\n <section className=\"overflow-hidden rounded-lg border border-border bg-card-bg\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border px-3 py-2\">\n <h3 className=\"text-text-secondary text-[10px] font-semibold tracking-wide uppercase\">Test Run</h3>\n <button\n type=\"button\"\n disabled={running}\n onClick={() => void handleRunTest()}\n className={auiButtonClass({ variant: 'default', size: 'sm' })}\n >\n <Icon name={running ? 'loader' : 'play'} className={cn('size-3.5', running && 'animate-spin')} />\n Run Test\n </button>\n </div>\n {lastTestRun == null ? (\n <p className=\"text-text-secondary px-3 py-3 text-sm\">\n Run a one-off test using the schedule task. This does not change the cron pending run.\n </p>\n ) : (\n <div className=\"flex items-center gap-3 px-3 py-3\">\n <ScheduleRunChip run={lastTestRun} />\n <div className=\"min-w-0 text-sm\">\n <p className=\"text-text-primary font-medium\">{runTypeLabel(lastTestRun.name)}</p>\n <p className=\"text-text-secondary\">\n {formatRelativeTime(lastTestRun.triggeredAt ?? lastTestRun.scheduledFor)}\n </p>\n </div>\n </div>\n )}\n </section>\n </div>\n );\n}\n","import type { ScheduleRun, ScheduleRunStatus } from '../../server/types.js';\n\nexport function isManualRun(name: string): boolean {\n return name.startsWith('manual-');\n}\n\nexport function runChipKind(status: ScheduleRunStatus): 'success' | 'failed' {\n if (status === 'failed') return 'failed';\n return 'success';\n}\n\nexport function runStatusLabel(status: ScheduleRunStatus): string {\n if (status === 'failed') return 'Failed';\n if (status === 'triggered') return 'Triggered';\n return 'Scheduled';\n}\n\nexport function runTypeLabel(name: string): string {\n return isManualRun(name) ? 'Manual test' : 'Cron';\n}\n\n/** Newest-first API rows → up to `limit` historical runs, oldest on the left. */\nexport function lastHistoricalRuns(runs: readonly ScheduleRun[], limit = 5): ScheduleRun[] {\n const historical = runs.filter(run => run.status !== 'scheduled');\n return historical.slice(0, limit).reverse();\n}\n\nexport function formatScheduleRunInstant(iso: string | null): string {\n if (iso == null) return '—';\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return '—';\n return new Intl.DateTimeFormat(undefined, {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n }).format(date);\n}\n","'use client';\n\nimport type { ScheduleRun } from '../../server/types.js';\nimport { formatScheduleRunInstant, runStatusLabel, runTypeLabel } from './scheduleRuns.js';\n\nexport function ScheduleRunTooltip({ run }: { run: ScheduleRun }) {\n return (\n <div className=\"flex flex-col gap-1 text-left text-xs\">\n <p className=\"text-text-primary font-medium\">{runStatusLabel(run.status)}</p>\n <p className=\"text-text-secondary\">{runTypeLabel(run.name)}</p>\n <p className=\"text-text-secondary\">Scheduled for: {formatScheduleRunInstant(run.scheduledFor)}</p>\n {run.triggeredAt != null ? (\n <p className=\"text-text-secondary\">Triggered at: {formatScheduleRunInstant(run.triggeredAt)}</p>\n ) : null}\n <p className=\"text-text-secondary\">Triggered by: {run.triggeredBy}</p>\n </div>\n );\n}\n","'use client';\n\nimport { Icon } from '../../icons/Icon.js';\nimport type { ScheduleRun } from '../../server/types.js';\nimport { cn } from '../lib/cn.js';\nimport { Tooltip } from '../primitives/Tooltip.js';\nimport { formatScheduleRunInstant, runChipKind, runStatusLabel } from './scheduleRuns.js';\nimport { ScheduleRunTooltip } from './ScheduleRunTooltip.js';\n\nconst CHIP_STYLES = {\n success:\n 'border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300',\n failed: 'border-red-600/30 bg-red-500/10 text-red-700 dark:border-red-400/35 dark:bg-red-500/15 dark:text-red-300',\n} as const;\n\nexport function ScheduleRunChip({ run }: { run: ScheduleRun }) {\n const kind = runChipKind(run.status);\n const when = formatScheduleRunInstant(run.triggeredAt ?? run.scheduledFor);\n return (\n <Tooltip content={<ScheduleRunTooltip run={run} />} side=\"top\">\n <span\n className={cn('inline-flex size-6 shrink-0 items-center justify-center rounded-md border', CHIP_STYLES[kind])}\n aria-label={`${runStatusLabel(run.status)} run at ${when}`}\n >\n <Icon name={kind === 'failed' ? 'triangle-exclamation' : 'check'} className=\"size-3.5\" />\n </span>\n </Tooltip>\n );\n}\n","'use client';\n\nimport type { ScheduleStatus } from '../../server/types.js';\nimport { cn } from '../lib/cn.js';\n\nexport function ScheduleStatusBadge({ status }: { status: ScheduleStatus }) {\n const active = status === 'active';\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium',\n active\n ? 'border-emerald-600/30 bg-emerald-500/10 text-emerald-700 dark:border-emerald-400/35 dark:bg-emerald-500/15 dark:text-emerald-300'\n : 'border-border bg-secondary-bg text-text-secondary',\n )}\n >\n <span\n className={cn(\n 'size-1.5 shrink-0 rounded-full',\n active ? 'bg-emerald-600 dark:bg-emerald-400' : 'bg-text-secondary',\n )}\n aria-hidden\n />\n {active ? 'Active' : 'Paused'}\n </span>\n );\n}\n","'use client';\n\nimport type { ScheduleRun } from '../../server/types.js';\nimport { ScheduleRunChip } from './ScheduleRunChip.js';\nimport { lastHistoricalRuns } from './scheduleRuns.js';\n\nexport function ScheduleLastRunsCell({ runs }: { runs: readonly ScheduleRun[] }) {\n const history = lastHistoricalRuns(runs);\n if (history.length === 0) {\n return <span className=\"text-text-secondary text-sm\">—</span>;\n }\n return (\n <div className=\"flex items-center gap-1\">\n {history.map(run => (\n <ScheduleRunChip key={run.id} run={run} />\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useMemo","useState","useEffect","useState","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useEffect","saved","jsx","jsx","jsxs","useState","useEffect","useMemo"]}
|