agent-relay-server 0.29.0 → 0.30.1

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/public/index.html CHANGED
@@ -11190,6 +11190,17 @@ function shortPath$1(cwd, segments = 2) {
11190
11190
  const parts = cwd.replace(/\/+$/, "").split("/");
11191
11191
  return parts.length <= segments ? cwd : parts.slice(-segments).join("/");
11192
11192
  }
11193
+ function normalizePathForCompare(path) {
11194
+ return path.trim().replace(/\\/g, "/").replace(/\/+$/, "") || "/";
11195
+ }
11196
+ function pathWithinBase(path, baseDir) {
11197
+ if (!path?.trim() || !baseDir?.trim()) return false;
11198
+ const normalizedPath = normalizePathForCompare(path);
11199
+ const normalizedBase = normalizePathForCompare(baseDir);
11200
+ if (normalizedBase === "/") return normalizedPath.startsWith("/");
11201
+ if (normalizedPath === "/") return false;
11202
+ return normalizedPath === normalizedBase || normalizedPath.startsWith(normalizedBase + "/");
11203
+ }
11193
11204
  function isBuiltInAgent(agent) {
11194
11205
  return agent?.meta?.builtin === true || agent?.id === "user" || agent?.id === "system";
11195
11206
  }
@@ -11355,7 +11366,7 @@ function isClaimableTaskWaiting(task) {
11355
11366
  function isClaimableMessageWaiting(msg) {
11356
11367
  return Boolean(msg.claimable && !msg.claimedBy && !(msg.kind === "task" && Number.isSafeInteger(msg.payload?.taskId)));
11357
11368
  }
11358
- function targetMatchesAgent(target, agent) {
11369
+ function dashboardTargetMatchesAgent(target, agent) {
11359
11370
  if (!target || !agent) return false;
11360
11371
  if (target === "broadcast" || target === agent.id) return true;
11361
11372
  if (target.startsWith("tag:")) return (agent.tags || []).includes(target.slice(4));
@@ -11749,7 +11760,7 @@ function timeAgo(now, iso) {
11749
11760
  if (diff < 86400) return Math.floor(diff / 3600) + "h ago";
11750
11761
  return Math.floor(diff / 86400) + "d ago";
11751
11762
  }
11752
- function fmtTime$1(iso) {
11763
+ function fmtTime(iso) {
11753
11764
  if (!iso) return "";
11754
11765
  return new Date(iso).toLocaleString();
11755
11766
  }
@@ -12066,12 +12077,6 @@ function firstAvailableProvider(orchestrator) {
12066
12077
  function defaultModelFor(provider) {
12067
12078
  return PROVIDER_CATALOG[provider]?.defaultModel ?? "";
12068
12079
  }
12069
- function pathWithinBase(path, baseDir) {
12070
- const value = path.trim().replace(/\\/g, "/").replace(/\/+$/, "");
12071
- const base = (baseDir || "").trim().replace(/\\/g, "/").replace(/\/+$/, "");
12072
- if (!value || !base) return false;
12073
- return value === base || value.startsWith(base + "/");
12074
- }
12075
12080
  function indexAgents(agents) {
12076
12081
  const byId = {};
12077
12082
  for (const agent of agents) byId[agent.id] = agent;
@@ -12191,16 +12196,8 @@ function renderTimelineMarkdown(events, exportedAt) {
12191
12196
  }
12192
12197
  return lines.join("\n");
12193
12198
  }
12194
- function normalizePathForCompare$1(path) {
12195
- return path.replace(/\/+$/, "") || "/";
12196
- }
12197
- function pathWithin$1(path, baseDir) {
12198
- const normalizedPath = normalizePathForCompare$1(path);
12199
- const normalizedBase = normalizePathForCompare$1(baseDir);
12200
- return normalizedPath === normalizedBase || normalizedPath.startsWith(normalizedBase + "/");
12201
- }
12202
12199
  function orchestratorForPath(orchestrators, path) {
12203
- return orchestrators.filter((orch) => orch.status === "online" && pathWithin$1(path, orch.baseDir)).sort((a, b) => normalizePathForCompare$1(b.baseDir).length - normalizePathForCompare$1(a.baseDir).length)[0];
12200
+ return orchestrators.filter((orch) => orch.status === "online" && pathWithinBase(path, orch.baseDir)).sort((a, b) => normalizePathForCompare(b.baseDir).length - normalizePathForCompare(a.baseDir).length)[0];
12204
12201
  }
12205
12202
  function orchestratorForAgent(orchestrators, agent) {
12206
12203
  const managed = orchestrators.find((orch) => orch.managedAgents.some((managedAgent) => managedAgent.agentId === agent.id));
@@ -12293,6 +12290,7 @@ var useRelayStore = create$1()(persist((set, get) => ({
12293
12290
  health: null,
12294
12291
  maintenanceJobs: [],
12295
12292
  workspaces: [],
12293
+ workspaceFocusId: null,
12296
12294
  workspaceGitState: {},
12297
12295
  workspaceMergePreview: {},
12298
12296
  workspaceDiff: {},
@@ -12593,6 +12591,10 @@ var useRelayStore = create$1()(persist((set, get) => ({
12593
12591
  if (view === "files") await s.fetchOrchestrators();
12594
12592
  if (view === "analytics") await s.fetchAnalytics();
12595
12593
  },
12594
+ async openWorkspaceFocus(workspaceId) {
12595
+ set({ workspaceFocusId: workspaceId });
12596
+ await get().switchView("workspaces");
12597
+ },
12596
12598
  startClock() {
12597
12599
  useClock.getState().start();
12598
12600
  },
@@ -25823,7 +25825,7 @@ function useAgentAttention(agent) {
25823
25825
  const archivedAt = Number(archivedThreads[agent.id] || 0);
25824
25826
  const unread = archivedAt >= peerMessages.filter(isHumanInboundMessage).reduce((max, m) => Math.max(max, m.id), 0) && archivedAt > 0 ? 0 : peerMessages.filter((m) => isHumanInboundMessage(m) && !isSessionActivityStep(m) && !(m.readBy || []).includes("user") && m.id > cursor).length;
25825
25827
  const pendingPairInvite = pairs.find((p) => (p.status === "active" || p.status === "pending") && (p.requesterId === agent.id || p.targetId === agent.id))?.status === "pending";
25826
- const claimableTasks = tasks.filter((t) => isClaimableTaskWaiting(t) && targetMatchesAgent(t.target, agent)).length + messages.filter((m) => isClaimableMessageWaiting(m) && targetMatchesAgent(m.to, agent)).length;
25828
+ const claimableTasks = tasks.filter((t) => isClaimableTaskWaiting(t) && dashboardTargetMatchesAgent(t.target, agent)).length + messages.filter((m) => isClaimableMessageWaiting(m) && dashboardTargetMatchesAgent(m.to, agent)).length;
25827
25829
  return {
25828
25830
  unread,
25829
25831
  pendingPairInvite,
@@ -77208,7 +77210,7 @@ function SidebarContent() {
77208
77210
  }
77209
77211
  function Sidebar() {
77210
77212
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
77211
- className: "hidden xl:flex w-[250px] min-w-[250px] h-dvh sticky top-0 flex-col border-r border-border bg-card",
77213
+ className: "hidden xl:flex w-[250px] min-w-[250px] h-[calc(100dvh-var(--sat))] sticky top-[var(--sat)] flex-col border-r border-border bg-card",
77212
77214
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
77213
77215
  className: "px-5 py-4 font-bold text-base border-b border-border flex items-center gap-2",
77214
77216
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Radio, { className: "w-4 h-4 text-primary" }), "Agent Relay"]
@@ -77230,7 +77232,7 @@ function MobileDrawer() {
77230
77232
  className: cn$2("xl:hidden fixed inset-0 z-40 bg-black/50 transition-opacity duration-200", open ? "opacity-100" : "opacity-0 pointer-events-none"),
77231
77233
  onClick: () => set({ mobileMenuOpen: false })
77232
77234
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
77233
- className: cn$2("xl:hidden fixed inset-y-0 left-0 z-50 w-[280px] flex flex-col bg-card border-r border-border transition-transform duration-200 ease-out", open ? "translate-x-0" : "-translate-x-full"),
77235
+ className: cn$2("xl:hidden fixed inset-y-0 left-0 z-50 w-[280px] flex flex-col pt-[var(--sat)] bg-card border-r border-border transition-transform duration-200 ease-out", open ? "translate-x-0" : "-translate-x-full"),
77234
77236
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
77235
77237
  className: "px-5 py-4 font-bold text-base border-b border-border flex items-center gap-2",
77236
77238
  children: [
@@ -109163,6 +109165,60 @@ function formatTokenCount(tokens) {
109163
109165
  return String(tokens);
109164
109166
  }
109165
109167
  //#endregion
109168
+ //#region src/components/shared/branch-state-badge.tsx
109169
+ var BRANCH_STATE_META = {
109170
+ idle: {
109171
+ label: "idle",
109172
+ tip: "Branch worktree — nothing to land yet.",
109173
+ className: "bg-zinc-500/10 text-zinc-400 border-zinc-500/20",
109174
+ Icon: Circle
109175
+ },
109176
+ changes: {
109177
+ label: "changes",
109178
+ tip: "Unlanded work in this branch — use \"Mark workspace ready\" to land it.",
109179
+ className: "bg-amber-500/10 text-amber-400 border-amber-500/20",
109180
+ Icon: GitCommitHorizontal
109181
+ },
109182
+ ready: {
109183
+ label: "ready",
109184
+ tip: "Handed off — the relay auto-merge will land it (~2 min sweep).",
109185
+ className: "bg-blue-500/10 text-blue-400 border-blue-500/20",
109186
+ Icon: CircleArrowUp
109187
+ },
109188
+ steward: {
109189
+ label: "steward",
109190
+ tip: "Under reconciliation — a steward is landing it. No action needed.",
109191
+ className: "bg-orange-500/10 text-orange-400 border-orange-500/20",
109192
+ Icon: Wrench
109193
+ },
109194
+ blocked: {
109195
+ label: "blocked",
109196
+ tip: "Escalated — the auto-merge/steward path is stuck. Needs human attention.",
109197
+ className: "bg-red-500/10 text-red-400 border-red-500/20",
109198
+ Icon: TriangleAlert
109199
+ }
109200
+ };
109201
+ function BranchStateBadge({ state, onClick, iconOnly = false, className }) {
109202
+ const meta = BRANCH_STATE_META[state];
109203
+ const { Icon } = meta;
109204
+ const interactive = Boolean(onClick);
109205
+ const tip = interactive ? `${meta.tip} Click to open this workspace.` : meta.tip;
109206
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
109207
+ role: interactive ? "button" : void 0,
109208
+ tabIndex: interactive ? 0 : void 0,
109209
+ title: tip,
109210
+ onClick,
109211
+ onKeyDown: interactive ? (e) => {
109212
+ if (e.key === "Enter" || e.key === " ") {
109213
+ e.preventDefault();
109214
+ onClick?.(e);
109215
+ }
109216
+ } : void 0,
109217
+ className: cn$2("inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium leading-none", meta.className, interactive && "cursor-pointer hover:brightness-125 focus:outline-none focus:ring-1 focus:ring-current", className),
109218
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "h-2.5 w-2.5 shrink-0" }), !iconOnly && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: meta.label })]
109219
+ });
109220
+ }
109221
+ //#endregion
109166
109222
  //#region node_modules/@xterm/xterm/lib/xterm.mjs
109167
109223
  /**
109168
109224
  * Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.
@@ -126385,11 +126441,24 @@ function TerminalViewer({ orchestratorId, session, interactive: initialInteracti
126385
126441
  });
126386
126442
  }
126387
126443
  function TerminalDialog({ open, onOpenChange, orchestratorId, session, interactive }) {
126444
+ const [vpHeight, setVpHeight] = (0, import_react.useState)(null);
126445
+ (0, import_react.useEffect)(() => {
126446
+ if (!open) return;
126447
+ const vv = window.visualViewport;
126448
+ if (!vv) return;
126449
+ function onResize() {
126450
+ setVpHeight(vv.height);
126451
+ }
126452
+ onResize();
126453
+ vv.addEventListener("resize", onResize);
126454
+ return () => vv.removeEventListener("resize", onResize);
126455
+ }, [open]);
126388
126456
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog, {
126389
126457
  open,
126390
126458
  onOpenChange,
126391
126459
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, {
126392
- className: "inset-0 translate-x-0 translate-y-0 w-auto h-auto max-w-none rounded-none p-0 bg-background border-border gap-0 overflow-hidden",
126460
+ className: "inset-x-0 top-0 translate-x-0 translate-y-0 w-auto max-w-none rounded-none p-0 pt-[var(--sat)] bg-background border-border gap-0 overflow-hidden",
126461
+ style: { height: vpHeight ? `${vpHeight}px` : "100dvh" },
126393
126462
  showCloseButton: false,
126394
126463
  blurOverlay: false,
126395
126464
  onEscapeKeyDown: (e) => e.preventDefault(),
@@ -127362,16 +127431,8 @@ function parentPath$1(path) {
127362
127431
  const index = trimmed.lastIndexOf("/");
127363
127432
  return index > 0 ? trimmed.slice(0, index) : "/";
127364
127433
  }
127365
- function normalizePathForCompare(path) {
127366
- return path.replace(/\/+$/, "") || "/";
127367
- }
127368
- function pathWithin(path, baseDir) {
127369
- const normalizedPath = normalizePathForCompare(path);
127370
- const normalizedBase = normalizePathForCompare(baseDir);
127371
- return normalizedPath === normalizedBase || normalizedPath.startsWith(normalizedBase + "/");
127372
- }
127373
127434
  function orchestratorForFilePreview(orchestrators, path) {
127374
- return orchestrators.filter((orch) => orch.status === "online" && pathWithin(path, orch.baseDir)).sort((a, b) => normalizePathForCompare(b.baseDir).length - normalizePathForCompare(a.baseDir).length)[0] || orchestrators.find((orch) => orch.status === "online");
127435
+ return orchestrators.filter((orch) => orch.status === "online" && pathWithinBase(path, orch.baseDir)).sort((a, b) => normalizePathForCompare(b.baseDir).length - normalizePathForCompare(a.baseDir).length)[0] || orchestrators.find((orch) => orch.status === "online");
127375
127436
  }
127376
127437
  function supportsSideFilePreview() {
127377
127438
  return typeof window !== "undefined" && window.matchMedia("(min-width: 1280px)").matches;
@@ -127689,7 +127750,7 @@ function AgentListPanel({ threads, onSelectAgent }) {
127689
127750
  className: "flex items-center gap-1 shrink-0",
127690
127751
  children: [lastActivityAt > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
127691
127752
  className: "text-[10px] text-muted-foreground",
127692
- title: fmtTime$1(lastActivityAt),
127753
+ title: fmtTime(lastActivityAt),
127693
127754
  children: timeAgo(now, lastActivityAt)
127694
127755
  }), unread > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge$1, {
127695
127756
  className: "bg-red-500 text-white text-xs min-w-[18px] h-[18px] flex items-center justify-center shrink-0 px-1",
@@ -129204,6 +129265,8 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129204
129265
  const setReplyDraft = useRelayStore((s) => s.setReplyDraft);
129205
129266
  const exportThread = useRelayStore((s) => s.exportThread);
129206
129267
  const doAgentAction = useRelayStore((s) => s.doAgentAction);
129268
+ const workspaceAction = useRelayStore((s) => s.workspaceAction);
129269
+ const openWorkspaceFocus = useRelayStore((s) => s.openWorkspaceFocus);
129207
129270
  const forkFromAgent = useRelayStore((s) => s.forkFromAgent);
129208
129271
  const chatHistoryImports = useRelayStore((s) => s.chatHistoryImports);
129209
129272
  const peerHistory = useRelayStore((s) => s.threadHistory[s.selectedInboxThread] ?? NO_THREAD_HISTORY);
@@ -129552,7 +129615,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129552
129615
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
129553
129616
  className: "flex h-full min-w-0",
129554
129617
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
129555
- className: "flex h-full min-w-0 flex-1 flex-col",
129618
+ className: "@container/chat flex h-full min-w-0 flex-1 flex-col",
129556
129619
  children: [
129557
129620
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
129558
129621
  className: "flex items-center justify-between px-3 md:px-4 py-2.5 md:py-3 border-b border-border shrink-0",
@@ -129596,11 +129659,16 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129596
129659
  agent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AgentRuntimeChips, {
129597
129660
  agent,
129598
129661
  compact: true,
129599
- className: "hidden md:flex shrink-0"
129662
+ className: "hidden @4xl/chat:flex shrink-0"
129600
129663
  }),
129601
129664
  agent?.context && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextRing, { utilization: agent.context.utilization }),
129665
+ agent?.branchState && agent.branchWorkspaceId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BranchStateBadge, {
129666
+ state: agent.branchState,
129667
+ className: "shrink-0",
129668
+ onClick: () => void openWorkspaceFocus(agent.branchWorkspaceId)
129669
+ }),
129602
129670
  thread?.attention.unread ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Badge$1, {
129603
- className: "bg-red-500/20 text-red-400 text-xs shrink-0 hidden sm:flex",
129671
+ className: "bg-red-500/20 text-red-400 text-xs shrink-0 hidden @2xl/chat:flex",
129604
129672
  children: [thread.attention.unread, " unread"]
129605
129673
  }) : null
129606
129674
  ]
@@ -129623,7 +129691,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129623
129691
  canOpenTerminal && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129624
129692
  variant: "ghost",
129625
129693
  size: "icon-sm",
129626
- className: "hidden sm:inline-flex",
129694
+ className: "hidden @4xl/chat:inline-flex",
129627
129695
  disabled: terminalOpening,
129628
129696
  title: "Terminal",
129629
129697
  onClick: () => void handleOpenTerminal(),
@@ -129637,10 +129705,18 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129637
129705
  onClick: interruptAgent,
129638
129706
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleStop, { className: "w-3.5 h-3.5" })
129639
129707
  }),
129708
+ agent.branchState === "changes" && agent.branchWorkspaceId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129709
+ variant: "ghost",
129710
+ size: "icon-sm",
129711
+ className: "hidden @4xl/chat:inline-flex text-amber-400 hover:text-amber-300",
129712
+ title: "Mark workspace ready — hand off to the auto-merge",
129713
+ onClick: () => openConfirm("Mark Workspace Ready", `Mark ${displayName(agent)}'s branch ready to land? The relay auto-merge will rebase and land it.`, () => workspaceAction(agent.branchWorkspaceId, "ready")),
129714
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Flag, { className: "w-3.5 h-3.5" })
129715
+ }),
129640
129716
  canCompact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129641
129717
  variant: "ghost",
129642
129718
  size: "icon-sm",
129643
- className: "hidden sm:inline-flex",
129719
+ className: "hidden @4xl/chat:inline-flex",
129644
129720
  title: "Compact",
129645
129721
  onClick: () => openConfirm("Compact Agent", `Compact context for ${displayName(agent)}?`, () => doAgentAction(agent, "compact")),
129646
129722
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Minimize2, { className: "w-3.5 h-3.5" })
@@ -129648,7 +129724,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129648
129724
  canClearContext && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129649
129725
  variant: "ghost",
129650
129726
  size: "icon-sm",
129651
- className: "hidden sm:inline-flex",
129727
+ className: "hidden @4xl/chat:inline-flex",
129652
129728
  title: "Clear context",
129653
129729
  onClick: () => openConfirm("Clear Context", `Clear context for ${displayName(agent)}?`, () => doAgentAction(agent, "clearContext")),
129654
129730
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Eraser, { className: "w-3.5 h-3.5" })
@@ -129656,7 +129732,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129656
129732
  canShutdown && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129657
129733
  variant: "ghost",
129658
129734
  size: "icon-sm",
129659
- className: "hidden sm:inline-flex",
129735
+ className: "hidden @4xl/chat:inline-flex",
129660
129736
  title: "Shutdown",
129661
129737
  onClick: () => openConfirm("Shutdown Agent", `Shutdown ${displayName(agent)}?`, () => doAgentAction(agent, "shutdown")),
129662
129738
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Power, { className: "w-3.5 h-3.5" })
@@ -129664,7 +129740,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129664
129740
  agent && typeof agent.meta?.cwd === "string" && agent.meta.cwd && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129665
129741
  variant: "ghost",
129666
129742
  size: "icon-sm",
129667
- className: "hidden sm:inline-flex",
129743
+ className: "hidden @4xl/chat:inline-flex",
129668
129744
  title: `Open ${agent.meta.cwd} in Files`,
129669
129745
  onClick: () => void openFilesForAgent(agent),
129670
129746
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FolderOpen, { className: "w-3.5 h-3.5" })
@@ -129672,7 +129748,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129672
129748
  agent && thread && thread.messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129673
129749
  variant: "ghost",
129674
129750
  size: "icon-sm",
129675
- className: "hidden sm:inline-flex",
129751
+ className: "hidden @4xl/chat:inline-flex",
129676
129752
  title: "Fork — spawn new agent with this chat history",
129677
129753
  onClick: () => forkFromAgent(agent.id, thread.messages),
129678
129754
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitFork, { className: "w-3.5 h-3.5" })
@@ -129680,7 +129756,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129680
129756
  thread && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129681
129757
  variant: "ghost",
129682
129758
  size: "icon-sm",
129683
- className: "hidden sm:inline-flex",
129759
+ className: "hidden @4xl/chat:inline-flex",
129684
129760
  title: "Mark unread",
129685
129761
  onClick: () => markInboxThreadUnread(selectedInboxThread),
129686
129762
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MailX, { className: "w-3.5 h-3.5" })
@@ -129688,7 +129764,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129688
129764
  thread && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129689
129765
  variant: "ghost",
129690
129766
  size: "icon-sm",
129691
- className: "hidden sm:inline-flex",
129767
+ className: "hidden @4xl/chat:inline-flex",
129692
129768
  title: "Mark read",
129693
129769
  onClick: () => markInboxThreadRead(thread.peer, thread.messages),
129694
129770
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MailOpen, { className: "w-3.5 h-3.5" })
@@ -129696,7 +129772,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129696
129772
  exportableThread && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129697
129773
  variant: "ghost",
129698
129774
  size: "icon-sm",
129699
- className: "hidden sm:inline-flex",
129775
+ className: "hidden @4xl/chat:inline-flex",
129700
129776
  title: "Export thread",
129701
129777
  onClick: () => exportThread({
129702
129778
  ...exportableThread,
@@ -129709,7 +129785,7 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129709
129785
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
129710
129786
  variant: "ghost",
129711
129787
  size: "icon-sm",
129712
- className: "sm:hidden",
129788
+ className: "@4xl/chat:hidden",
129713
129789
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Ellipsis, { className: "w-3.5 h-3.5" })
129714
129790
  })
129715
129791
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DropdownMenuContent, {
@@ -129724,6 +129800,10 @@ function ChatPanel({ threads, onBack, showBackButton }) {
129724
129800
  onClick: interruptAgent,
129725
129801
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CircleStop, { className: "w-3.5 h-3.5" }), "Interrupt"]
129726
129802
  }),
129803
+ agent.branchState === "changes" && agent.branchWorkspaceId && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DropdownMenuItem, {
129804
+ onClick: () => openConfirm("Mark Workspace Ready", `Mark ${displayName(agent)}'s branch ready to land? The relay auto-merge will rebase and land it.`, () => workspaceAction(agent.branchWorkspaceId, "ready")),
129805
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Flag, { className: "w-3.5 h-3.5" }), "Mark Ready"]
129806
+ }),
129727
129807
  canCompact && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DropdownMenuItem, {
129728
129808
  onClick: () => openConfirm("Compact Agent", `Compact context for ${displayName(agent)}?`, () => doAgentAction(agent, "compact")),
129729
129809
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Minimize2, { className: "w-3.5 h-3.5" }), "Compact"]
@@ -130046,7 +130126,7 @@ function ChatView() {
130046
130126
  }
130047
130127
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
130048
130128
  className: "flex -m-4 md:-m-6",
130049
- style: { height: "calc(100dvh - var(--header-h))" },
130129
+ style: { height: "calc(100dvh - var(--header-h) - var(--sat))" },
130050
130130
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
130051
130131
  className: "hidden md:flex w-full",
130052
130132
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
@@ -130082,7 +130162,7 @@ function MobileChatContainer({ children }) {
130082
130162
  return () => vv.removeEventListener("resize", onResize);
130083
130163
  }, []);
130084
130164
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
130085
- className: "fixed inset-x-0 top-0 z-40 flex flex-col bg-background",
130165
+ className: "fixed inset-x-0 top-0 z-40 flex flex-col bg-background pt-[var(--sat)]",
130086
130166
  style: { height: height ? `${height}px` : "100dvh" },
130087
130167
  children
130088
130168
  });
@@ -130101,6 +130181,8 @@ function AgentCard({ agent }) {
130101
130181
  const doAgentAction = useRelayStore((s) => s.doAgentAction);
130102
130182
  const doDeleteAgent = useRelayStore((s) => s.doDeleteAgent);
130103
130183
  const openFilesForAgent = useRelayStore((s) => s.openFilesForAgent);
130184
+ const workspaceAction = useRelayStore((s) => s.workspaceAction);
130185
+ const openWorkspaceFocus = useRelayStore((s) => s.openWorkspaceFocus);
130104
130186
  const { terminalOpen, terminalTarget, terminalOpening, openTerminal: handleOpenTerminal, closeTerminal: handleCloseTerminal } = useAgentTerminal(agent.id);
130105
130187
  const pairsMap = usePairsByAgentId();
130106
130188
  const rawAttention = useAgentAttention(agent);
@@ -130152,6 +130234,14 @@ function AgentCard({ agent }) {
130152
130234
  children: shortPath$1(agent.meta.cwd)
130153
130235
  })
130154
130236
  ]
130237
+ }),
130238
+ agent.branchState && agent.branchWorkspaceId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BranchStateBadge, {
130239
+ state: agent.branchState,
130240
+ className: "mt-0.5 shrink-0",
130241
+ onClick: (e) => {
130242
+ e.stopPropagation();
130243
+ openWorkspaceFocus(agent.branchWorkspaceId);
130244
+ }
130155
130245
  })
130156
130246
  ]
130157
130247
  }),
@@ -130236,6 +130326,14 @@ function AgentCard({ agent }) {
130236
130326
  onClick: () => void handleOpenTerminal(),
130237
130327
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Terminal, { className: "w-3 h-3" })
130238
130328
  }),
130329
+ agent.branchState === "changes" && agent.branchWorkspaceId && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
130330
+ size: "icon",
130331
+ variant: "ghost",
130332
+ className: "h-7 w-7 text-amber-400 hover:text-amber-300",
130333
+ title: "Mark workspace ready — hand off to the auto-merge",
130334
+ onClick: () => openConfirm("Mark Workspace Ready", `Mark ${displayName(agent)}'s branch ready to land? The relay auto-merge will rebase and land it.`, () => workspaceAction(agent.branchWorkspaceId, "ready")),
130335
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Flag, { className: "w-3 h-3" })
130336
+ }),
130239
130337
  canCompact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
130240
130338
  size: "icon",
130241
130339
  variant: "ghost",
@@ -130572,10 +130670,6 @@ function LogViewer({ orchestratorId, session, lines = 200 }) {
130572
130670
  }
130573
130671
  //#endregion
130574
130672
  //#region src/components/views/managed-agents.tsx
130575
- function fmtTime(value) {
130576
- if (!value) return "-";
130577
- return new Date(value).toLocaleString();
130578
- }
130579
130673
  function terminalSessionFor(item, agent) {
130580
130674
  const agentSession = agent?.meta?.tmuxSession;
130581
130675
  if (typeof agentSession === "string" && agentSession.trim()) return agentSession;
@@ -131857,11 +131951,20 @@ function WorkspaceRow({ workspace }) {
131857
131951
  const now = useNow();
131858
131952
  const [expanded, setExpanded] = (0, import_react.useState)(false);
131859
131953
  const agentsById = useRelayStore((s) => s.agentsById);
131954
+ const focused = useRelayStore((s) => s.workspaceFocusId === workspace.id);
131860
131955
  const owner = workspace.ownerAgentId ? agentsById[workspace.ownerAgentId] : void 0;
131861
131956
  const steward = workspace.stewardAgentId ? agentsById[workspace.stewardAgentId] : void 0;
131862
131957
  const path = workspace.worktreePath || workspace.sourceCwd || workspace.repoRoot;
131958
+ const rowRef = (0, import_react.useRef)(null);
131959
+ (0, import_react.useEffect)(() => {
131960
+ if (focused) rowRef.current?.scrollIntoView({
131961
+ behavior: "smooth",
131962
+ block: "center"
131963
+ });
131964
+ }, [focused]);
131863
131965
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
131864
- className: "border-t border-border",
131966
+ ref: rowRef,
131967
+ className: `border-t border-border ${focused ? "bg-primary/5 ring-1 ring-inset ring-primary/40" : ""}`,
131865
131968
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
131866
131969
  className: "grid gap-3 px-3 py-3 text-sm lg:grid-cols-[minmax(180px,1.2fr)_minmax(220px,1.5fr)_minmax(160px,1fr)_minmax(170px,auto)]",
131867
131970
  children: [
@@ -132006,6 +132109,14 @@ function RepoGroup({ repoRoot, workspaces }) {
132006
132109
  function WorkspacesView() {
132007
132110
  const [filter, setFilter] = (0, import_react.useState)("active");
132008
132111
  const workspaces = useRelayStore((s) => s.workspaces);
132112
+ const set = useRelayStore((s) => s.set);
132113
+ const workspaceFocusId = useRelayStore((s) => s.workspaceFocusId);
132114
+ (0, import_react.useEffect)(() => {
132115
+ if (workspaceFocusId) setFilter("all");
132116
+ }, [workspaceFocusId]);
132117
+ (0, import_react.useEffect)(() => () => {
132118
+ set({ workspaceFocusId: null });
132119
+ }, [set]);
132009
132120
  const visibleWorkspaces = (0, import_react.useMemo)(() => filterWorkspaces(workspaces, filter), [workspaces, filter]);
132010
132121
  const grouped = (0, import_react.useMemo)(() => groupWorkspaces(visibleWorkspaces), [visibleWorkspaces]);
132011
132122
  const liveCount = workspaces.filter((item) => LIVE_STATUSES.has(item.status)).length;
@@ -133615,7 +133726,7 @@ function MemoryView() {
133615
133726
  }),
133616
133727
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
133617
133728
  className: "text-xs text-muted-foreground",
133618
- title: fmtTime$1(selectedMemory.updatedAt),
133729
+ title: fmtTime(selectedMemory.updatedAt),
133619
133730
  children: ["updated ", timeAgo(now, selectedMemory.updatedAt)]
133620
133731
  }),
133621
133732
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
@@ -133806,7 +133917,7 @@ function MemoryRow({ memory, selected, now, onSelect }) {
133806
133917
  }),
133807
133918
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
133808
133919
  className: "text-[10px] text-muted-foreground",
133809
- title: fmtTime$1(memory.updatedAt),
133920
+ title: fmtTime(memory.updatedAt),
133810
133921
  children: timeAgo(now, memory.updatedAt)
133811
133922
  }),
133812
133923
  memory.accessCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -133956,7 +134067,7 @@ function ActivityView() {
133956
134067
  }),
133957
134068
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
133958
134069
  className: "text-xs text-muted-foreground ml-auto shrink-0",
133959
- title: fmtTime$1(item.ts ?? item.createdAt),
134070
+ title: fmtTime(item.ts ?? item.createdAt),
133960
134071
  children: timeAgo(now, item.ts ?? item.createdAt)
133961
134072
  })
133962
134073
  ]
@@ -134119,7 +134230,7 @@ function PairCard({ pair, now, agentName, onAccept, onReject, onMessage, onHangu
134119
134230
  children: pair.id.slice(-10)
134120
134231
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
134121
134232
  className: "text-xs text-muted-foreground",
134122
- title: fmtTime$1(pair.updatedAt),
134233
+ title: fmtTime(pair.updatedAt),
134123
134234
  children: timeAgo(now, pair.updatedAt)
134124
134235
  })]
134125
134236
  })]
@@ -134412,7 +134523,7 @@ function MessageRow({ msg, now, agentLabel, agentsById, onReply, onClaim, onRetr
134412
134523
  }),
134413
134524
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
134414
134525
  className: "ml-auto shrink-0",
134415
- title: fmtTime$1(msg.createdAt),
134526
+ title: fmtTime(msg.createdAt),
134416
134527
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
134417
134528
  className: "opacity-40 mr-1",
134418
134529
  children: ["#", msg.id]
@@ -134822,7 +134933,7 @@ function TaskCard({ task, now, agentName, onClaim, onEvents, onStatusChange }) {
134822
134933
  })]
134823
134934
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
134824
134935
  className: "text-xs text-muted-foreground shrink-0",
134825
- title: fmtTime$1(task.createdAt),
134936
+ title: fmtTime(task.createdAt),
134826
134937
  children: ["#", task.id]
134827
134938
  })]
134828
134939
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
@@ -134866,7 +134977,7 @@ function TaskCard({ task, now, agentName, onClaim, onEvents, onStatusChange }) {
134866
134977
  }),
134867
134978
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
134868
134979
  className: "flex items-center gap-1 mt-0.5",
134869
- title: fmtTime$1(task.updatedAt),
134980
+ title: fmtTime(task.updatedAt),
134870
134981
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
134871
134982
  className: "text-muted-foreground/60",
134872
134983
  children: "updated"
@@ -135449,7 +135560,7 @@ function AutomationCard({ automation, runs, now, selected, onEdit, onRun, onTogg
135449
135560
  className: "flex flex-wrap items-center gap-2 text-xs text-muted-foreground",
135450
135561
  children: [
135451
135562
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
135452
- title: automation.nextRunAt ? fmtTime$1(automation.nextRunAt) : void 0,
135563
+ title: automation.nextRunAt ? fmtTime(automation.nextRunAt) : void 0,
135453
135564
  children: ["next ", automation.nextRunAt ? timeAgo(now, automation.nextRunAt) : "disabled"]
135454
135565
  }),
135455
135566
  latestRun && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge$1, {
@@ -135961,7 +136072,7 @@ function RunHistory({ runs, automations, agents, orchestrators, now, logRunId, o
135961
136072
  }),
135962
136073
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
135963
136074
  className: "text-muted-foreground",
135964
- title: fmtTime$1(run.updatedAt),
136075
+ title: fmtTime(run.updatedAt),
135965
136076
  children: timeAgo(now, run.updatedAt)
135966
136077
  }),
135967
136078
  logTarget ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
@@ -155739,14 +155850,14 @@ function MaintenanceCard({ job, now, onRun }) {
155739
155850
  className: "text-muted-foreground",
155740
155851
  children: "Last run"
155741
155852
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: job.lastRunAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
155742
- title: fmtTime$1(job.lastRunAt),
155853
+ title: fmtTime(job.lastRunAt),
155743
155854
  children: timeAgo(now, job.lastRunAt)
155744
155855
  }) : "never" })] }),
155745
155856
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
155746
155857
  className: "text-muted-foreground",
155747
155858
  children: "Next run"
155748
155859
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: job.nextRunAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
155749
- title: fmtTime$1(job.nextRunAt),
155860
+ title: fmtTime(job.nextRunAt),
155750
155861
  children: nextRunText(now, job.nextRunAt)
155751
155862
  }) : "-" })] }),
155752
155863
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
@@ -155817,14 +155928,14 @@ function MaintenanceRow({ job, now, onRun }) {
155817
155928
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
155818
155929
  className: "px-3 py-3 text-xs text-muted-foreground",
155819
155930
  children: job.lastRunAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
155820
- title: fmtTime$1(job.lastRunAt),
155931
+ title: fmtTime(job.lastRunAt),
155821
155932
  children: timeAgo(now, job.lastRunAt)
155822
155933
  }) : "never"
155823
155934
  }),
155824
155935
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
155825
155936
  className: "px-3 py-3 text-xs text-muted-foreground",
155826
155937
  children: job.nextRunAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
155827
- title: fmtTime$1(job.nextRunAt),
155938
+ title: fmtTime(job.nextRunAt),
155828
155939
  children: nextRunText(now, job.nextRunAt)
155829
155940
  }) : "-"
155830
155941
  }),
@@ -156961,7 +157072,7 @@ function AgentDiagnostics({ agent, orchestrators }) {
156961
157072
  }),
156962
157073
  managedAgent.startedAt && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KV, {
156963
157074
  label: "Started",
156964
- value: fmtTime$1(managedAgent.startedAt)
157075
+ value: fmtTime(managedAgent.startedAt)
156965
157076
  }),
156966
157077
  managedOrch && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KV, {
156967
157078
  label: "Orchestrator",
@@ -157636,7 +157747,7 @@ function AgentDetailDrawer() {
157636
157747
  children: "Created"
157637
157748
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
157638
157749
  className: "truncate",
157639
- children: fmtTime$1(agent.createdAt)
157750
+ children: fmtTime(agent.createdAt)
157640
157751
  })]
157641
157752
  }),
157642
157753
  agent.machine && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -158098,7 +158209,7 @@ function ActiveMemoryRow({ memory, now, onOpen }) {
158098
158209
  ]
158099
158210
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
158100
158211
  className: "shrink-0 text-right text-[10px] text-muted-foreground",
158101
- title: fmtTime$1(memory.lastAccessedAt ?? memory.updatedAt),
158212
+ title: fmtTime(memory.lastAccessedAt ?? memory.updatedAt),
158102
158213
  children: timeAgo(now, memory.lastAccessedAt ?? memory.updatedAt)
158103
158214
  })]
158104
158215
  })
@@ -158224,7 +158335,7 @@ function TimelineRow({ entry, now }) {
158224
158335
  children: entry.title
158225
158336
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
158226
158337
  className: "ml-auto shrink-0 text-[10px] text-muted-foreground",
158227
- title: fmtTime$1(entry.ts),
158338
+ title: fmtTime(entry.ts),
158228
158339
  children: timeAgo(now, entry.ts)
158229
158340
  })]
158230
158341
  }),
@@ -158897,7 +159008,7 @@ function TaskEventsModal() {
158897
159008
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
158898
159009
  className: "text-xs text-muted-foreground mt-1",
158899
159010
  children: [
158900
- fmtTime$1(evt.createdAt),
159011
+ fmtTime(evt.createdAt),
158901
159012
  " · ",
158902
159013
  evt.source
158903
159014
  ]
@@ -160579,12 +160690,12 @@ function App() {
160579
160690
  }, [commandPaletteOpen]);
160580
160691
  const ViewComponent = views[view] || OverviewView;
160581
160692
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
160582
- className: "flex min-h-dvh",
160693
+ className: "flex min-h-[calc(100dvh-var(--sat))] mt-[var(--sat)]",
160583
160694
  children: [
160584
160695
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sidebar, {}),
160585
160696
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileDrawer, {}),
160586
160697
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", {
160587
- className: "flex-1 h-dvh overflow-y-auto",
160698
+ className: "flex-1 h-[calc(100dvh-var(--sat))] overflow-y-auto",
160588
160699
  children: [
160589
160700
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MobileNav, {}),
160590
160701
  !authNeeded && connectionError && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -161107,6 +161218,10 @@ if ("serviceWorker" in navigator) {
161107
161218
  container: card-header / inline-size;
161108
161219
  }
161109
161220
 
161221
+ .\@container\/chat {
161222
+ container: chat / inline-size;
161223
+ }
161224
+
161110
161225
  .pointer-events-none {
161111
161226
  pointer-events: none;
161112
161227
  }
@@ -161203,6 +161318,10 @@ if ("serviceWorker" in navigator) {
161203
161318
  top: calc(var(--header-h, 3rem) + .5rem);
161204
161319
  }
161205
161320
 
161321
+ .top-\[var\(--sat\)\] {
161322
+ top: var(--sat);
161323
+ }
161324
+
161206
161325
  .-right-0\.5 {
161207
161326
  right: calc(var(--spacing) * -.5);
161208
161327
  }
@@ -161405,6 +161524,10 @@ if ("serviceWorker" in navigator) {
161405
161524
  margin-top: calc(var(--spacing) * 4);
161406
161525
  }
161407
161526
 
161527
+ .mt-\[var\(--sat\)\] {
161528
+ margin-top: var(--sat);
161529
+ }
161530
+
161408
161531
  .mt-auto {
161409
161532
  margin-top: auto;
161410
161533
  }
@@ -161659,16 +161782,12 @@ if ("serviceWorker" in navigator) {
161659
161782
  height: calc(100dvh - 24rem);
161660
161783
  }
161661
161784
 
161662
- .h-\[var\(--header-h\)\] {
161663
- height: var(--header-h);
161664
- }
161665
-
161666
- .h-auto {
161667
- height: auto;
161785
+ .h-\[calc\(100dvh-var\(--sat\)\)\] {
161786
+ height: calc(100dvh - var(--sat));
161668
161787
  }
161669
161788
 
161670
- .h-dvh {
161671
- height: 100dvh;
161789
+ .h-\[var\(--header-h\)\] {
161790
+ height: var(--header-h);
161672
161791
  }
161673
161792
 
161674
161793
  .h-fit {
@@ -161791,8 +161910,8 @@ if ("serviceWorker" in navigator) {
161791
161910
  min-height: 360px;
161792
161911
  }
161793
161912
 
161794
- .min-h-dvh {
161795
- min-height: 100dvh;
161913
+ .min-h-\[calc\(100dvh-var\(--sat\)\)\] {
161914
+ min-height: calc(100dvh - var(--sat));
161796
161915
  }
161797
161916
 
161798
161917
  .w-\(--radix-dropdown-menu-trigger-width\) {
@@ -163811,6 +163930,10 @@ if ("serviceWorker" in navigator) {
163811
163930
  padding-top: 15vh;
163812
163931
  }
163813
163932
 
163933
+ .pt-\[var\(--sat\)\] {
163934
+ padding-top: var(--sat);
163935
+ }
163936
+
163814
163937
  .pr-2 {
163815
163938
  padding-right: calc(var(--spacing) * 2);
163816
163939
  }
@@ -164684,6 +164807,10 @@ if ("serviceWorker" in navigator) {
164684
164807
  animation-play-state: paused;
164685
164808
  }
164686
164809
 
164810
+ .ring-inset {
164811
+ --tw-ring-inset: inset;
164812
+ }
164813
+
164687
164814
  .running {
164688
164815
  animation-play-state: running;
164689
164816
  }
@@ -165011,6 +165138,10 @@ if ("serviceWorker" in navigator) {
165011
165138
  }
165012
165139
  }
165013
165140
 
165141
+ .hover\:text-amber-300:hover {
165142
+ color: var(--color-amber-300);
165143
+ }
165144
+
165014
165145
  .hover\:text-blue-300:hover {
165015
165146
  color: var(--color-blue-300);
165016
165147
  }
@@ -165066,13 +165197,36 @@ if ("serviceWorker" in navigator) {
165066
165197
  .hover\:opacity-100:hover {
165067
165198
  opacity: 1;
165068
165199
  }
165200
+
165201
+ .hover\:brightness-125:hover {
165202
+ --tw-brightness: brightness(125%);
165203
+ filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
165204
+ }
165069
165205
  }
165070
165206
 
165071
165207
  .focus\:bg-accent:focus {
165072
165208
  background-color: var(--accent);
165073
165209
  }
165074
165210
 
165075
- .focus\:text-accent-foreground:focus, :is(.focus\:\*\*\:text-accent-foreground:focus *), :is(.not-data-\[variant\=destructive\]\:focus\:\*\*\:text-accent-foreground:not([data-variant="destructive"]):focus *) {
165211
+ .focus\:text-accent-foreground:focus {
165212
+ color: var(--accent-foreground);
165213
+ }
165214
+
165215
+ .focus\:ring-1:focus {
165216
+ --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
165217
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
165218
+ }
165219
+
165220
+ .focus\:ring-current:focus {
165221
+ --tw-ring-color: currentcolor;
165222
+ }
165223
+
165224
+ .focus\:outline-none:focus {
165225
+ --tw-outline-style: none;
165226
+ outline-style: none;
165227
+ }
165228
+
165229
+ :is(.focus\:\*\*\:text-accent-foreground:focus *), :is(.not-data-\[variant\=destructive\]\:focus\:\*\*\:text-accent-foreground:not([data-variant="destructive"]):focus *) {
165076
165230
  color: var(--accent-foreground);
165077
165231
  }
165078
165232
 
@@ -165557,10 +165711,6 @@ if ("serviceWorker" in navigator) {
165557
165711
  display: block;
165558
165712
  }
165559
165713
 
165560
- .sm\:flex {
165561
- display: flex;
165562
- }
165563
-
165564
165714
  .sm\:hidden {
165565
165715
  display: none;
165566
165716
  }
@@ -165868,6 +166018,26 @@ if ("serviceWorker" in navigator) {
165868
166018
  }
165869
166019
  }
165870
166020
 
166021
+ @container chat (min-width: 42rem) {
166022
+ .\@2xl\/chat\:flex {
166023
+ display: flex;
166024
+ }
166025
+ }
166026
+
166027
+ @container chat (min-width: 56rem) {
166028
+ .\@4xl\/chat\:flex {
166029
+ display: flex;
166030
+ }
166031
+
166032
+ .\@4xl\/chat\:hidden {
166033
+ display: none;
166034
+ }
166035
+
166036
+ .\@4xl\/chat\:inline-flex {
166037
+ display: inline-flex;
166038
+ }
166039
+ }
166040
+
165871
166041
  .dark\:border-input:is(.dark *) {
165872
166042
  border-color: var(--input);
165873
166043
  }
@@ -166954,6 +167124,7 @@ if ("serviceWorker" in navigator) {
166954
167124
 
166955
167125
  :root {
166956
167126
  --header-h: 3rem;
167127
+ --sat: env(safe-area-inset-top, 0px);
166957
167128
  }
166958
167129
 
166959
167130
  .code-preview .shiki {