@nextclaw/ui 0.26.4 → 0.26.5

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.
Files changed (99) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/.vite/manifest.json +361 -361
  3. package/dist/assets/{account-panel-DVi_jhkG.js → account-panel-BAH7FW6z.js} +1 -1
  4. package/dist/assets/{api-BZvNpFOS.js → api-DjiZvIa0.js} +1 -1
  5. package/dist/assets/app-presenter-provider-CCRFsFYr.js +232 -0
  6. package/dist/assets/{appearance-settings-page-AZNBzLmT.js → appearance-settings-page-CdP86QJ7.js} +1 -1
  7. package/dist/assets/{book-open-CmRdT3N1.js → book-open-Bcnn2_uV.js} +1 -1
  8. package/dist/assets/{card-CdRBL1E0.js → card-Cqs73hGI.js} +1 -1
  9. package/dist/assets/{channels-list-page-eZN74FN3.js → channels-list-page-5qGagKuE.js} +1 -1
  10. package/dist/assets/{circle-dashed-HOgt3gIJ.js → circle-dashed-EY1ScSMe.js} +1 -1
  11. package/dist/assets/{client-DKKbdJ6Q.js → client-CH7w6yRV.js} +1 -1
  12. package/dist/assets/{config-split-page-BA3V6b3Q.js → config-split-page-CuEGQL8Z.js} +1 -1
  13. package/dist/assets/{confirm-dialog-8vqYZ0wy.js → confirm-dialog-CxfecBzO.js} +1 -1
  14. package/dist/assets/{context-menu-DHVVdHzN.js → context-menu-BsCj2fRs.js} +1 -1
  15. package/dist/assets/{createLucideIcon-DE0sB9Nu.js → createLucideIcon-Cfo2ySi5.js} +1 -1
  16. package/dist/assets/{desktop-capabilities-page-B9-B9k1A.js → desktop-capabilities-page-BDYITStl.js} +1 -1
  17. package/dist/assets/{desktop-update-config-Cfr3IRUe.js → desktop-update-config-e-zhkJuS.js} +1 -1
  18. package/dist/assets/{dialog-BUfWO8hr.js → dialog-QjQoKbIV.js} +1 -1
  19. package/dist/assets/doc-browser-CLEdkH9z.js +1 -0
  20. package/dist/assets/{doc-browser-context-ClLgMbxd.js → doc-browser-context-DwgG6wrz.js} +1 -1
  21. package/dist/assets/{download-CKqS1Ksj.js → download-BoaKzDJk.js} +1 -1
  22. package/dist/assets/{es2015-BiB05Sav.js → es2015-Bp6cuSGh.js} +1 -1
  23. package/dist/assets/{extensions-vPD4dGqt.js → extensions-CgShSIkd.js} +1 -1
  24. package/dist/assets/{eye-bKzylu3p.js → eye-kisejBFH.js} +1 -1
  25. package/dist/assets/{form-actions-CCoxz33Q.js → form-actions-D9JWSFQu.js} +1 -1
  26. package/dist/assets/{i18n-OGmF0Ws_.js → i18n-Bm3Ov7Fy.js} +2 -2
  27. package/dist/assets/{keyboard-shortcuts-settings-page-D8rosOVh.js → keyboard-shortcuts-settings-page-DZ8A1iLg.js} +1 -1
  28. package/dist/assets/loader-circle-Bd1fTm-x.js +1 -0
  29. package/dist/assets/{login-page-BT3GV3Sb.js → login-page-C-DvcG3L.js} +1 -1
  30. package/dist/assets/login-page-D99JjH9F.js +1 -0
  31. package/dist/assets/{main-bEWCGDHr.js → main-Bt5r6b21.js} +2 -2
  32. package/dist/assets/main-DXd_aKJV.css +1 -0
  33. package/dist/assets/main-i18n-catalog.config-D0Ll36J_.js +1 -0
  34. package/dist/assets/mcp-marketplace-page-DUoGfSmY.js +1 -0
  35. package/dist/assets/{model-config-page-D21a-BO0.js → model-config-page-9NNf-mzK.js} +1 -1
  36. package/dist/assets/{navigation-link-DC-Pku0Y.js → navigation-link-CjxNC8aT.js} +1 -1
  37. package/dist/assets/panel-app-i18n-catalog.config-Ddf2Kv8A.js +1 -0
  38. package/dist/assets/{panelStandalone-CX8X2hjh.js → panelStandalone-BaUzY8Wy.js} +2 -2
  39. package/dist/assets/{privacy-settings-page-e0LFHZJm.js → privacy-settings-page-CVMBFuak.js} +1 -1
  40. package/dist/assets/projects-BEsU3box.js +1 -0
  41. package/dist/assets/{provider-models-DFQgF4hS.js → provider-models-Dm-pmWAA.js} +1 -1
  42. package/dist/assets/{provider-scoped-model-input-DaONL0j_.js → provider-scoped-model-input-CzrXg4cX.js} +1 -1
  43. package/dist/assets/{providers-config-page-CEOhQlMe.js → providers-config-page-839uUADZ.js} +1 -1
  44. package/dist/assets/{puzzle-D_TiFXOv.js → puzzle-BGvD2DPZ.js} +1 -1
  45. package/dist/assets/{pwa-C9ac_1dg.js → pwa-DNNK_8E9.js} +1 -1
  46. package/dist/assets/{refresh-cw-BG8VfcdA.js → refresh-cw-BlXDrVP0.js} +1 -1
  47. package/dist/assets/remote-B5qIuUbT.js +1 -0
  48. package/dist/assets/{rotate-cw-DPEegUU2.js → rotate-cw-ei6rPD6z.js} +1 -1
  49. package/dist/assets/{runtime-config-page-DDT1dVLt.js → runtime-config-page-Bf-4JYxQ.js} +1 -1
  50. package/dist/assets/{save-CPlctBjT.js → save-DdF-bXgC.js} +1 -1
  51. package/dist/assets/{search-config-page-CDwmd6eX.js → search-config-page-C0qA3j-T.js} +1 -1
  52. package/dist/assets/{secrets-config-page-1OvgmwPv.js → secrets-config-page-DxfZWpnk.js} +1 -1
  53. package/dist/assets/security-config-CItfIQZ4.js +1 -0
  54. package/dist/assets/{select-Y9IEbx9x.js → select-CWyjnar7.js} +1 -1
  55. package/dist/assets/{service-apps-panel-DPrLeF3N.js → service-apps-panel-D3SOkRVv.js} +1 -1
  56. package/dist/assets/{settings-2-CrGx9_De.js → settings-2-CrNhfInU.js} +1 -1
  57. package/dist/assets/{status-dot-Cb8ewlUr.js → status-dot-C3SRFEta.js} +1 -1
  58. package/dist/assets/{tag-chip-D-6aPuuh.js → tag-chip-BIuavK2K.js} +1 -1
  59. package/dist/assets/{theme-provider-BjF1Eowc.js → theme-provider-CWUz4yO9.js} +1 -1
  60. package/dist/assets/{trash-2-DER2EJKK.js → trash-2-hAbJh9VZ.js} +1 -1
  61. package/dist/assets/{use-config-BM5jC65L.js → use-config-evzage09.js} +1 -1
  62. package/dist/assets/{use-desktop-capabilities-ezKJwKqg.js → use-desktop-capabilities-BYDjFlpt.js} +1 -1
  63. package/dist/assets/{use-viewport-layout-vmbQUNT6.js → use-viewport-layout-D_9XWGDV.js} +1 -1
  64. package/dist/assets/x-ChPbNv39.js +1 -0
  65. package/dist/index.html +34 -34
  66. package/dist/panel-standalone.html +10 -10
  67. package/package.json +3 -3
  68. package/src/app/configs/__tests__/app-navigation.config.test.ts +4 -2
  69. package/src/app/configs/app-navigation.config.ts +7 -2
  70. package/src/features/chat/features/message/components/chat-message-list.container.tsx +0 -2
  71. package/src/features/chat/features/message/utils/__tests__/chat-message-process-summary.utils.test.ts +4 -6
  72. package/src/features/chat/features/message/utils/chat-message-process-summary.utils.ts +2 -10
  73. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
  74. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -0
  75. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -3
  76. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +1 -0
  77. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +1 -1
  78. package/src/features/inbox/pages/inbox-page.test.ts +12 -3
  79. package/src/features/inbox/pages/inbox-page.tsx +31 -24
  80. package/src/features/projects/pages/project-home-page.tsx +4 -2
  81. package/src/platforms/mobile/components/__tests__/mobile-app-shell.test.tsx +9 -0
  82. package/src/platforms/mobile/components/mobile-app-shell.tsx +4 -2
  83. package/src/platforms/mobile/components/mobile-topbar.tsx +2 -2
  84. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +3 -3
  85. package/src/shared/components/workbench/workbench-surface.tsx +1 -1
  86. package/src/shared/lib/i18n/locales/en-US/chat.json +1 -2
  87. package/src/shared/lib/i18n/locales/zh-CN/chat.json +1 -2
  88. package/dist/assets/app-presenter-provider-BcYL-VNe.js +0 -124
  89. package/dist/assets/doc-browser-w8q1j0jL.js +0 -1
  90. package/dist/assets/loader-circle-Clq1Gtb1.js +0 -1
  91. package/dist/assets/login-page-DKId3By8.js +0 -1
  92. package/dist/assets/main-i18n-catalog.config-Bpu5GcwF.js +0 -1
  93. package/dist/assets/main-kqMRTwOs.css +0 -1
  94. package/dist/assets/mcp-marketplace-page-CZIP6j3L.js +0 -1
  95. package/dist/assets/panel-app-i18n-catalog.config-D44qmtfk.js +0 -1
  96. package/dist/assets/projects-Rki7Fmth.js +0 -1
  97. package/dist/assets/remote-DkSx5x4R.js +0 -1
  98. package/dist/assets/security-config-Pv4CM-kw.js +0 -1
  99. package/dist/assets/x-DSz9cGhy.js +0 -1
@@ -2,7 +2,7 @@ import { PageResourceActionsMenu } from '@/features/right-panel-resources';
2
2
  import { pageResourceFromSystemObject } from '@/features/right-panel-resources';
3
3
  import { useEffect, useMemo, useState } from "react";
4
4
  import type { InboxDelivery } from "@nextclaw/shared";
5
- import { Archive, Inbox, MessageCircle, MoreVertical, RotateCcw, Trash2 } from "lucide-react";
5
+ import { Archive, ArrowLeft, Inbox, MessageCircle, MoreVertical, RotateCcw, Trash2 } from "lucide-react";
6
6
  import { ContextMenu, ContextMenuTrigger } from '@/shared/components/ui/context-menu/context-menu';
7
7
  import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
8
8
  import { Link, useNavigate, useParams } from "react-router-dom";
@@ -167,6 +167,7 @@ function InboxListPane({
167
167
 
168
168
  function InboxDetailPane({
169
169
  delivery,
170
+ isMobile,
170
171
  error,
171
172
  pending,
172
173
  onArchiveToggle,
@@ -175,6 +176,7 @@ function InboxDetailPane({
175
176
  onReadToggle,
176
177
  }: {
177
178
  delivery: InboxDelivery | null;
179
+ isMobile: boolean;
178
180
  error: string | null;
179
181
  pending: boolean;
180
182
  onArchiveToggle: () => void;
@@ -182,38 +184,52 @@ function InboxDetailPane({
182
184
  onDelete: () => void;
183
185
  onReadToggle: () => void;
184
186
  }) {
187
+ const navigate = useNavigate();
188
+ const backButton = <IconActionButton size="sm" icon={<ArrowLeft className="h-4 w-4" />} label={t("inboxTitle")} onClick={() => navigate('/inbox')} />;
185
189
  const scrollRestoration = useScrollRestoration<HTMLDivElement>({
186
190
  restorationKey: delivery ? `inbox:delivery:${delivery.id}` : null,
187
191
  });
188
192
  const { onScroll, scrollRef } = scrollRestoration;
189
193
  if (!delivery) {
190
- return <main className="flex min-h-0 flex-col"><InboxEmptyState selection /></main>;
194
+ return <main className="flex min-h-0 flex-col"><div className="md:hidden">{backButton}</div><InboxEmptyState selection /></main>;
191
195
  }
192
196
  const isHtml = delivery.contentType === "html";
193
197
  return (
194
- <main className="flex min-h-0 flex-col">
195
- <div className="shrink-0 px-4 py-2 md:border-b md:border-border/50 md:px-6 md:py-3">
196
- <div className="flex min-h-7 min-w-0 items-center gap-2">
198
+ <main className="flex min-h-0 min-w-0 flex-col max-md:pt-[env(safe-area-inset-top,0px)] max-md:pb-[env(safe-area-inset-bottom,0px)]">
199
+ <div className="shrink-0 border-b border-border/50 px-2 py-2 md:px-6 md:py-3">
200
+ <div className="flex min-h-7 min-w-0 items-center gap-1">
201
+ <div className="md:hidden">{backButton}</div>
197
202
  <h2
198
203
  title={delivery.title}
199
- className="min-w-0 truncate text-sm font-medium text-foreground"
204
+ className="min-w-0 flex-1 truncate text-sm font-medium text-foreground md:flex-none"
200
205
  >
201
206
  {delivery.title}
202
207
  </h2>
203
- <span className="hidden shrink-0 text-muted-foreground sm:inline" aria-hidden="true">·</span>
208
+ <span className="hidden shrink-0 text-muted-foreground md:inline" aria-hidden="true">·</span>
204
209
  <time
205
- className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground sm:block"
210
+ className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground md:block"
206
211
  dateTime={delivery.createdAt}
207
212
  >
208
213
  {formatDateTime(delivery.createdAt)}
209
214
  </time>
215
+ {isMobile ? <div className="flex shrink-0 items-center">
216
+ <IconActionButton size="sm" icon={<MessageCircle className="h-4 w-4" />} label={t('inboxContinueChat')} disabled={pending} onClick={onContinue} />
217
+ <ContextMenu label={t('inboxTitle')} groups={[{ key: 'delivery', items: [
218
+ { key: 'read', label: delivery.readAt ? t('inboxMarkUnread') : t('inboxMarkRead'), disabled: pending, onSelect: onReadToggle },
219
+ { key: 'archive', label: delivery.archivedAt ? t('inboxRestore') : t('inboxArchive'), icon: <Archive className="h-4 w-4" />, disabled: pending, onSelect: onArchiveToggle },
220
+ { key: 'delete', label: t('inboxDelete'), icon: <Trash2 className="h-4 w-4" />, destructive: true, disabled: pending, onSelect: onDelete },
221
+ ] }]}>
222
+ <div><ContextMenuTrigger><IconActionButton size="sm" icon={<MoreVertical className="h-4 w-4" />} label={t('more')} /></ContextMenuTrigger></div>
223
+ </ContextMenu>
224
+ </div> : null}
210
225
  </div>
211
226
  </div>
227
+ {error ? <p role="alert" className="shrink-0 px-4 py-2 text-sm text-destructive">{error}</p> : null}
212
228
  <div className={cn(
213
229
  "min-h-0 flex-1",
214
230
  isHtml
215
231
  ? "p-0 md:p-4"
216
- : "custom-scrollbar overflow-y-auto px-5 py-5 sm:px-6 sm:py-6",
232
+ : "custom-scrollbar overflow-y-auto overscroll-contain px-4 py-4 sm:px-6 sm:py-6",
217
233
  )}
218
234
  ref={scrollRef}
219
235
  onScroll={onScroll}
@@ -228,8 +244,7 @@ function InboxDetailPane({
228
244
  />
229
245
  </div>
230
246
  </div>
231
- <div className="shrink-0 border-t border-border/50 px-4 py-2 md:px-6 md:py-3">
232
- {error ? <p role="alert" className="mb-2 text-sm text-destructive">{error}</p> : null}
247
+ {!isMobile ? <div className="shrink-0 border-t border-border/50 px-6 py-3">
233
248
  <div className="flex items-center justify-between gap-2">
234
249
  <div className="hidden md:flex flex-wrap items-center gap-1">
235
250
  <Button size="sm" variant="outline" disabled={pending} onClick={onReadToggle}>
@@ -246,21 +261,12 @@ function InboxDetailPane({
246
261
  {t("inboxDelete")}
247
262
  </Button>
248
263
  </div>
249
- <div className="md:hidden">
250
- <ContextMenu label={t('inboxTitle')} groups={[{ key: 'delivery', items: [
251
- { key: 'read', label: delivery.readAt ? t('inboxMarkUnread') : t('inboxMarkRead'), disabled: pending, onSelect: onReadToggle },
252
- { key: 'archive', label: delivery.archivedAt ? t('inboxRestore') : t('inboxArchive'), icon: <Archive className="h-4 w-4" />, disabled: pending, onSelect: onArchiveToggle },
253
- { key: 'delete', label: t('inboxDelete'), icon: <Trash2 className="h-4 w-4" />, destructive: true, disabled: pending, onSelect: onDelete },
254
- ] }]}>
255
- <div><ContextMenuTrigger><IconActionButton icon={<MoreVertical className="h-4 w-4" />} label={t('more')} /></ContextMenuTrigger></div>
256
- </ContextMenu>
257
- </div>
258
264
  <Button size="sm" disabled={pending} onClick={onContinue}>
259
265
  <MessageCircle className="mr-2 h-4 w-4" />
260
266
  {t("inboxContinueChat")}
261
267
  </Button>
262
268
  </div>
263
- </div>
269
+ </div> : null}
264
270
  </main>
265
271
  );
266
272
  }
@@ -359,8 +365,8 @@ export function InboxPage() {
359
365
  });
360
366
  };
361
367
 
362
- const showList = !isMobile || !activeDelivery;
363
- const showDetail = !isMobile || Boolean(activeDelivery);
368
+ const showList = !isMobile || !deliveryId;
369
+ const showDetail = !isMobile || Boolean(deliveryId);
364
370
 
365
371
  return (
366
372
  <div className="flex h-full min-h-0 flex-col md:gap-6">
@@ -372,7 +378,7 @@ export function InboxPage() {
372
378
 
373
379
  <div className="min-h-0 flex-1 overflow-hidden bg-background md:rounded-2xl md:border md:border-border/60">
374
380
  {deliveriesQuery.isError ? (
375
- <div role="alert" className="p-6 text-sm text-destructive">{t("inboxLoadError")}</div>
381
+ <div className="p-4">{isMobile && deliveryId ? <IconActionButton icon={<ArrowLeft className="h-4 w-4" />} label={t("inboxTitle")} onClick={() => navigate('/inbox')} /> : null}<p role="alert" className="text-sm text-destructive">{t("inboxLoadError")}</p></div>
376
382
  ) : (
377
383
  <div className="grid h-full min-h-0 grid-cols-1 md:grid-cols-[300px_minmax(0,1fr)]">
378
384
  {showList ? <InboxListPane
@@ -383,6 +389,7 @@ export function InboxPage() {
383
389
  /> : null}
384
390
  {showDetail ? <InboxDetailPane
385
391
  delivery={activeDelivery}
392
+ isMobile={isMobile}
386
393
  error={error}
387
394
  pending={pendingAction !== null}
388
395
  onArchiveToggle={toggleArchive}
@@ -1,5 +1,5 @@
1
1
  import { useState } from "react";
2
- import { useNavigate, useParams } from "react-router-dom";
2
+ import { useLocation, useNavigate, useParams } from "react-router-dom";
3
3
  import { useProjects } from "@/shared/hooks/use-projects";
4
4
  import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
5
5
  import { t } from "@/shared/lib/i18n";
@@ -43,6 +43,7 @@ export function ProjectsPage() {
43
43
  tab?: string;
44
44
  }>();
45
45
  const navigate = useNavigate();
46
+ const { state } = useLocation();
46
47
  const presenter = usePresenter();
47
48
  const { isMobile } = useViewportLayout();
48
49
  const projects = useProjects();
@@ -86,7 +87,7 @@ export function ProjectsPage() {
86
87
  <select
87
88
  id="project-home-selection"
88
89
  value=""
89
- onChange={(event) => navigate(`/projects/${encodeURIComponent(event.target.value)}/overview`)}
90
+ onChange={(event) => navigate(`/projects/${encodeURIComponent(event.target.value)}/overview`, { state })}
90
91
  className="min-h-11 w-full rounded-xl border border-border bg-card px-3 text-base text-foreground"
91
92
  >
92
93
  <option value="" disabled>{t("projectsChoose")}</option>
@@ -117,6 +118,7 @@ export function ProjectsPage() {
117
118
  onValueChange={(value) =>
118
119
  navigate(
119
120
  `/projects/${encodeURIComponent(selectedProject.id)}/${value}`,
121
+ { state },
120
122
  )
121
123
  }
122
124
  >
@@ -31,6 +31,15 @@ function renderShell(pathname: string) {
31
31
  }
32
32
 
33
33
  describe("MobileAppShell", () => {
34
+ it("lets inbox details own their reading chrome and restores navigation on the list", () => {
35
+ const detail = renderShell("/inbox/report-1");
36
+ expect(screen.queryByTestId("mobile-bottom-nav")).toBeNull();
37
+ expect(screen.queryByTestId("mobile-topbar")).toBeNull();
38
+ detail.unmount();
39
+ renderShell("/inbox");
40
+ expect(screen.getByTestId("mobile-bottom-nav")).toBeTruthy();
41
+ expect(screen.getByTestId("mobile-topbar")).toBeTruthy();
42
+ });
34
43
  it("shows the bottom navigation on the chat list route", () => {
35
44
  const { shell } = renderShell("/chat");
36
45
 
@@ -1,6 +1,7 @@
1
1
  import { lazy, Suspense } from "react";
2
2
  import {
3
3
  isChatSessionDetailRoute,
4
+ isInboxDetailRoute,
4
5
  isMainWorkspaceRoute,
5
6
  } from "@/app/configs/app-navigation.config";
6
7
  import { MobileBottomNav } from "@/platforms/mobile/components/mobile-bottom-nav";
@@ -32,8 +33,9 @@ export function MobileAppShell({
32
33
  children,
33
34
  }: MobileAppShellProps) {
34
35
  const isMainRoute = isMainWorkspaceRoute(pathname);
35
- const showTopbar = pathname !== '/chat' && !isChatSessionDetailRoute(pathname);
36
- const showBottomNav = !isChatSessionDetailRoute(pathname);
36
+ const ownsDetailChrome = isChatSessionDetailRoute(pathname) || isInboxDetailRoute(pathname);
37
+ const showTopbar = pathname !== '/chat' && !ownsDetailChrome;
38
+ const showBottomNav = !ownsDetailChrome;
37
39
 
38
40
  return (
39
41
  <div className="flex h-[100svh] flex-col bg-background font-sans text-foreground supports-[height:100dvh]:h-[100dvh]">
@@ -6,8 +6,8 @@ import { IconActionButton } from "@/shared/components/ui/actions/icon-action-but
6
6
 
7
7
  export function MobileTopbar({ leadingInset }: { leadingInset?: string }) {
8
8
  const navigate = useNavigate();
9
- const { pathname } = useLocation();
10
- const routeMeta = resolveMobileRouteMeta(pathname, t);
9
+ const { pathname, state } = useLocation();
10
+ const routeMeta = resolveMobileRouteMeta(pathname, t, typeof state?.returnTo === 'string' ? state.returnTo : undefined);
11
11
 
12
12
  return (
13
13
  <header
@@ -233,12 +233,12 @@ function CompactTabItem({
233
233
  onClick={(event) => event.target === event.currentTarget && tab.onSelect()}
234
234
  className={cn(
235
235
  tabBaseClassName ??
236
- "flex max-w-[180px] cursor-pointer items-center gap-1.5 border-r border-gray-200/70 border-b-2 px-2.5 py-2 transition-colors",
236
+ "flex h-8 max-w-[180px] cursor-pointer items-center gap-1.5 border-r border-border/50 px-2.5 transition-colors",
237
237
  "group relative",
238
238
  tab.active
239
- ? (activeTabClassName ?? "border-b-primary bg-[var(--interaction-selection)] text-foreground")
239
+ ? (activeTabClassName ?? "bg-background text-foreground")
240
240
  : (inactiveTabClassName ??
241
- "border-b-transparent bg-transparent text-muted-foreground hover:bg-[var(--interaction-hover)]"),
241
+ "bg-transparent text-muted-foreground hover:bg-[var(--interaction-hover)]"),
242
242
  )}
243
243
  >
244
244
  <CompactTabLabelButton tab={tab} labelClassName={labelClassName} />
@@ -265,7 +265,7 @@ export function WorkbenchSurface({
265
265
  }}
266
266
  >
267
267
  <header
268
- className="flex min-h-10 shrink-0 select-none items-center gap-1 border-b border-border/60 bg-muted/30 px-2"
268
+ className={cn("flex shrink-0 select-none items-center gap-1 border-b border-border/60 bg-muted/30 pr-2", navigation && !state.minimized ? "min-h-8 pl-0" : "min-h-10 pl-2")}
269
269
  style={{ touchAction: floating ? "none" : undefined, paddingTop: isCompact ? "env(safe-area-inset-top, 0px)" : undefined }}
270
270
  onPointerDown={(event) => startInteraction(event)}
271
271
  onDoubleClick={(event) => {
@@ -282,8 +282,6 @@
282
282
  "chatHistoryLoadFailed": "Couldn’t load earlier messages",
283
283
  "chatHistoryRetry": "Retry",
284
284
  "chatProcessSummaryProcessed": "Processed",
285
- "chatProcessSummaryError": "Failed",
286
- "chatProcessSummaryStopped": "Stopped",
287
285
  "chatProcessDurationHoursMinutes": "{hours}h {minutes}m",
288
286
  "chatProcessDurationHours": "{hours}h",
289
287
  "chatProcessDurationMinutesSeconds": "{minutes}m {seconds}s",
@@ -610,6 +608,7 @@
610
608
  "chatMessageCopy": "Copy",
611
609
  "chatMessageCopied": "Copied",
612
610
  "chatMermaidDiagram": "Diagram",
611
+ "chatMarkdownFrontmatter": "Document properties",
613
612
  "chatMermaidExpand": "Expand diagram",
614
613
  "chatMermaidLoading": "Rendering diagram…",
615
614
  "chatMermaidRenderError": "Diagram could not be rendered; showing source instead",
@@ -282,8 +282,6 @@
282
282
  "chatHistoryLoadFailed": "较早消息加载失败",
283
283
  "chatHistoryRetry": "重试",
284
284
  "chatProcessSummaryProcessed": "已处理",
285
- "chatProcessSummaryError": "处理失败",
286
- "chatProcessSummaryStopped": "已停止",
287
285
  "chatProcessDurationHoursMinutes": "{hours}小时{minutes}分钟",
288
286
  "chatProcessDurationHours": "{hours}小时",
289
287
  "chatProcessDurationMinutesSeconds": "{minutes}分钟{seconds}秒",
@@ -610,6 +608,7 @@
610
608
  "chatMessageCopy": "复制",
611
609
  "chatMessageCopied": "已复制",
612
610
  "chatMermaidDiagram": "图表",
611
+ "chatMarkdownFrontmatter": "文档属性",
613
612
  "chatMermaidExpand": "放大图表",
614
613
  "chatMermaidLoading": "正在渲染图表…",
615
614
  "chatMermaidRenderError": "图表无法渲染,已显示源代码",