@nextclaw/ui 0.15.5 → 0.15.6

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 (147) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/assets/api-Dyb5rgh0.js +13 -0
  3. package/dist/assets/app-presenter-provider-7jV0nPiL.js +106 -0
  4. package/dist/assets/{appearance-settings-page-80fLa4-9.js → appearance-settings-page-DFm3BbEb.js} +1 -1
  5. package/dist/assets/{book-open-CN7Shpij.js → book-open-L6LCuqOr.js} +1 -1
  6. package/dist/assets/{channels-list-page-R7M6pzp6.js → channels-list-page-DOaPKNJA.js} +2 -2
  7. package/dist/assets/{chat-page-152YuwfU.js → chat-page-Cw9uDhD_.js} +1 -1
  8. package/dist/assets/{config-split-page-BlfvfmTm.js → config-split-page-CqlqjnCK.js} +1 -1
  9. package/dist/assets/{confirm-dialog-Dt8Kdbgp.js → confirm-dialog-bAp8NU93.js} +1 -1
  10. package/dist/assets/desktop-update-config-2SjMfCMl.js +1 -0
  11. package/dist/assets/{dist-D5ycbwCo.js → dist-CrtbGLlh.js} +1 -1
  12. package/dist/assets/doc-browser-A5IRyDXQ2.js +1 -0
  13. package/dist/assets/{doc-browser-C9u7N9vH.js → doc-browser-BmnQa30-.js} +1 -1
  14. package/dist/assets/{doc-browser-context-CCdW9TJf.js → doc-browser-context-BlpUUFrR.js} +1 -1
  15. package/dist/assets/{download-CyPgglKr.js → download-BhZZNXD8.js} +1 -1
  16. package/dist/assets/{external-link-BahW1sl3.js → external-link-B9Uoq5J7.js} +1 -1
  17. package/dist/assets/{eye-D8gGXMkD.js → eye-K5knauEM.js} +1 -1
  18. package/dist/assets/{folder-DGWqFDvE.js → folder-BIYZZWJv.js} +1 -1
  19. package/dist/assets/{form-actions-D2imZLnU.js → form-actions-CKprWFeM.js} +1 -1
  20. package/dist/assets/index-BVn702m4.css +1 -0
  21. package/dist/assets/{index-CT0iYlxV.js → index-CFxJ1Fkg.js} +2 -2
  22. package/dist/assets/loader-circle-Bj2RMrCR.js +1 -0
  23. package/dist/assets/{logo-badge-CuPetu-v.js → logo-badge-BQ-XFZod.js} +1 -1
  24. package/dist/assets/mcp-marketplace-page-BfA7A3n4.js +9 -0
  25. package/dist/assets/mcp-marketplace-page-CXHYO95j.js +1 -0
  26. package/dist/assets/{model-config-page-DiJcvBML.js → model-config-page-BbWbW_qM.js} +1 -1
  27. package/dist/assets/plus-TmFdwO3P.js +1 -0
  28. package/dist/assets/{popover-Btp7KVc3.js → popover-CX9zFsuc.js} +1 -1
  29. package/dist/assets/{provider-scoped-model-input-DZMtoAJG.js → provider-scoped-model-input-B-9_DtIP.js} +1 -1
  30. package/dist/assets/providers-config-page-xwIjGur2.js +1 -0
  31. package/dist/assets/{react-BY-U3h3t.js → react-DsgudwpT.js} +1 -1
  32. package/dist/assets/{refresh-cw-Cme5qFej.js → refresh-cw-kXdvbhFf.js} +1 -1
  33. package/dist/assets/remote-B9F2uCk9.js +1 -0
  34. package/dist/assets/rotate-cw-DEc6aihr.js +1 -0
  35. package/dist/assets/runtime-config-page-DTsi7czJ.js +1 -0
  36. package/dist/assets/{save-DNg2yJTS.js → save-C9qpz2_2.js} +1 -1
  37. package/dist/assets/{search-3ykfrAFt.js → search-_kEi29qo.js} +1 -1
  38. package/dist/assets/{search-config-page-DrVKa_Ls.js → search-config-page-H7ug8f4D.js} +1 -1
  39. package/dist/assets/{secrets-config-page-B39uQ5kF.js → secrets-config-page-C1_6rINu.js} +2 -2
  40. package/dist/assets/security-config-Cr2ERKLu.js +1 -0
  41. package/dist/assets/{select-B5EecXJt.js → select-MJKhKAWR.js} +1 -1
  42. package/dist/assets/{setting-row-Qv1Ps79v.js → setting-row-DA3tJuew.js} +1 -1
  43. package/dist/assets/{settings-2-D-3um9Az.js → settings-2-D_y7zXJz.js} +1 -1
  44. package/dist/assets/{skeleton-BgkzQd4U.js → skeleton-0uTLUhm9.js} +1 -1
  45. package/dist/assets/{tabs-BVD8gp3y.js → tabs-h44XPocd.js} +1 -1
  46. package/dist/assets/{tag-chip-0qn-f3Bo.js → tag-chip-bRZ04q3C.js} +1 -1
  47. package/dist/assets/{trash-2-cnsMppRC.js → trash-2-BRpSE-Wt.js} +1 -1
  48. package/dist/assets/use-config-CwDEAl6f.js +1 -0
  49. package/dist/assets/{use-confirm-dialog-C_o0eQeH.js → use-confirm-dialog-BbnWw-8c.js} +1 -1
  50. package/dist/assets/{use-viewport-layout-BWav4KCL.js → use-viewport-layout-CqgIMDQL.js} +1 -1
  51. package/dist/assets/x-DdEDL6ju.js +1 -0
  52. package/dist/index.html +29 -29
  53. package/package.json +8 -8
  54. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +84 -1
  55. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +13 -2
  56. package/src/features/chat/components/layout/__tests__/chat-sidebar-test.utils.ts +22 -0
  57. package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +13 -24
  58. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +16 -4
  59. package/src/features/chat/components/layout/chat-sidebar.tsx +38 -2
  60. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +1 -0
  61. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +52 -2
  62. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +22 -0
  63. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +8 -9
  64. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +55 -0
  65. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +12 -11
  66. package/src/features/chat/features/conversation/hooks/use-session-conversation-preference-actions.ts +94 -0
  67. package/src/features/chat/features/input/hooks/__tests__/use-chat-input-surface-state.test.tsx +37 -0
  68. package/src/features/chat/features/input/hooks/use-chat-input-surface-state.ts +140 -63
  69. package/src/features/chat/features/input/input-surface-plugins/__tests__/context-reference-plugin.test.ts +175 -0
  70. package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +23 -0
  71. package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.types.ts +8 -1
  72. package/src/features/chat/features/input/input-surface-plugins/context-reference-plugin.utils.ts +274 -0
  73. package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +4 -1
  74. package/src/features/chat/features/input/utils/__tests__/chat-composer-state.utils.test.ts +26 -0
  75. package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +50 -4
  76. package/src/features/chat/features/input/utils/chat-composer-state.utils.ts +4 -10
  77. package/src/features/chat/features/input/utils/chat-composer-token-protocol.utils.ts +29 -0
  78. package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +66 -8
  79. package/src/features/chat/features/input/utils/chat-input-bar.utils.ts +1 -0
  80. package/src/features/chat/features/ncp/hooks/__tests__/use-hydrated-ncp-agent.test.tsx +41 -3
  81. package/src/features/chat/features/project/components/__tests__/chat-project-create-dialog.test.tsx +67 -0
  82. package/src/features/chat/features/project/components/chat-project-create-dialog.tsx +203 -0
  83. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +7 -7
  84. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-project-dialog.test.tsx +47 -0
  85. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +6 -3
  86. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -0
  87. package/src/features/chat/features/session/components/session-header/chat-session-project-dialog.tsx +3 -0
  88. package/src/features/chat/features/session/components/session-header/chat-session-switcher-groups.tsx +245 -0
  89. package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +81 -127
  90. package/src/features/chat/features/session/utils/__tests__/chat-sidebar-session-groups.utils.test.ts +22 -0
  91. package/src/features/chat/features/session/utils/chat-run-metadata.utils.ts +6 -6
  92. package/src/features/chat/features/session/utils/chat-sidebar-session-groups.utils.ts +12 -1
  93. package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +3 -0
  94. package/src/features/chat/features/welcome/components/chat-welcome.tsx +1 -0
  95. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-project-options.utils.test.ts +20 -0
  96. package/src/features/chat/features/welcome/utils/chat-welcome-project-options.utils.ts +15 -2
  97. package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +23 -0
  98. package/src/features/settings/components/config/provider-form.tsx +0 -4
  99. package/src/features/settings/utils/__tests__/provider-form-support.utils.test.ts +7 -9
  100. package/src/features/settings/utils/provider-form-model.utils.ts +0 -4
  101. package/src/features/system-status/hooks/use-current-version-release-notes-link.ts +33 -0
  102. package/src/features/system-status/index.ts +9 -0
  103. package/src/features/system-status/utils/update-release-notes.utils.ts +44 -3
  104. package/src/index.css +10 -16
  105. package/src/shared/components/common/__tests__/brand-header.test.tsx +110 -3
  106. package/src/shared/components/common/brand-header.tsx +121 -35
  107. package/src/shared/components/path-picker/__tests__/server-path-picker-dialog.test.tsx +288 -38
  108. package/src/shared/components/path-picker/server-path-picker-dialog.tsx +290 -199
  109. package/src/shared/components/path-picker/server-path-picker-directory-list.tsx +103 -0
  110. package/src/shared/components/path-picker/server-path-picker-footer.tsx +58 -0
  111. package/src/shared/components/path-picker/server-path-picker-locations.tsx +148 -0
  112. package/src/shared/components/path-picker/server-path-picker-navigation-bar.tsx +198 -0
  113. package/src/shared/components/path-picker/server-path-picker-new-folder.tsx +59 -0
  114. package/src/shared/components/path-picker/server-path-picker-toolbar.tsx +25 -0
  115. package/src/shared/hooks/use-projects.ts +28 -0
  116. package/src/shared/hooks/use-server-path-create-directory.ts +6 -0
  117. package/src/shared/hooks/use-server-path-search.ts +40 -0
  118. package/src/shared/lib/api/index.ts +1 -0
  119. package/src/shared/lib/api/projects/project.utils.ts +14 -0
  120. package/src/shared/lib/api/types.ts +27 -0
  121. package/src/shared/lib/api/utils/server-path.utils.ts +21 -1
  122. package/src/shared/lib/i18n/locales/en-US/chat.json +35 -2
  123. package/src/shared/lib/i18n/locales/en-US/core.json +2 -3
  124. package/src/shared/lib/i18n/locales/en-US/desktop-update.json +4 -0
  125. package/src/shared/lib/i18n/locales/en-US/path-picker.json +25 -0
  126. package/src/shared/lib/i18n/locales/zh-CN/chat.json +35 -2
  127. package/src/shared/lib/i18n/locales/zh-CN/core.json +2 -3
  128. package/src/shared/lib/i18n/locales/zh-CN/desktop-update.json +4 -0
  129. package/src/shared/lib/i18n/locales/zh-CN/path-picker.json +25 -0
  130. package/dist/assets/api-IlX_CbwU.js +0 -13
  131. package/dist/assets/app-presenter-provider-Bbl_MVbg.js +0 -106
  132. package/dist/assets/desktop-update-config-DreMJu9z.js +0 -1
  133. package/dist/assets/doc-browser-DJQ5XPsi2.js +0 -1
  134. package/dist/assets/index-0av6WO9-.css +0 -1
  135. package/dist/assets/loader-circle-DtKek-qG.js +0 -1
  136. package/dist/assets/mcp-marketplace-page-4qMwFDpz.js +0 -1
  137. package/dist/assets/mcp-marketplace-page-BbxN5aZF.js +0 -9
  138. package/dist/assets/plus-BwgE-Zwf.js +0 -1
  139. package/dist/assets/providers-config-page-DfiWveEF.js +0 -1
  140. package/dist/assets/remote-BaVECEZw.js +0 -1
  141. package/dist/assets/rotate-cw-CMRZxIkH.js +0 -1
  142. package/dist/assets/runtime-config-page-wygwvMB4.js +0 -1
  143. package/dist/assets/security-config-BPzet76z.js +0 -1
  144. package/dist/assets/use-config-D6yx0lb0.js +0 -1
  145. package/dist/assets/x-B3o1dWR5.js +0 -1
  146. package/src/features/chat/features/input/input-surface-plugins/__tests__/panel-app-reference-plugin.test.ts +0 -77
  147. package/src/features/chat/features/input/input-surface-plugins/panel-app-reference-plugin.utils.ts +0 -144
@@ -1 +0,0 @@
1
- import{mt as e}from"./api-IlX_CbwU.js";export{e as SecurityConfig};
@@ -1 +0,0 @@
1
- import{r as e}from"./react-BY-U3h3t.js";import{$ as t,H as n,I as r,J as i,Jt as a,K as o,Kt as s,Q as c,R as l,U as u,V as d,Y as f,an as p,at as m,et as h,it as g,nt as _,q as v,qt as y,rt as b,tt as x,z as S}from"./api-IlX_CbwU.js";function C(){return a({queryKey:[`config`],queryFn:d,staleTime:3e4,refetchOnWindowFocus:!0})}function w(){return a({queryKey:[`config-meta`],queryFn:n,staleTime:1/0})}function T(){return a({queryKey:[`providers`],queryFn:v,staleTime:3e4,refetchOnWindowFocus:!0})}function E(){return a({queryKey:[`provider-templates`],queryFn:o,staleTime:1/0})}function D(){return a({queryKey:[`config-schema`],queryFn:u,staleTime:1/0})}function O(){let t=p();return y({mutationFn:x,onSuccess:()=>{t.invalidateQueries({queryKey:[`config`]}),s.success(e(`configSaved`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function k(){let t=p();return y({mutationFn:({data:e})=>g(e),onSuccess:()=>{t.invalidateQueries({queryKey:[`config`]}),t.invalidateQueries({queryKey:[`config-meta`]}),s.success(e(`configSavedApplied`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function A(){let t=p();return y({mutationFn:({provider:e,data:t})=>_(e,t),onSuccess:(n,r)=>{t.invalidateQueries({queryKey:[`providers`]}),t.invalidateQueries({queryKey:[`config`]}),r.silentSuccess||s.success(e(`configSaved`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function j(){let t=p();return y({mutationFn:({data:e})=>r(e??{}),onSuccess:()=>{t.invalidateQueries({queryKey:[`providers`]}),t.invalidateQueries({queryKey:[`config`]}),s.success(e(`configSaved`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function M(){let t=p();return y({mutationFn:({provider:e})=>l(e),onSuccess:()=>{t.invalidateQueries({queryKey:[`providers`]}),t.invalidateQueries({queryKey:[`config`]}),s.success(e(`configSaved`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function N(){return y({mutationFn:({provider:e,data:n})=>t(e,n)})}function P(){return y({mutationFn:({provider:e,data:t})=>c(e,t)})}function F(){return y({mutationFn:({provider:e,data:t})=>f(e,t)})}function I(){return y({mutationFn:({provider:e})=>i(e)})}function L(){let t=p();return y({mutationFn:({channel:e,data:t})=>h(e,t),onSuccess:()=>{t.invalidateQueries({queryKey:[`config`]}),t.invalidateQueries({queryKey:[`config-meta`]}),s.success(e(`configSavedApplying`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function R(){let t=p();return y({mutationFn:({data:e})=>b(e),onSuccess:()=>{t.invalidateQueries({queryKey:[`config`]}),s.success(e(`configSavedApplied`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function z(){let t=p();return y({mutationFn:({data:e})=>m(e),onSuccess:()=>{t.invalidateQueries({queryKey:[`config`]}),s.success(e(`configSavedApplied`))},onError:t=>{s.error(e(`configSaveFailed`)+`: `+t.message)}})}function B(){return y({mutationFn:({actionId:e,data:t})=>S(e,t),onError:t=>{s.error(e(`error`)+`: `+t.message)}})}export{k as _,M as a,F as c,P as d,N as f,R as g,A as h,j as i,E as l,O as m,w as n,B as o,L as p,D as r,I as s,C as t,T as u,z as v};
@@ -1 +0,0 @@
1
- import{c as e}from"./dist-D5ycbwCo.js";var t=e(`X`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]);export{t};
@@ -1,77 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { resolveChatInputSurfaceState } from '@nextclaw/agent-chat-ui';
3
- import { createPanelAppReferenceInputSurfacePlugin, PANEL_APP_REFERENCE_TRIGGER_SPEC } from '@/features/chat/features/input/input-surface-plugins/panel-app-reference-plugin.utils';
4
- import type { PanelAppEntryView } from '@/shared/lib/api';
5
-
6
- function createPanelApp(overrides: Partial<PanelAppEntryView> & Pick<PanelAppEntryView, 'appId' | 'title'>): PanelAppEntryView {
7
- return {
8
- id: overrides.id ?? overrides.appId,
9
- appId: overrides.appId,
10
- fileName: overrides.fileName ?? `${overrides.appId}.panel.html`,
11
- kind: overrides.kind ?? 'single-file',
12
- title: overrides.title,
13
- description: overrides.description,
14
- contentPath: overrides.contentPath ?? `/panels/${overrides.appId}.panel.html`,
15
- createdAt: overrides.createdAt ?? '2026-06-18T00:00:00.000Z',
16
- updatedAt: overrides.updatedAt ?? '2026-06-18T00:00:00.000Z',
17
- sizeBytes: overrides.sizeBytes ?? 100,
18
- favorite: overrides.favorite ?? false,
19
- clientDeclared: overrides.clientDeclared ?? false,
20
- clientGranted: overrides.clientGranted ?? false,
21
- lastOpenedAt: overrides.lastOpenedAt,
22
- openCount: overrides.openCount ?? 0,
23
- };
24
- }
25
-
26
- describe('panel app reference input surface plugin', () => {
27
- it('returns panel app reference items for @ trigger queries', () => {
28
- const plugin = createPanelAppReferenceInputSurfacePlugin({
29
- itemTexts: {
30
- appIdLabel: 'App ID',
31
- fileLabel: 'File',
32
- noDescriptionLabel: 'No description',
33
- subtitle: 'Panel App',
34
- },
35
- menuTexts: {
36
- loadingLabel: 'Loading',
37
- sectionLabel: 'Panel Apps',
38
- emptyLabel: 'Empty',
39
- hintLabel: 'Type @',
40
- itemHintLabel: 'Enter to reference',
41
- },
42
- });
43
-
44
- const state = resolveChatInputSurfaceState({
45
- plugins: [plugin],
46
- trigger: {
47
- ...PANEL_APP_REFERENCE_TRIGGER_SPEC,
48
- query: 'task',
49
- start: 0,
50
- end: 5,
51
- },
52
- data: {
53
- isPanelAppsLoading: false,
54
- isSkillsLoading: false,
55
- panelApps: [
56
- createPanelApp({
57
- appId: 'task-board',
58
- title: 'Task Board',
59
- description: 'Track tasks',
60
- }),
61
- ],
62
- recentSkillValues: [],
63
- skillRecords: [],
64
- },
65
- });
66
-
67
- expect(state.panel?.items).toEqual([
68
- expect.objectContaining({
69
- key: 'panel-app:task-board',
70
- title: 'Task Board',
71
- tokenKind: 'panel_app',
72
- tokenKey: 'task-board',
73
- value: 'task-board',
74
- }),
75
- ]);
76
- });
77
- });
@@ -1,144 +0,0 @@
1
- import {
2
- createInputSurfaceReferenceTokenPlugin,
3
- type ChatInputSurfaceItem,
4
- type ChatInputSurfaceMenuTexts,
5
- type ChatInputSurfacePlugin,
6
- type ChatInputSurfaceTriggerSpec,
7
- } from '@nextclaw/agent-chat-ui';
8
- import type { ChatInputProductPluginData } from './chat-input-product-plugin-adapters.types';
9
- import type { PanelAppEntryView } from '@/shared/lib/api';
10
- import {
11
- scoreInputSurfaceSearchCandidate,
12
- resolveInputSurfaceMatchTier,
13
- } from './input-surface-search.utils';
14
-
15
- export const PANEL_APP_REFERENCE_TRIGGER_SPEC: ChatInputSurfaceTriggerSpec = {
16
- key: 'panel-app-reference',
17
- marker: '@',
18
- };
19
-
20
- function getPanelAppActivityTime(entry: PanelAppEntryView): number {
21
- return Date.parse(entry.lastOpenedAt ?? entry.updatedAt) || 0;
22
- }
23
-
24
- export type PanelAppInputSurfaceItemTexts = {
25
- appIdLabel: string;
26
- fileLabel: string;
27
- noDescriptionLabel: string;
28
- subtitle: string;
29
- };
30
-
31
- function resolvePanelAppInputSurfaceEntries(params: {
32
- entries: readonly PanelAppEntryView[];
33
- query: string;
34
- }): PanelAppEntryView[] {
35
- const collator = new Intl.Collator(undefined, { sensitivity: 'base', numeric: true });
36
- return params.entries
37
- .map((entry, order) => ({
38
- entry,
39
- order,
40
- score: scoreInputSurfaceSearchCandidate(
41
- {
42
- id: entry.appId,
43
- label: entry.title || entry.appId,
44
- description: entry.description,
45
- aliases: [entry.id, entry.fileName],
46
- },
47
- params.query,
48
- ),
49
- }))
50
- .filter((entry) => entry.score > 0)
51
- .sort((left, right) => {
52
- const leftTier = resolveInputSurfaceMatchTier(left.score);
53
- const rightTier = resolveInputSurfaceMatchTier(right.score);
54
- if (rightTier !== leftTier) {
55
- return rightTier - leftTier;
56
- }
57
- if (left.entry.favorite !== right.entry.favorite) {
58
- return left.entry.favorite ? -1 : 1;
59
- }
60
- const rightActivity = getPanelAppActivityTime(right.entry);
61
- const leftActivity = getPanelAppActivityTime(left.entry);
62
- if (rightActivity !== leftActivity) {
63
- return rightActivity - leftActivity;
64
- }
65
- if (right.score !== left.score) {
66
- return right.score - left.score;
67
- }
68
- const labelCompare = collator.compare(left.entry.title || left.entry.appId, right.entry.title || right.entry.appId);
69
- return labelCompare || left.order - right.order;
70
- })
71
- .map(({ entry }) => entry);
72
- }
73
-
74
- function buildPanelAppInputSurfaceItemEntries(params: {
75
- entries: readonly PanelAppEntryView[];
76
- keyPrefix?: string;
77
- query: string;
78
- texts: PanelAppInputSurfaceItemTexts;
79
- }): Array<{ entry: PanelAppEntryView; item: ChatInputSurfaceItem }> {
80
- const keyPrefix = params.keyPrefix ?? 'panel-app';
81
- return resolvePanelAppInputSurfaceEntries({
82
- entries: params.entries,
83
- query: params.query,
84
- }).map((entry) => ({
85
- entry,
86
- item: {
87
- key: `${keyPrefix}:${entry.appId}`,
88
- title: entry.title || entry.appId,
89
- subtitle: params.texts.subtitle,
90
- description: (entry.description ?? '').trim() || params.texts.noDescriptionLabel,
91
- detailLines: [
92
- `${params.texts.appIdLabel}: ${entry.appId}`,
93
- `${params.texts.fileLabel}: ${entry.fileName}`,
94
- ],
95
- },
96
- }));
97
- }
98
-
99
- export function buildPanelAppInputSurfaceItems(params: {
100
- entries: readonly PanelAppEntryView[];
101
- keyPrefix?: string;
102
- query: string;
103
- texts: PanelAppInputSurfaceItemTexts;
104
- }): ChatInputSurfaceItem[] {
105
- return buildPanelAppInputSurfaceItemEntries(params).map(({ item }) => item);
106
- }
107
-
108
- function buildPanelAppReferenceItems(params: {
109
- entries: readonly PanelAppEntryView[];
110
- query: string;
111
- texts: PanelAppInputSurfaceItemTexts;
112
- }): ChatInputSurfaceItem[] {
113
- return buildPanelAppInputSurfaceItemEntries(params).map(({ entry, item }) => ({
114
- ...item,
115
- tokenKind: 'panel_app',
116
- tokenKey: entry.appId,
117
- value: entry.appId,
118
- }));
119
- }
120
-
121
- export function createPanelAppReferenceInputSurfacePlugin(params: {
122
- itemTexts: {
123
- appIdLabel: string;
124
- fileLabel: string;
125
- noDescriptionLabel: string;
126
- subtitle: string;
127
- };
128
- menuTexts: ChatInputSurfaceMenuTexts;
129
- }): ChatInputSurfacePlugin<ChatInputProductPluginData> {
130
- return createInputSurfaceReferenceTokenPlugin({
131
- key: 'panel-app-reference',
132
- trigger: PANEL_APP_REFERENCE_TRIGGER_SPEC,
133
- tokenKind: 'panel_app',
134
- texts: params.menuTexts,
135
- getIsLoading: ({ data }) => data.isPanelAppsLoading,
136
- getRecords: ({ data }) => data.panelApps,
137
- getItems: ({ records, query }) =>
138
- buildPanelAppReferenceItems({
139
- entries: records,
140
- query,
141
- texts: params.itemTexts,
142
- }),
143
- });
144
- }