@nextclaw/ui 0.15.0 → 0.15.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.
Files changed (191) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/assets/{api-DLtsiBKm.js → api-B7Qigvtm.js} +2 -2
  3. package/dist/assets/{appearance-settings-page-CtkeYXux.js → appearance-settings-page-CuE0Iiqj.js} +1 -1
  4. package/dist/assets/{book-open-BQwWBDKb.js → book-open-Ba2f7YiG.js} +1 -1
  5. package/dist/assets/channels-list-page-CTsM6TcP.js +8 -0
  6. package/dist/assets/chat-page-C_5dcuE3.js +1 -0
  7. package/dist/assets/config-split-page-Fbb4PtTf.js +1 -0
  8. package/dist/assets/{confirm-dialog-iIJFFp2T.js → confirm-dialog-D2EG3nqE.js} +1 -1
  9. package/dist/assets/desktop-update-config-BGR3HUi1.js +1 -0
  10. package/dist/assets/{dist-D2eZC3OR.js → dist-7JTjycxE.js} +1 -1
  11. package/dist/assets/{dist-CBxWOazz.js → dist-wXLhk4hl.js} +1 -1
  12. package/dist/assets/doc-browser-bHyXnxlj.js +1 -0
  13. package/dist/assets/doc-browser-context-CYAGm5d5.js +1 -0
  14. package/dist/assets/doc-browser-gTrQ3jCF.js +1 -0
  15. package/dist/assets/{es2015-DhQo_oS6.js → es2015-j1SRCIX5.js} +1 -1
  16. package/dist/assets/{external-link-CM5dnUI6.js → external-link-DxuPaDoK.js} +1 -1
  17. package/dist/assets/form-actions-BztL7P_T.js +1 -0
  18. package/dist/assets/{i18n-provider-di1waTGX.js → i18n-provider-B4oMxOFx.js} +1 -1
  19. package/dist/assets/index-CvrvblgX.css +1 -0
  20. package/dist/assets/index-Obd4JYU2.js +104 -0
  21. package/dist/assets/loader-circle-CdzgK4eH.js +1 -0
  22. package/dist/assets/{mcp-marketplace-page-C_MVQUbT.js → mcp-marketplace-page-Bt7CuOoq.js} +2 -2
  23. package/dist/assets/mcp-marketplace-page-Ck3t78_n.js +1 -0
  24. package/dist/assets/model-config-page-DeKk9gvE.js +1 -0
  25. package/dist/assets/plus-Bx7wQbhG.js +1 -0
  26. package/dist/assets/{provider-scoped-model-input-g1WkGiJ8.js → provider-scoped-model-input-DsH2LF1q.js} +1 -1
  27. package/dist/assets/providers-config-page-BFnGp68F.js +1 -0
  28. package/dist/assets/{react-DjpzoZXB.js → react-UirzUuST.js} +1 -1
  29. package/dist/assets/{refresh-cw-DaTv3zxE.js → refresh-cw-eT8BF-8B.js} +1 -1
  30. package/dist/assets/remote-CDkHZtA8.js +1 -0
  31. package/dist/assets/rotate-cw-1JqxHTuw.js +1 -0
  32. package/dist/assets/runtime-config-page-BelAqiNG.js +1 -0
  33. package/dist/assets/{save-BZof1uie.js → save-Cb2g0BOi.js} +1 -1
  34. package/dist/assets/{search-MxAarS_g.js → search-BcHjwdsb.js} +1 -1
  35. package/dist/assets/search-config-page-zPm6--Ig.js +1 -0
  36. package/dist/assets/secrets-config-page-Cxyp-KuQ.js +3 -0
  37. package/dist/assets/security-config-B_gCq9fn.js +1 -0
  38. package/dist/assets/{select-D7GcNP0z.js → select-CdSEOwVM.js} +1 -1
  39. package/dist/assets/{setting-row-CuozlnJd.js → setting-row-CTAtGexr.js} +1 -1
  40. package/dist/assets/settings-2-2DWauOjY.js +1 -0
  41. package/dist/assets/{side-dock-BcLau5S_.js → side-dock-DPvakJ0a.js} +2 -2
  42. package/dist/assets/{skeleton-shfmXuYp.js → skeleton-P5oM14E1.js} +1 -1
  43. package/dist/assets/{switch-C1BWMU5c.js → switch-BU_UEULb.js} +1 -1
  44. package/dist/assets/{tag-chip-DCUrQUCP.js → tag-chip-D-WsKoT1.js} +1 -1
  45. package/dist/assets/{tooltip-DfAHHA76.js → tooltip-CjkOaHW7.js} +1 -1
  46. package/dist/assets/{use-config-DAdbT5QJ.js → use-config--hx5oxQn.js} +1 -1
  47. package/dist/assets/{use-confirm-dialog-eWcJ6V-s.js → use-confirm-dialog-CD9a_SK1.js} +1 -1
  48. package/dist/assets/x-DT5x45JU.js +1 -0
  49. package/dist/index.html +38 -30
  50. package/index.html +12 -4
  51. package/package.json +9 -9
  52. package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +29 -1
  53. package/src/app/components/layout/sidebar-items.tsx +43 -4
  54. package/src/app/components/layout/sidebar.tsx +83 -61
  55. package/src/app/configs/app-navigation.config.ts +49 -0
  56. package/src/app/styles/design-system.css +82 -0
  57. package/src/features/agents/components/__tests__/agents-page.test.tsx +135 -2
  58. package/src/features/agents/components/agent-advanced-config-fields.tsx +70 -0
  59. package/src/features/agents/components/agent-details-dialog.tsx +398 -0
  60. package/src/features/agents/components/agent-dialogs.tsx +20 -47
  61. package/src/features/agents/components/agents-page.tsx +76 -10
  62. package/src/features/agents/types/agent-form.types.ts +21 -0
  63. package/src/features/agents/utils/agent-form.utils.ts +39 -0
  64. package/src/features/channels/components/config/channel-form.tsx +14 -11
  65. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +172 -1
  66. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +11 -1
  67. package/src/features/chat/components/conversation/chat-conversation-header.tsx +7 -3
  68. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +1 -1
  69. package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +48 -0
  70. package/src/features/chat/components/layout/__tests__/chat-sidebar-utility-menu.test.tsx +55 -0
  71. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +0 -3
  72. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +3 -4
  73. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +29 -30
  74. package/src/features/chat/components/layout/chat-sidebar.tsx +21 -7
  75. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +18 -3
  76. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +2 -1
  77. package/src/features/chat/features/message/components/__tests__/chat-inline-panel-app-card.test.tsx +22 -1
  78. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +1 -1
  79. package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +10 -5
  80. package/src/features/chat/features/message/utils/chat-inline-panel-app-card.utils.ts +0 -11
  81. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-agent-runtime.test.tsx +23 -1
  82. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-session-list-view.test.tsx +74 -0
  83. package/src/features/chat/features/ncp/hooks/use-ncp-session-list-view.ts +3 -2
  84. package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +116 -0
  85. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +108 -46
  86. package/src/features/chat/features/session/components/chat-sidebar-session-entry.tsx +6 -0
  87. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +48 -24
  88. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +0 -3
  89. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +0 -4
  90. package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +294 -0
  91. package/src/features/chat/features/session/utils/__tests__/chat-session-display.utils.test.ts +15 -1
  92. package/src/features/chat/features/session/utils/__tests__/ncp-session-adapter.utils.test.ts +24 -4
  93. package/src/features/chat/features/session/utils/chat-session-display.utils.ts +3 -0
  94. package/src/features/chat/features/session/utils/chat-sidebar-session-groups.utils.ts +25 -3
  95. package/src/features/chat/features/session/utils/ncp-session-adapter.utils.ts +1 -0
  96. package/src/features/chat/features/welcome/components/chat-welcome-capability-grid.tsx +9 -4
  97. package/src/features/chat/features/welcome/components/chat-welcome.tsx +0 -5
  98. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +193 -56
  99. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +1 -0
  100. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +144 -0
  101. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +99 -0
  102. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -1
  103. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +67 -14
  104. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +3 -0
  105. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +44 -1
  106. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +45 -3
  107. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +46 -0
  108. package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +33 -2
  109. package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +47 -0
  110. package/src/features/chat/managers/chat-session-list.manager.ts +32 -0
  111. package/src/features/chat/managers/chat-thread.manager.ts +8 -2
  112. package/src/features/chat/stores/chat-session-list.store.ts +28 -5
  113. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +5 -12
  114. package/src/features/panel-apps/components/panel-app-list-item.tsx +6 -6
  115. package/src/features/panel-apps/index.ts +1 -0
  116. package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +2 -10
  117. package/src/features/panel-apps/utils/panel-app-iframe.utils.ts +6 -0
  118. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +11 -3
  119. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +3 -1
  120. package/src/features/service-apps/components/service-apps-panel.tsx +145 -35
  121. package/src/features/settings/components/config/provider-auth-section.tsx +1 -1
  122. package/src/features/settings/components/config/provider-form.tsx +11 -8
  123. package/src/features/settings/components/config/provider-models-section.tsx +7 -7
  124. package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
  125. package/src/features/settings/components/config/secrets-config-form.tsx +5 -4
  126. package/src/features/settings/pages/model-config-page.tsx +26 -25
  127. package/src/features/settings/pages/providers-config-page.tsx +10 -13
  128. package/src/features/settings/pages/search-config-page.tsx +8 -5
  129. package/src/features/system-status/components/__tests__/desktop-update-config.test.tsx +97 -5
  130. package/src/features/system-status/components/config/runtime-config-editor.tsx +5 -4
  131. package/src/features/system-status/components/desktop-update-config.tsx +91 -2
  132. package/src/features/system-status/utils/update-release-notes.utils.ts +94 -0
  133. package/src/index.css +18 -0
  134. package/src/shared/components/config-split-page.tsx +6 -6
  135. package/src/shared/components/doc-browser/__tests__/doc-browser-url.utils.test.ts +73 -0
  136. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +48 -0
  137. package/src/shared/components/doc-browser/doc-browser-context.tsx +4 -0
  138. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +5 -1
  139. package/src/shared/components/doc-browser/doc-browser-renderer.types.ts +2 -1
  140. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +10 -10
  141. package/src/shared/components/doc-browser/doc-browser.tsx +6 -4
  142. package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +62 -4
  143. package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +18 -0
  144. package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +28 -3
  145. package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +36 -0
  146. package/src/shared/components/ui/actions/form-actions.tsx +25 -0
  147. package/src/shared/components/ui/actions/icon-action-button.tsx +25 -2
  148. package/src/shared/components/ui/card.tsx +12 -4
  149. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -1
  150. package/src/shared/hooks/use-server-path-browse.ts +26 -4
  151. package/src/shared/hooks/use-server-path-read.ts +11 -1
  152. package/src/shared/lib/api/ncp-session.types.ts +1 -1
  153. package/src/shared/lib/api/types.ts +12 -3
  154. package/src/shared/lib/api/utils/server-path.utils.ts +1 -0
  155. package/src/shared/lib/i18n/locales/en-US/agents.json +41 -0
  156. package/src/shared/lib/i18n/locales/en-US/chat.json +19 -0
  157. package/src/shared/lib/i18n/locales/en-US/core.json +3 -0
  158. package/src/shared/lib/i18n/locales/en-US/desktop-update.json +8 -0
  159. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +5 -0
  160. package/src/shared/lib/i18n/locales/zh-CN/agents.json +41 -0
  161. package/src/shared/lib/i18n/locales/zh-CN/chat.json +19 -0
  162. package/src/shared/lib/i18n/locales/zh-CN/core.json +3 -0
  163. package/src/shared/lib/i18n/locales/zh-CN/desktop-update.json +8 -0
  164. package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +5 -0
  165. package/src/shared/lib/session-project/workspace-file-breadcrumb.utils.ts +9 -5
  166. package/src/shared/lib/theme/index.test.ts +21 -0
  167. package/src/shared/lib/theme/index.ts +6 -4
  168. package/src/vite-env.d.ts +2 -0
  169. package/dist/assets/channels-list-page-Cv8o9Hxg.js +0 -8
  170. package/dist/assets/chat-page-BtA7H1Ea.js +0 -1
  171. package/dist/assets/config-split-page-EidRBpP2.js +0 -1
  172. package/dist/assets/desktop-update-config-C6n_TB1r.js +0 -1
  173. package/dist/assets/doc-browser-B76XOXmW.js +0 -1
  174. package/dist/assets/doc-browser-DBnj9UMB.js +0 -1
  175. package/dist/assets/doc-browser-context-Sv-044Cl.js +0 -1
  176. package/dist/assets/ellipsis-2uzhypw5.js +0 -1
  177. package/dist/assets/index-CBRP-7-a.css +0 -1
  178. package/dist/assets/index-Z1fYpbNd.js +0 -104
  179. package/dist/assets/loader-circle-BjmN5DeJ.js +0 -1
  180. package/dist/assets/mcp-marketplace-page-CoZIiD6G.js +0 -1
  181. package/dist/assets/model-config-page-Cdr9P6TQ.js +0 -1
  182. package/dist/assets/plus-3ztRZD_l.js +0 -1
  183. package/dist/assets/providers-config-page-CWlO7J4A.js +0 -1
  184. package/dist/assets/remote-CKWZfVVB.js +0 -1
  185. package/dist/assets/rotate-cw-CHcaRUDz.js +0 -1
  186. package/dist/assets/runtime-config-page-CfTqh1nv.js +0 -1
  187. package/dist/assets/search-config-page-Dm8daYny.js +0 -1
  188. package/dist/assets/secrets-config-page-D8AbcR05.js +0 -3
  189. package/dist/assets/security-config-Ds0LsJmo.js +0 -1
  190. package/dist/assets/x-DqL1mYLC.js +0 -1
  191. /package/dist/assets/{config-hints-fGnUjDe9.js → config-hints-C_iP1zl_.js} +0 -0
@@ -7,16 +7,35 @@ import {
7
7
  } from '@/shared/components/ui/tooltip';
8
8
  import { cn } from '@/shared/lib/utils';
9
9
 
10
+ type IconActionButtonSize = 'sm' | 'md' | 'lg';
11
+ type IconActionButtonTone = 'default' | 'strong';
12
+
10
13
  type IconActionButtonProps = Omit<
11
14
  React.ButtonHTMLAttributes<HTMLButtonElement>,
12
15
  'children' | 'type'
13
16
  > & {
14
17
  icon: React.ReactNode;
15
18
  label: string;
19
+ size?: IconActionButtonSize;
20
+ /** default: soft accent hover. strong: denser gray hover for nested hover surfaces. */
21
+ tone?: IconActionButtonTone;
16
22
  tooltip?: string | false | null;
17
23
  tooltipSide?: 'top' | 'right' | 'bottom' | 'left';
18
24
  };
19
25
 
26
+ const SIZE_CLASS: Record<IconActionButtonSize, string> = {
27
+ sm: 'h-6 w-6 rounded-md p-1',
28
+ md: 'h-7 w-7 rounded-md p-1.5',
29
+ lg: 'h-8 w-8 rounded-lg p-1.5',
30
+ };
31
+
32
+ const TONE_CLASS: Record<IconActionButtonTone, string> = {
33
+ default:
34
+ 'text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground/45 disabled:hover:bg-transparent disabled:hover:text-muted-foreground/45',
35
+ strong:
36
+ 'text-muted-foreground hover:bg-black/10 hover:text-foreground disabled:text-muted-foreground/45 disabled:hover:bg-transparent disabled:hover:text-muted-foreground/45',
37
+ };
38
+
20
39
  const IconActionButton = React.forwardRef<HTMLButtonElement, IconActionButtonProps>(
21
40
  (
22
41
  {
@@ -24,6 +43,8 @@ const IconActionButton = React.forwardRef<HTMLButtonElement, IconActionButtonPro
24
43
  disabled = false,
25
44
  icon,
26
45
  label,
46
+ size = 'md',
47
+ tone = 'default',
27
48
  tooltip,
28
49
  tooltipSide = 'bottom',
29
50
  ...buttonProps
@@ -38,8 +59,9 @@ const IconActionButton = React.forwardRef<HTMLButtonElement, IconActionButtonPro
38
59
  disabled={disabled}
39
60
  aria-label={label}
40
61
  className={cn(
41
- 'inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 disabled:cursor-not-allowed',
42
- 'text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground/45 disabled:hover:bg-transparent disabled:hover:text-muted-foreground/45',
62
+ 'inline-flex shrink-0 items-center justify-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 disabled:cursor-not-allowed',
63
+ SIZE_CLASS[size],
64
+ TONE_CLASS[tone],
43
65
  className
44
66
  )}
45
67
  >
@@ -63,3 +85,4 @@ const IconActionButton = React.forwardRef<HTMLButtonElement, IconActionButtonPro
63
85
  IconActionButton.displayName = 'IconActionButton';
64
86
 
65
87
  export { IconActionButton };
88
+ export type { IconActionButtonProps, IconActionButtonSize, IconActionButtonTone };
@@ -3,13 +3,21 @@ import { cn } from '@/shared/lib/utils';
3
3
 
4
4
  const Card = React.forwardRef<
5
5
  HTMLDivElement,
6
- React.HTMLAttributes<HTMLDivElement> & { hover?: boolean }
7
- >(({ className, hover = true, ...props }, ref) => (
6
+ React.HTMLAttributes<HTMLDivElement> & {
7
+ hover?: boolean;
8
+ /** Flat settings-style surface: light border, no shadow. */
9
+ surface?: 'raised' | 'flat';
10
+ }
11
+ >(({ className, hover = true, surface = 'raised', ...props }, ref) => (
8
12
  <div
9
13
  ref={ref}
10
14
  className={cn(
11
- 'rounded-2xl border border-border bg-card text-card-foreground shadow-card transition-all duration-base',
12
- hover && 'hover:border-primary/25 hover:shadow-card-hover',
15
+ 'rounded-2xl border bg-card text-card-foreground transition-colors duration-base',
16
+ surface === 'raised'
17
+ ? 'border-border shadow-card'
18
+ : 'border-border/75 shadow-none',
19
+ hover && surface === 'raised' && 'hover:border-primary/25 hover:shadow-card-hover',
20
+ hover && surface === 'flat' && 'hover:bg-muted/40',
13
21
  className
14
22
  )}
15
23
  {...props}
@@ -147,11 +147,12 @@ function CompactTabItem({
147
147
  <CompactTabLabelButton tab={tab} labelClassName={labelClassName} />
148
148
  {tab.onClose && tab.closePlacement !== "leading-hover" ? (
149
149
  <IconActionButton
150
+ size="sm"
151
+ tone="strong"
150
152
  icon={<X className="h-3 w-3" />}
151
153
  label={tab.closeLabel ?? ""}
152
154
  tooltip={tab.closeLabel ?? null}
153
155
  onClick={(event) => closeCompactTab(event, tab.onClose!)}
154
- className="h-5 w-5 rounded p-0.5 hover:bg-black/10"
155
156
  />
156
157
  ) : null}
157
158
  </div>
@@ -1,19 +1,41 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import { fetchServerPathBrowse } from '@/shared/lib/api';
3
3
 
4
+ export function buildServerPathBrowseQueryKey(params: {
5
+ path?: string | null;
6
+ basePath?: string | null;
7
+ includeFiles?: boolean;
8
+ }) {
9
+ return [
10
+ 'server-path-browse',
11
+ params.path?.trim() ?? '',
12
+ params.basePath?.trim() ?? '',
13
+ params.includeFiles ?? false,
14
+ ] as const;
15
+ }
16
+
4
17
  export function useServerPathBrowse(params: {
5
18
  path?: string | null;
19
+ basePath?: string | null;
6
20
  includeFiles?: boolean;
7
21
  enabled?: boolean;
8
22
  }) {
23
+ const { basePath, enabled, includeFiles, path } = params;
24
+ const normalizedPath = path?.trim() ?? '';
25
+ const normalizedBasePath = basePath?.trim() ?? '';
9
26
  return useQuery({
10
- queryKey: ['server-path-browse', params.path ?? null, params.includeFiles ?? false],
27
+ queryKey: buildServerPathBrowseQueryKey({
28
+ path: normalizedPath,
29
+ basePath: normalizedBasePath,
30
+ includeFiles,
31
+ }),
11
32
  queryFn: () =>
12
33
  fetchServerPathBrowse({
13
- path: params.path,
14
- includeFiles: params.includeFiles,
34
+ path: normalizedPath,
35
+ basePath: normalizedBasePath,
36
+ includeFiles,
15
37
  }),
16
- enabled: params.enabled ?? true,
38
+ enabled: enabled ?? true,
17
39
  staleTime: 0,
18
40
  });
19
41
  }
@@ -1,6 +1,13 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import { fetchServerPathRead } from '@/shared/lib/api';
3
3
 
4
+ export function buildServerPathReadQueryKey(params: {
5
+ path?: string | null;
6
+ basePath?: string | null;
7
+ }) {
8
+ return ['server-path-read', params.path?.trim() ?? '', params.basePath ?? null] as const;
9
+ }
10
+
4
11
  export function useServerPathRead(params: {
5
12
  path?: string | null;
6
13
  basePath?: string | null;
@@ -8,7 +15,10 @@ export function useServerPathRead(params: {
8
15
  }) {
9
16
  const normalizedPath = params.path?.trim() ?? '';
10
17
  return useQuery({
11
- queryKey: ['server-path-read', normalizedPath, params.basePath ?? null],
18
+ queryKey: buildServerPathReadQueryKey({
19
+ path: normalizedPath,
20
+ basePath: params.basePath,
21
+ }),
12
22
  queryFn: () =>
13
23
  fetchServerPathRead({
14
24
  path: normalizedPath,
@@ -32,7 +32,7 @@ export type SessionContextWindowView = {
32
32
  };
33
33
 
34
34
  export type SessionActivityPreviewView = {
35
- state: "running" | "completed" | "failed" | "idle";
35
+ state: "running" | "completed" | "failed" | "cancelled" | "idle";
36
36
  timestamp: string;
37
37
  statusText?: string;
38
38
  replyText?: string;
@@ -56,6 +56,9 @@ export type BootstrapStatusView = {
56
56
  };
57
57
 
58
58
  export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "adaptive" | "xhigh";
59
+ export type AgentModelsView = Record<string, {
60
+ params: Record<string, unknown>;
61
+ } & Record<string, unknown>>;
59
62
 
60
63
  export type ProviderInstanceView = {
61
64
  providerId: string;
@@ -253,11 +256,13 @@ export type AgentProfileView = {
253
256
  workspace?: string;
254
257
  model?: string;
255
258
  runtime?: string;
256
- runtimeConfig?: Record<string, unknown>;
259
+ runtimeConfig?: Record<string, unknown> | null;
257
260
  engine?: string;
258
261
  engineConfig?: Record<string, unknown>;
259
262
  thinkingDefault?: ThinkingLevel;
263
+ models?: AgentModelsView;
260
264
  contextTokens?: number;
265
+ reservedContextTokens?: number;
261
266
  maxToolIterations?: number;
262
267
  builtIn?: boolean;
263
268
  };
@@ -270,7 +275,8 @@ export type AgentCreateRequest = {
270
275
  home?: string;
271
276
  model?: string;
272
277
  runtime?: string;
273
- runtimeConfig?: Record<string, unknown>;
278
+ runtimeConfig?: Record<string, unknown> | null;
279
+ contextTokens?: number | null;
274
280
  };
275
281
 
276
282
  export type AgentUpdateRequest = {
@@ -279,7 +285,8 @@ export type AgentUpdateRequest = {
279
285
  avatar?: string;
280
286
  model?: string;
281
287
  runtime?: string;
282
- runtimeConfig?: Record<string, unknown>;
288
+ runtimeConfig?: Record<string, unknown> | null;
289
+ contextTokens?: number | null;
283
290
  };
284
291
 
285
292
  export type AgentDeleteResult = {
@@ -523,7 +530,9 @@ export type ConfigView = {
523
530
  engine?: string;
524
531
  engineConfig?: Record<string, unknown>;
525
532
  thinkingDefault?: ThinkingLevel;
533
+ models?: AgentModelsView;
526
534
  contextTokens?: number;
535
+ reservedContextTokens?: number;
527
536
  maxToolIterations?: number;
528
537
  };
529
538
  runtimes?: {
@@ -17,6 +17,7 @@ function encodeServerPathSegments(path: string): string {
17
17
 
18
18
  export async function fetchServerPathBrowse(params?: {
19
19
  path?: string | null;
20
+ basePath?: string | null;
20
21
  includeFiles?: boolean;
21
22
  }): Promise<ServerPathBrowseView> {
22
23
  return await nextclawClient.serverPaths.browse(params);
@@ -19,12 +19,52 @@
19
19
  "agentsRuntimeSelectPlaceholder": "Select runtime",
20
20
  "agentsRuntimeUnavailableHelp": "This runtime is no longer available in the current list. Switch to an installed and available runtime.",
21
21
  "agentsCreateAction": "Create Agent",
22
+ "agentsViewDetailsAction": "View details",
22
23
  "agentsEditAction": "Edit",
23
24
  "agentsEditDialogTitle": "Edit agent identity",
24
25
  "agentsEditDialogDescription": "Update the name, role description, and avatar. The agent ID and home directory stay stable to protect existing memory, skills, and sessions.",
25
26
  "agentsEditHomeReadonly": "Home directory stays unchanged",
26
27
  "agentsEditHomeReadonlyHint": "Use a dedicated config migration flow to move the home directory and avoid losing agent context unexpectedly.",
27
28
  "agentsEditSaveAction": "Save edits",
29
+ "agentsAdvancedConfigToggle": "Advanced configuration",
30
+ "agentsAdvancedConfigDescription": "Leave a field empty to inherit the default configuration; filled values become overrides for this agent.",
31
+ "agentsAdvancedInheritOption": "Inherit default",
32
+ "agentsAdvancedInheritPlaceholder": "Empty inherits default",
33
+ "agentsAdvancedContextTokensLabel": "Context window size",
34
+ "agentsAdvancedReservedContextTokensLabel": "Reserved context size",
35
+ "agentsAdvancedMaxToolIterationsLabel": "Max tool iterations",
36
+ "agentsAdvancedThinkingDefaultLabel": "Default thinking level",
37
+ "agentsAdvancedRuntimeConfigLabel": "Runtime config JSON",
38
+ "agentsAdvancedModelsLabel": "Model overrides JSON",
39
+ "agentsAdvancedJsonPlaceholder": "Leave empty to inherit defaults; enter a JSON object when filled",
40
+ "agentsAdvancedInvalidNumberError": "Advanced numeric fields must contain a valid number",
41
+ "agentsAdvancedInvalidJsonError": "Advanced JSON parsing failed",
42
+ "agentsAdvancedJsonObjectError": "Advanced JSON must be an object",
43
+ "agentsAdvancedParseFailed": "Failed to parse advanced configuration",
44
+ "agentsDetailsDialogTitle": "Agent details",
45
+ "agentsDetailsDialogDescription": "View this agent's visible identity, runtime, and context configuration.",
46
+ "agentsDetailsEditAction": "Edit",
47
+ "agentsDetailsIdentitySection": "Identity",
48
+ "agentsDetailsRuntimeSection": "Runtime",
49
+ "agentsDetailsContextSection": "Context",
50
+ "agentsDetailsBehaviorSection": "Behavior",
51
+ "agentsDetailsFieldId": "Agent ID",
52
+ "agentsDetailsFieldDisplayName": "Display name",
53
+ "agentsDetailsFieldDescription": "Role description",
54
+ "agentsDetailsFieldWorkspace": "Home directory",
55
+ "agentsDetailsFieldAvatar": "Avatar",
56
+ "agentsDetailsFieldModel": "Model",
57
+ "agentsDetailsFieldRuntime": "Runtime",
58
+ "agentsDetailsFieldRuntimeConfig": "Runtime config",
59
+ "agentsDetailsFieldContextTokens": "Context window size",
60
+ "agentsDetailsFieldReservedContextTokens": "Reserved context size",
61
+ "agentsDetailsFieldMaxToolIterations": "Max tool iterations",
62
+ "agentsDetailsFieldThinkingDefault": "Default thinking level",
63
+ "agentsDetailsFieldModelOverrides": "Model overrides",
64
+ "agentsDetailsInheritedDefault": "Inherited default",
65
+ "agentsDetailsAgentOverride": "Agent override",
66
+ "agentsDetailsEmptyValue": "No description",
67
+ "agentsDetailsUnsetValue": "Not set",
28
68
  "agentsRemoveAction": "Remove",
29
69
  "agentsNewChat": "New Chat",
30
70
  "agentsLoading": "Loading agents...",
@@ -38,6 +78,7 @@
38
78
  "agentsCardBuiltInSummary": "The built-in main agent, ideal as the default entry and coordinating collaborator.",
39
79
  "agentsCardCustomSummary": "A dedicated identity with its own memory, skills, and role style.",
40
80
  "agentsCardRuntimeLabel": "Runtime",
81
+ "agentsCardContextTokensLabel": "Context",
41
82
  "agentsCardHomeLabel": "Home Directory",
42
83
  "agentsCardAvatarLabel": "Avatar",
43
84
  "agentsCardStartChat": "Start Chat",
@@ -29,6 +29,9 @@
29
29
  "chatProviderSetupTitle": "Configure a Provider First",
30
30
  "chatProviderSetupDescription": "No models are available yet. Configure and save at least one provider, then return to start chatting.",
31
31
  "chatSessionLabel": "Current Session",
32
+ "chatSessionSwitch": "Switch session",
33
+ "chatSessionSwitcherTitle": "Recent sessions",
34
+ "chatSessionSwitcherNoResults": "No matching sessions",
32
35
  "chatNoSession": "No session selected",
33
36
  "chatHistoryLoading": "Loading session history...",
34
37
  "chatBackToParent": "Back to parent",
@@ -38,6 +41,9 @@
38
41
  "chatChildSessionEmpty": "No child session messages yet.",
39
42
  "chatWorkspaceBack": "Back in workspace",
40
43
  "chatWorkspaceForward": "Forward in workspace",
44
+ "chatWorkspaceRefreshFile": "Refresh preview",
45
+ "chatWorkspaceMaximizePanel": "Maximize workspace panel",
46
+ "chatWorkspaceRestorePanel": "Restore workspace panel",
41
47
  "chatWorkspaceClosePanel": "Close workspace panel",
42
48
  "chatWorkspaceSideChatDraftTitle": "Side chat",
43
49
  "chatWorkspaceSideChatDraftSubtitle": "This draft will inherit the parent session context when you send the first message.",
@@ -46,7 +52,13 @@
46
52
  "chatWorkspacePreview": "Preview",
47
53
  "chatWorkspaceDiff": "Diff",
48
54
  "chatWorkspaceCloseFile": "Close file",
55
+ "chatWorkspaceLoadingPreview": "Loading preview…",
49
56
  "chatWorkspaceLoadingFile": "Loading file…",
57
+ "chatWorkspaceLoadingDirectory": "Loading directory…",
58
+ "chatWorkspaceOpenDirectory": "Open directory",
59
+ "chatWorkspaceOpenFile": "Open file",
60
+ "chatWorkspaceDirectoryEmpty": "This directory is empty.",
61
+ "chatWorkspaceDirectoryLoadFailed": "Failed to load directory",
50
62
  "chatWorkspacePreviewUnsupported": "This file is not supported in the sidebar preview yet.",
51
63
  "chatWorkspacePreviewEmpty": "No file content is available for preview.",
52
64
  "chatWorkspaceDiffEmpty": "No diff content is available.",
@@ -196,6 +208,13 @@
196
208
  "chatSidebarYesterday": "Yesterday",
197
209
  "chatSidebarPrevious7Days": "Previous 7 Days",
198
210
  "chatSidebarOlder": "Older",
211
+ "chatSidebarPinned": "Pinned",
212
+ "chatSidebarPinSession": "Pin session",
213
+ "chatSidebarUnpinSession": "Unpin session",
214
+ "chatSidebarPinProject": "Pin project",
215
+ "chatSidebarUnpinProject": "Unpin project",
216
+ "chatSidebarExpandProject": "Expand project",
217
+ "chatSidebarCollapseProject": "Collapse project",
199
218
  "chatSidebarProjectViewEmpty": "No project conversations yet",
200
219
  "chatWelcomeTitle": "Hello, how can I help you?",
201
220
  "chatWelcomeSubtitle": "Describe the goal, choose the project context, and let NextClaw take it from there.",
@@ -11,6 +11,8 @@
11
11
  "marketplace": "Marketplace",
12
12
  "advanced": "Advanced",
13
13
  "settings": "Settings",
14
+ "settingsGroupBasic": "Basic Configuration",
15
+ "settingsGroupAdvanced": "Advanced Configuration",
14
16
  "appearance": "Appearance",
15
17
  "settingsMenu": "Settings menu",
16
18
  "sidebarCollapse": "Collapse sidebar",
@@ -41,6 +43,7 @@
41
43
  "language": "Language",
42
44
  "theme": "Theme",
43
45
  "themeNatural": "Natural",
46
+ "themeWork": "Default",
44
47
  "themeMinimal": "Minimal",
45
48
  "themeWarm": "Paper",
46
49
  "themeCool": "Mist",
@@ -75,6 +75,14 @@
75
75
  "desktopUpdatesDownloadNow": "Download Update",
76
76
  "desktopUpdatesApplyNow": "Restart to Update",
77
77
  "desktopUpdatesReleaseNotes": "Release Notes",
78
+ "desktopUpdatesReleaseNotesPreviewTitle": "What's New",
79
+ "desktopUpdatesReleaseNotesPreviewDescription": "Review the main changes in this version before updating.",
80
+ "desktopUpdatesReleaseNotesPreviewLoading": "Loading release notes...",
81
+ "desktopUpdatesReleaseNotesPreviewUnavailable": "Structured release notes could not be loaded in the app. Open the full notes instead.",
82
+ "desktopUpdatesReleaseNotesFeature": "Features",
83
+ "desktopUpdatesReleaseNotesEnhancement": "Enhancements",
84
+ "desktopUpdatesReleaseNotesFix": "Fixes",
85
+ "desktopUpdatesReleaseNotesCompatibility": "Defaults and Compatibility",
78
86
  "desktopUpdatesLoadFailed": "Failed to load update state",
79
87
  "desktopUpdatesCheckFailed": "Failed to check for updates",
80
88
  "desktopUpdatesDownloadFailed": "Failed to download update",
@@ -65,6 +65,8 @@
65
65
  "serviceAppsLoading": "Loading service apps...",
66
66
  "serviceAppsLoadFailed": "Failed to load service apps",
67
67
  "serviceAppsEmpty": "No service apps yet",
68
+ "serviceAppsEmptyTitle": "No service apps",
69
+ "serviceAppsEmptyDescription": "Service apps expose local runtimes and actions that panel apps can call.",
68
70
  "serviceAppsRefresh": "Refresh service apps",
69
71
  "serviceAppsDiscoverActions": "Connect and discover actions",
70
72
  "serviceAppsDiscoverActionsHint": "Connect to the service app runtime and discover its available actions.",
@@ -84,6 +86,9 @@
84
86
  "serviceAppsStatusHint_running": "The service app runtime is connected and ready for action discovery or invocation.",
85
87
  "serviceAppsStatusHint_failed": "The runtime connection failed; check the error or disconnect and try again.",
86
88
  "serviceAppsStatusHint_stopped": "The service app is stopped.",
89
+ "serviceAppsActionsSection": "Actions",
90
+ "serviceAppsActionsEmpty": "No actions discovered yet",
91
+ "serviceAppsDetails": "Runtime details",
87
92
  "serviceAppsGrantedTo": "Granted to",
88
93
  "serviceAppsRevokeGrant": "Revoke grant",
89
94
  "serviceAppsRuntimeState_matched": "Matched",
@@ -19,12 +19,52 @@
19
19
  "agentsRuntimeSelectPlaceholder": "选择 Runtime",
20
20
  "agentsRuntimeUnavailableHelp": "当前 Runtime 已不在可用列表中;建议改选一个已安装且可用的 Runtime。",
21
21
  "agentsCreateAction": "创建 Agent",
22
+ "agentsViewDetailsAction": "查看详情",
22
23
  "agentsEditAction": "编辑",
23
24
  "agentsEditDialogTitle": "编辑 Agent 身份",
24
25
  "agentsEditDialogDescription": "更新名称、角色描述与头像。Agent ID 与主目录保持稳定,避免影响既有记忆、技能与会话。",
25
26
  "agentsEditHomeReadonly": "主目录保持不变",
26
27
  "agentsEditHomeReadonlyHint": "如需迁移主目录,请走独立配置迁移流程,避免意外丢失 Agent 上下文。",
27
28
  "agentsEditSaveAction": "保存编辑",
29
+ "agentsAdvancedConfigToggle": "高级配置",
30
+ "agentsAdvancedConfigDescription": "留空会继承默认配置;填写后会成为这个 Agent 的专属覆盖。",
31
+ "agentsAdvancedInheritOption": "继承默认",
32
+ "agentsAdvancedInheritPlaceholder": "留空继承默认",
33
+ "agentsAdvancedContextTokensLabel": "上下文窗口大小",
34
+ "agentsAdvancedReservedContextTokensLabel": "预留上下文大小",
35
+ "agentsAdvancedMaxToolIterationsLabel": "最大工具迭代次数",
36
+ "agentsAdvancedThinkingDefaultLabel": "默认思考强度",
37
+ "agentsAdvancedRuntimeConfigLabel": "Runtime 配置 JSON",
38
+ "agentsAdvancedModelsLabel": "模型覆盖 JSON",
39
+ "agentsAdvancedJsonPlaceholder": "留空继承默认;填写时请输入 JSON 对象",
40
+ "agentsAdvancedInvalidNumberError": "高级配置里的数字必须是有效数字",
41
+ "agentsAdvancedInvalidJsonError": "高级配置 JSON 解析失败",
42
+ "agentsAdvancedJsonObjectError": "高级配置 JSON 必须是对象",
43
+ "agentsAdvancedParseFailed": "高级配置解析失败",
44
+ "agentsDetailsDialogTitle": "Agent 详情",
45
+ "agentsDetailsDialogDescription": "查看这个 Agent 当前可见的身份、运行时与上下文配置。",
46
+ "agentsDetailsEditAction": "编辑",
47
+ "agentsDetailsIdentitySection": "身份",
48
+ "agentsDetailsRuntimeSection": "运行",
49
+ "agentsDetailsContextSection": "上下文",
50
+ "agentsDetailsBehaviorSection": "行为",
51
+ "agentsDetailsFieldId": "Agent ID",
52
+ "agentsDetailsFieldDisplayName": "显示名称",
53
+ "agentsDetailsFieldDescription": "角色描述",
54
+ "agentsDetailsFieldWorkspace": "主目录",
55
+ "agentsDetailsFieldAvatar": "头像",
56
+ "agentsDetailsFieldModel": "模型",
57
+ "agentsDetailsFieldRuntime": "Runtime",
58
+ "agentsDetailsFieldRuntimeConfig": "Runtime 配置",
59
+ "agentsDetailsFieldContextTokens": "上下文窗口大小",
60
+ "agentsDetailsFieldReservedContextTokens": "预留上下文大小",
61
+ "agentsDetailsFieldMaxToolIterations": "最大工具迭代次数",
62
+ "agentsDetailsFieldThinkingDefault": "默认思考强度",
63
+ "agentsDetailsFieldModelOverrides": "模型覆盖",
64
+ "agentsDetailsInheritedDefault": "继承默认",
65
+ "agentsDetailsAgentOverride": "Agent 覆盖",
66
+ "agentsDetailsEmptyValue": "暂无描述",
67
+ "agentsDetailsUnsetValue": "未设置",
28
68
  "agentsRemoveAction": "移除",
29
69
  "agentsNewChat": "新建会话",
30
70
  "agentsLoading": "正在加载 Agent...",
@@ -38,6 +78,7 @@
38
78
  "agentsCardBuiltInSummary": "系统主 Agent,适合作为默认入口与总控协作者。",
39
79
  "agentsCardCustomSummary": "专属 Agent 身份,可沉淀自己的记忆、技能与角色风格。",
40
80
  "agentsCardRuntimeLabel": "Runtime",
81
+ "agentsCardContextTokensLabel": "上下文",
41
82
  "agentsCardHomeLabel": "主目录",
42
83
  "agentsCardAvatarLabel": "Avatar",
43
84
  "agentsCardStartChat": "开始对话",
@@ -29,6 +29,9 @@
29
29
  "chatProviderSetupTitle": "开始前先配置提供商",
30
30
  "chatProviderSetupDescription": "你还没有可用模型。先在提供商页面配置并保存至少一个 Provider 后,再回来开始对话。",
31
31
  "chatSessionLabel": "当前会话",
32
+ "chatSessionSwitch": "切换会话",
33
+ "chatSessionSwitcherTitle": "最近会话",
34
+ "chatSessionSwitcherNoResults": "没有匹配的会话",
32
35
  "chatNoSession": "未选择会话",
33
36
  "chatHistoryLoading": "加载会话历史中...",
34
37
  "chatBackToParent": "返回父会话",
@@ -38,6 +41,9 @@
38
41
  "chatChildSessionEmpty": "子会话还没有消息。",
39
42
  "chatWorkspaceBack": "工作区后退",
40
43
  "chatWorkspaceForward": "工作区前进",
44
+ "chatWorkspaceRefreshFile": "刷新预览",
45
+ "chatWorkspaceMaximizePanel": "最大化工作区侧栏",
46
+ "chatWorkspaceRestorePanel": "还原工作区侧栏",
41
47
  "chatWorkspaceClosePanel": "关闭工作区侧栏",
42
48
  "chatWorkspaceSideChatDraftTitle": "Side chat",
43
49
  "chatWorkspaceSideChatDraftSubtitle": "发送第一条消息后,会继承父会话上下文并创建真实 child 会话。",
@@ -46,7 +52,13 @@
46
52
  "chatWorkspacePreview": "预览",
47
53
  "chatWorkspaceDiff": "Diff",
48
54
  "chatWorkspaceCloseFile": "关闭文件",
55
+ "chatWorkspaceLoadingPreview": "正在加载预览…",
49
56
  "chatWorkspaceLoadingFile": "正在加载文件…",
57
+ "chatWorkspaceLoadingDirectory": "正在加载目录…",
58
+ "chatWorkspaceOpenDirectory": "打开目录",
59
+ "chatWorkspaceOpenFile": "打开文件",
60
+ "chatWorkspaceDirectoryEmpty": "这个目录为空。",
61
+ "chatWorkspaceDirectoryLoadFailed": "读取目录失败",
50
62
  "chatWorkspacePreviewUnsupported": "该文件暂不支持在侧栏预览。",
51
63
  "chatWorkspacePreviewEmpty": "当前没有可显示的文件内容。",
52
64
  "chatWorkspaceDiffEmpty": "当前没有可显示的 diff 内容。",
@@ -196,6 +208,13 @@
196
208
  "chatSidebarYesterday": "昨天",
197
209
  "chatSidebarPrevious7Days": "近 7 天",
198
210
  "chatSidebarOlder": "更早",
211
+ "chatSidebarPinned": "已置顶",
212
+ "chatSidebarPinSession": "置顶会话",
213
+ "chatSidebarUnpinSession": "取消置顶会话",
214
+ "chatSidebarPinProject": "置顶项目",
215
+ "chatSidebarUnpinProject": "取消置顶项目",
216
+ "chatSidebarExpandProject": "展开项目",
217
+ "chatSidebarCollapseProject": "收起项目",
199
218
  "chatSidebarProjectViewEmpty": "还没有绑定项目的会话",
200
219
  "chatWelcomeTitle": "你好,有什么可以帮你的吗?",
201
220
  "chatWelcomeSubtitle": "描述目标,选择项目上下文,让 NextClaw 接住这次任务。",
@@ -11,6 +11,8 @@
11
11
  "marketplace": "市场",
12
12
  "advanced": "高级",
13
13
  "settings": "设置",
14
+ "settingsGroupBasic": "基础配置",
15
+ "settingsGroupAdvanced": "高级配置",
14
16
  "appearance": "外观",
15
17
  "settingsMenu": "设置菜单",
16
18
  "sidebarCollapse": "收起侧边栏",
@@ -41,6 +43,7 @@
41
43
  "language": "语言",
42
44
  "theme": "主题",
43
45
  "themeNatural": "自然",
46
+ "themeWork": "默认",
44
47
  "themeMinimal": "简白",
45
48
  "themeWarm": "纸暖",
46
49
  "themeCool": "雾蓝",
@@ -75,6 +75,14 @@
75
75
  "desktopUpdatesDownloadNow": "下载更新",
76
76
  "desktopUpdatesApplyNow": "立即重启更新",
77
77
  "desktopUpdatesReleaseNotes": "查看更新说明",
78
+ "desktopUpdatesReleaseNotesPreviewTitle": "本次更新",
79
+ "desktopUpdatesReleaseNotesPreviewDescription": "更新前可以先查看这个版本的主要变化。",
80
+ "desktopUpdatesReleaseNotesPreviewLoading": "正在读取更新说明...",
81
+ "desktopUpdatesReleaseNotesPreviewUnavailable": "暂时无法在应用内读取结构化更新说明,可以打开完整说明。",
82
+ "desktopUpdatesReleaseNotesFeature": "功能",
83
+ "desktopUpdatesReleaseNotesEnhancement": "增强",
84
+ "desktopUpdatesReleaseNotesFix": "修复",
85
+ "desktopUpdatesReleaseNotesCompatibility": "默认行为与兼容性",
78
86
  "desktopUpdatesLoadFailed": "读取更新状态失败",
79
87
  "desktopUpdatesCheckFailed": "检查更新失败",
80
88
  "desktopUpdatesDownloadFailed": "下载更新失败",
@@ -65,6 +65,8 @@
65
65
  "serviceAppsLoading": "加载服务应用中...",
66
66
  "serviceAppsLoadFailed": "服务应用加载失败",
67
67
  "serviceAppsEmpty": "暂无服务应用",
68
+ "serviceAppsEmptyTitle": "暂无服务应用",
69
+ "serviceAppsEmptyDescription": "服务应用提供本地运行时与动作,供面板应用调用。",
68
70
  "serviceAppsRefresh": "刷新服务应用",
69
71
  "serviceAppsDiscoverActions": "连接并发现动作",
70
72
  "serviceAppsDiscoverActionsHint": "连接服务应用运行时,并发现它当前可用的动作。",
@@ -84,6 +86,9 @@
84
86
  "serviceAppsStatusHint_running": "服务应用运行时已连接,可用于发现或调用动作。",
85
87
  "serviceAppsStatusHint_failed": "运行时连接失败,请查看错误信息或断开连接后重试。",
86
88
  "serviceAppsStatusHint_stopped": "服务应用已停止。",
89
+ "serviceAppsActionsSection": "动作",
90
+ "serviceAppsActionsEmpty": "尚未发现动作",
91
+ "serviceAppsDetails": "运行时详情",
87
92
  "serviceAppsGrantedTo": "已授权给",
88
93
  "serviceAppsRevokeGrant": "撤销授权",
89
94
  "serviceAppsRuntimeState_matched": "已匹配",
@@ -131,12 +131,13 @@ function readRelativeSegments(params: {
131
131
  function buildSegmentsFromLabels(params: {
132
132
  labels: string[];
133
133
  basePath?: string | null;
134
+ currentKind?: "file" | "directory";
134
135
  leading?: WorkspaceFileBreadcrumbSegmentViewModel | null;
135
136
  }): WorkspaceFileBreadcrumbSegmentViewModel[] {
136
- const { basePath = null, labels, leading = null } = params;
137
+ const { basePath = null, currentKind = "file", labels, leading = null } = params;
137
138
  const items = labels.map<WorkspaceFileBreadcrumbSegmentViewModel>(
138
139
  (label, index) => {
139
- const kind = index === labels.length - 1 ? "file" : "directory";
140
+ const kind = index === labels.length - 1 ? currentKind : "directory";
140
141
  const path = joinPathSegments(basePath, labels.slice(0, index + 1));
141
142
  return {
142
143
  key: `${index}:${label}`,
@@ -167,12 +168,13 @@ function buildLocationLabel(params: {
167
168
 
168
169
  export function buildWorkspaceFileBreadcrumb(params: {
169
170
  path: string;
171
+ kind?: "file" | "directory";
170
172
  sessionProjectRoot: string | null;
171
173
  line?: number | null;
172
174
  column?: number | null;
173
175
  truncated: boolean;
174
176
  }): WorkspaceFileBreadcrumbViewModel {
175
- const { column, line, path, sessionProjectRoot, truncated } = params;
177
+ const { column, kind = "file", line, path, sessionProjectRoot, truncated } = params;
176
178
  const fullPath = path.trim();
177
179
  const relativeSegments =
178
180
  sessionProjectRoot?.trim() && fullPath
@@ -192,6 +194,7 @@ export function buildWorkspaceFileBreadcrumb(params: {
192
194
  segments = buildSegmentsFromLabels({
193
195
  labels: relativeSegments,
194
196
  basePath: workspacePath,
197
+ currentKind: kind,
195
198
  leading: {
196
199
  key: `workspace:${workspaceLabel}`,
197
200
  label: workspaceLabel,
@@ -207,6 +210,7 @@ export function buildWorkspaceFileBreadcrumb(params: {
207
210
  segments = buildSegmentsFromLabels({
208
211
  labels,
209
212
  basePath: rootPath,
213
+ currentKind: kind,
210
214
  leading: prefix
211
215
  ? {
212
216
  key: `root:${prefix}`,
@@ -225,9 +229,9 @@ export function buildWorkspaceFileBreadcrumb(params: {
225
229
  {
226
230
  key: "file:unknown",
227
231
  label: fullPath || "file",
228
- kind: "file",
232
+ kind,
229
233
  path: fullPath,
230
- browsePath: readParentPath(fullPath),
234
+ browsePath: kind === "directory" ? fullPath : readParentPath(fullPath),
231
235
  isCurrent: true,
232
236
  },
233
237
  ];