@nextclaw/ui 0.12.15 → 0.12.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/assets/{api-HsS9C7l0.js → api-BIg--UMJ.js} +1 -1
- package/dist/assets/{app-manager-provider-CNa6cmOk.js → app-manager-provider-BfKiVYea.js} +1 -1
- package/dist/assets/{app-navigation.config-Dy69P_3O.js → app-navigation.config-xIjCAn-R.js} +1 -1
- package/dist/assets/{book-open-DJSe9YLj.js → book-open-CUd69I2f.js} +1 -1
- package/dist/assets/{channels-list-page-DtjYJ1FX.js → channels-list-page-5wQy-UW7.js} +1 -1
- package/dist/assets/chat-CXrERmQ1.js +60 -0
- package/dist/assets/{chat-page-Cslvp6SG.js → chat-page-CTLX0KsB.js} +1 -1
- package/dist/assets/{chunk-JZWAC4HX-CMPxE3BJ.js → chunk-JZWAC4HX-THqEFwu9.js} +1 -1
- package/dist/assets/{config-split-page-v7p1CQjU.js → config-split-page-UJSTBsEU.js} +1 -1
- package/dist/assets/{createLucideIcon-Y1cWg3R9.js → createLucideIcon-DVAlgDOi.js} +1 -1
- package/dist/assets/{desktop-update-config-CqJmmpjR.js → desktop-update-config-B0vQ5JID.js} +1 -1
- package/dist/assets/{dialog-CYis0wx_.js → dialog-t7OAmObC.js} +1 -1
- package/dist/assets/{dist-DIWOVzPY.js → dist-DWPNydLC.js} +1 -1
- package/dist/assets/doc-browser-BIggpN8Z.js +1 -0
- package/dist/assets/{doc-browser-BQT0fa3g.js → doc-browser-DznuT-CU.js} +1 -1
- package/dist/assets/{doc-browser-context-BacwCbOG.js → doc-browser-context-zXaTjrpA.js} +1 -1
- package/dist/assets/{doc-browser-CP6kjGaF.js → doc-browser-t96ibd-b.js} +1 -1
- package/dist/assets/{es2015-3VnZDFPs.js → es2015-BRVsmfFO.js} +1 -1
- package/dist/assets/{external-link-CPhZo92k.js → external-link-D1Xqff6i.js} +1 -1
- package/dist/assets/{folder-orBwjR8h.js → folder-B_fuaX3x.js} +1 -1
- package/dist/assets/{hash-BvWW8Scd.js → hash-BRvv_UUq.js} +1 -1
- package/dist/assets/i18n-CF_jgT_-.js +1 -0
- package/dist/assets/index-DuHqJ8wn.css +1 -0
- package/dist/assets/{index-D0_J-bk_.js → index-mw77my39.js} +2 -2
- package/dist/assets/{key-round-B5u2XQwa.js → key-round-DFVNXZcD.js} +1 -1
- package/dist/assets/loader-circle-DEz3bHGb.js +1 -0
- package/dist/assets/{logo-badge-BLQdO_th.js → logo-badge-CRVKkIl9.js} +1 -1
- package/dist/assets/{logos-WPtZ1joO.js → logos-BVCi_7_I.js} +1 -1
- package/dist/assets/marketplace-page-DVmk8dZk.js +1 -0
- package/dist/assets/{marketplace-page-It54wla_.js → marketplace-page-apq5LpYx.js} +1 -1
- package/dist/assets/mcp-marketplace-page-CskrJuKU.js +1 -0
- package/dist/assets/{mcp-marketplace-page-C64VUmni.js → mcp-marketplace-page-DiqTAdRJ.js} +1 -1
- package/dist/assets/message-square-CLhDWybk.js +1 -0
- package/dist/assets/{model-config-Cu6zLI8a.js → model-config-cth12uRn.js} +1 -1
- package/dist/assets/{notice-card-DDVM6IFQ.js → notice-card-CXY09tsa.js} +1 -1
- package/dist/assets/play-CnnPm8ca.js +1 -0
- package/dist/assets/plus-CdYMdiws.js +1 -0
- package/dist/assets/{popover-Dliq2K8O.js → popover-CbQxrchk.js} +1 -1
- package/dist/assets/{provider-scoped-model-input-D0oXIrWA.js → provider-scoped-model-input-CZEB2m98.js} +1 -1
- package/dist/assets/{providers-list-CrwTWzge.js → providers-list-Dsj2BYPm.js} +1 -1
- package/dist/assets/{refresh-ccw-pX3BUxPF.js → refresh-ccw-C-ytTHiq.js} +1 -1
- package/dist/assets/remote-DMMC2PSo.js +1 -0
- package/dist/assets/{rotate-cw-Bm8W8iaF.js → rotate-cw-ClSrRUa0.js} +1 -1
- package/dist/assets/{runtime-config-page-CYZyCr04.js → runtime-config-page-JpAUjHTI.js} +1 -1
- package/dist/assets/{save-CZ9zvmBJ.js → save-KxhpE3Zr.js} +1 -1
- package/dist/assets/{search-DpxqxcpP.js → search-Bz3Q64sr.js} +1 -1
- package/dist/assets/{search-config-D_H6cr07.js → search-config-C_xRBv_i.js} +1 -1
- package/dist/assets/{secrets-config-BG9fic_R.js → secrets-config-BOL024Fj.js} +1 -1
- package/dist/assets/{select-D-gjRjhr.js → select-tRTLG4FK.js} +1 -1
- package/dist/assets/{sessions-config-page-DzSOCrQt.js → sessions-config-page-CLEEGNYL.js} +1 -1
- package/dist/assets/{setting-row-Cl4_XpIR.js → setting-row-DMDgBCC7.js} +1 -1
- package/dist/assets/{settings-C9WgQdGW.js → settings-Cto6z-Ij.js} +1 -1
- package/dist/assets/skeleton-BwfJfVK3.js +1 -0
- package/dist/assets/{sparkles-gvRilA9f.js → sparkles-xZ74eW0P.js} +1 -1
- package/dist/assets/{status-dot-W2TPs1Zf.js → status-dot-Bobpfutv.js} +1 -1
- package/dist/assets/{tabs-custom-BxZfWeD1.js → tabs-custom-C3Mf-NLb.js} +1 -1
- package/dist/assets/{tag-chip-DfmhmN50.js → tag-chip-BZ14i5b1.js} +1 -1
- package/dist/assets/{theme-provider-CajCgE_N.js → theme-provider-D6Cgm6i-.js} +1 -1
- package/dist/assets/{tooltip-C1XVx_h1.js → tooltip-7lsLGcL9.js} +1 -1
- package/dist/assets/{trash-2-WC4Dlakj.js → trash-2-WFSNa5oj.js} +1 -1
- package/dist/assets/{use-config-BIErdQNR.js → use-config-CXu7dFzw.js} +1 -1
- package/dist/assets/{use-confirm-dialog-B3ZsM4V-.js → use-confirm-dialog-Df1SozKw.js} +1 -1
- package/dist/assets/{use-infinite-scroll-loader-rO55YHGO.js → use-infinite-scroll-loader-BogRuzgz.js} +1 -1
- package/dist/assets/{use-viewport-layout-zLAsjh3A.js → use-viewport-layout-CWlW5b-T.js} +1 -1
- package/dist/assets/x-BvS2y4e_.js +1 -0
- package/dist/index.html +39 -39
- package/package.json +4 -4
- package/src/features/chat/components/conversation/chat-input-bar.container.tsx +5 -1
- package/src/features/chat/utils/chat-input-bar.utils.test.ts +3 -3
- package/src/features/chat/utils/chat-input-toolbar.utils.ts +1 -1
- package/src/index.css +97 -5
- package/src/shared/components/common/agent-avatar.test.tsx +33 -0
- package/src/shared/components/common/agent-avatar.tsx +6 -9
- package/src/shared/lib/i18n/chat.ts +2 -1
- package/dist/assets/chat-Rmwi-kQn.js +0 -58
- package/dist/assets/doc-browser-DK2tXLi_.js +0 -1
- package/dist/assets/i18n-BhoFaF7E.js +0 -1
- package/dist/assets/index-OrUEVLgT.css +0 -1
- package/dist/assets/loader-circle-DotuB8NZ.js +0 -1
- package/dist/assets/marketplace-page-CJHkdgv_.js +0 -1
- package/dist/assets/mcp-marketplace-page-DIItTRy_.js +0 -1
- package/dist/assets/message-square-CO_7rU-N.js +0 -1
- package/dist/assets/play-kSfmJAme.js +0 -1
- package/dist/assets/plus-BNaF7Wq5.js +0 -1
- package/dist/assets/remote-BpAw88FR.js +0 -1
- package/dist/assets/skeleton-BN6fOana.js +0 -1
- package/dist/assets/x-D1867E7F.js +0 -1
package/dist/index.html
CHANGED
|
@@ -78,45 +78,45 @@
|
|
|
78
78
|
})();
|
|
79
79
|
</script>
|
|
80
80
|
<title>NextClaw</title>
|
|
81
|
-
<script type="module" crossorigin src="/assets/index-
|
|
82
|
-
<link rel="modulepreload" crossorigin href="/assets/i18n-
|
|
83
|
-
<link rel="modulepreload" crossorigin href="/assets/api-
|
|
84
|
-
<link rel="modulepreload" crossorigin href="/assets/es2015-
|
|
85
|
-
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-
|
|
86
|
-
<link rel="modulepreload" crossorigin href="/assets/select-
|
|
87
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
88
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
89
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
90
|
-
<link rel="modulepreload" crossorigin href="/assets/popover-
|
|
91
|
-
<link rel="modulepreload" crossorigin href="/assets/tooltip-
|
|
92
|
-
<link rel="modulepreload" crossorigin href="/assets/chunk-JZWAC4HX-
|
|
93
|
-
<link rel="modulepreload" crossorigin href="/assets/use-config-
|
|
94
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-provider-
|
|
95
|
-
<link rel="modulepreload" crossorigin href="/assets/search-
|
|
96
|
-
<link rel="modulepreload" crossorigin href="/assets/book-open-
|
|
97
|
-
<link rel="modulepreload" crossorigin href="/assets/external-link-
|
|
98
|
-
<link rel="modulepreload" crossorigin href="/assets/folder-
|
|
99
|
-
<link rel="modulepreload" crossorigin href="/assets/logos-
|
|
100
|
-
<link rel="modulepreload" crossorigin href="/assets/loader-circle-
|
|
101
|
-
<link rel="modulepreload" crossorigin href="/assets/plus-
|
|
102
|
-
<link rel="modulepreload" crossorigin href="/assets/refresh-ccw-
|
|
103
|
-
<link rel="modulepreload" crossorigin href="/assets/settings-
|
|
104
|
-
<link rel="modulepreload" crossorigin href="/assets/sparkles-
|
|
105
|
-
<link rel="modulepreload" crossorigin href="/assets/trash-2-
|
|
106
|
-
<link rel="modulepreload" crossorigin href="/assets/doc-browser-context-
|
|
107
|
-
<link rel="modulepreload" crossorigin href="/assets/doc-browser-
|
|
108
|
-
<link rel="modulepreload" crossorigin href="/assets/doc-browser-
|
|
109
|
-
<link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-
|
|
110
|
-
<link rel="modulepreload" crossorigin href="/assets/logo-badge-
|
|
111
|
-
<link rel="modulepreload" crossorigin href="/assets/skeleton-
|
|
112
|
-
<link rel="modulepreload" crossorigin href="/assets/chat-
|
|
113
|
-
<link rel="modulepreload" crossorigin href="/assets/key-round-
|
|
114
|
-
<link rel="modulepreload" crossorigin href="/assets/message-square-
|
|
115
|
-
<link rel="modulepreload" crossorigin href="/assets/app-navigation.config-
|
|
116
|
-
<link rel="modulepreload" crossorigin href="/assets/notice-card-
|
|
117
|
-
<link rel="modulepreload" crossorigin href="/assets/status-dot-
|
|
118
|
-
<link rel="modulepreload" crossorigin href="/assets/app-manager-provider-
|
|
119
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
81
|
+
<script type="module" crossorigin src="/assets/index-mw77my39.js"></script>
|
|
82
|
+
<link rel="modulepreload" crossorigin href="/assets/i18n-CF_jgT_-.js">
|
|
83
|
+
<link rel="modulepreload" crossorigin href="/assets/api-BIg--UMJ.js">
|
|
84
|
+
<link rel="modulepreload" crossorigin href="/assets/es2015-BRVsmfFO.js">
|
|
85
|
+
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-DVAlgDOi.js">
|
|
86
|
+
<link rel="modulepreload" crossorigin href="/assets/select-tRTLG4FK.js">
|
|
87
|
+
<link rel="modulepreload" crossorigin href="/assets/dist-DWPNydLC.js">
|
|
88
|
+
<link rel="modulepreload" crossorigin href="/assets/x-BvS2y4e_.js">
|
|
89
|
+
<link rel="modulepreload" crossorigin href="/assets/dialog-t7OAmObC.js">
|
|
90
|
+
<link rel="modulepreload" crossorigin href="/assets/popover-CbQxrchk.js">
|
|
91
|
+
<link rel="modulepreload" crossorigin href="/assets/tooltip-7lsLGcL9.js">
|
|
92
|
+
<link rel="modulepreload" crossorigin href="/assets/chunk-JZWAC4HX-THqEFwu9.js">
|
|
93
|
+
<link rel="modulepreload" crossorigin href="/assets/use-config-CXu7dFzw.js">
|
|
94
|
+
<link rel="modulepreload" crossorigin href="/assets/theme-provider-D6Cgm6i-.js">
|
|
95
|
+
<link rel="modulepreload" crossorigin href="/assets/search-Bz3Q64sr.js">
|
|
96
|
+
<link rel="modulepreload" crossorigin href="/assets/book-open-CUd69I2f.js">
|
|
97
|
+
<link rel="modulepreload" crossorigin href="/assets/external-link-D1Xqff6i.js">
|
|
98
|
+
<link rel="modulepreload" crossorigin href="/assets/folder-B_fuaX3x.js">
|
|
99
|
+
<link rel="modulepreload" crossorigin href="/assets/logos-BVCi_7_I.js">
|
|
100
|
+
<link rel="modulepreload" crossorigin href="/assets/loader-circle-DEz3bHGb.js">
|
|
101
|
+
<link rel="modulepreload" crossorigin href="/assets/plus-CdYMdiws.js">
|
|
102
|
+
<link rel="modulepreload" crossorigin href="/assets/refresh-ccw-C-ytTHiq.js">
|
|
103
|
+
<link rel="modulepreload" crossorigin href="/assets/settings-Cto6z-Ij.js">
|
|
104
|
+
<link rel="modulepreload" crossorigin href="/assets/sparkles-xZ74eW0P.js">
|
|
105
|
+
<link rel="modulepreload" crossorigin href="/assets/trash-2-WFSNa5oj.js">
|
|
106
|
+
<link rel="modulepreload" crossorigin href="/assets/doc-browser-context-zXaTjrpA.js">
|
|
107
|
+
<link rel="modulepreload" crossorigin href="/assets/doc-browser-t96ibd-b.js">
|
|
108
|
+
<link rel="modulepreload" crossorigin href="/assets/doc-browser-DznuT-CU.js">
|
|
109
|
+
<link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-CWlW5b-T.js">
|
|
110
|
+
<link rel="modulepreload" crossorigin href="/assets/logo-badge-CRVKkIl9.js">
|
|
111
|
+
<link rel="modulepreload" crossorigin href="/assets/skeleton-BwfJfVK3.js">
|
|
112
|
+
<link rel="modulepreload" crossorigin href="/assets/chat-CXrERmQ1.js">
|
|
113
|
+
<link rel="modulepreload" crossorigin href="/assets/key-round-DFVNXZcD.js">
|
|
114
|
+
<link rel="modulepreload" crossorigin href="/assets/message-square-CLhDWybk.js">
|
|
115
|
+
<link rel="modulepreload" crossorigin href="/assets/app-navigation.config-xIjCAn-R.js">
|
|
116
|
+
<link rel="modulepreload" crossorigin href="/assets/notice-card-CXY09tsa.js">
|
|
117
|
+
<link rel="modulepreload" crossorigin href="/assets/status-dot-Bobpfutv.js">
|
|
118
|
+
<link rel="modulepreload" crossorigin href="/assets/app-manager-provider-BfKiVYea.js">
|
|
119
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DuHqJ8wn.css">
|
|
120
120
|
</head>
|
|
121
121
|
|
|
122
122
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/ui",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"tailwind-merge": "^2.5.4",
|
|
29
29
|
"zod": "^3.23.8",
|
|
30
30
|
"zustand": "^5.0.2",
|
|
31
|
+
"@nextclaw/agent-chat-ui": "0.3.11",
|
|
31
32
|
"@nextclaw/ncp-http-agent-client": "0.3.17",
|
|
32
|
-
"@nextclaw/agent-chat": "0.1.10",
|
|
33
|
-
"@nextclaw/agent-chat-ui": "0.3.10",
|
|
34
33
|
"@nextclaw/ncp-react": "0.4.25",
|
|
35
|
-
"@nextclaw/ncp": "0.5.5"
|
|
34
|
+
"@nextclaw/ncp": "0.5.5",
|
|
35
|
+
"@nextclaw/agent-chat": "0.1.10"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@testing-library/react": "^16.3.0",
|
|
@@ -6,6 +6,7 @@ import type { SessionSkillEntryView } from '@/shared/lib/api';
|
|
|
6
6
|
import { buildChatSlashItems, buildModelStateHint, buildModelToolbarSelect, buildSkillPickerModel, buildThinkingToolbarSelect, type ChatModelRecord, type ChatSkillRecord, type ChatThinkingLevel } from '@/features/chat/utils/chat-input-bar.utils';
|
|
7
7
|
import { usePresenter } from '@/features/chat/components/providers/chat-presenter.provider';
|
|
8
8
|
import { useI18n } from '@/app/components/i18n-provider';
|
|
9
|
+
import { useViewportLayout } from '@/app/hooks/use-viewport-layout';
|
|
9
10
|
import { useChatInputStore } from '@/features/chat/stores/chat-input.store';
|
|
10
11
|
import { chatRecentModelsManager, CHAT_RECENT_MODELS_MIN_OPTIONS } from '@/features/chat/managers/chat-recent-models.manager';
|
|
11
12
|
import { chatRecentSkillsManager, CHAT_RECENT_SKILLS_MIN_OPTIONS } from '@/features/chat/managers/chat-recent-skills.manager';
|
|
@@ -203,6 +204,7 @@ function buildSkillPicker(params: { allSkillsLabel: string; presenter: ChatPrese
|
|
|
203
204
|
export function ChatInputBarContainer() {
|
|
204
205
|
const presenter = usePresenter();
|
|
205
206
|
const { language } = useI18n();
|
|
207
|
+
const { isMobile } = useViewportLayout();
|
|
206
208
|
const snapshot = useChatInputStore((state) => state.snapshot);
|
|
207
209
|
const runtimeAvailability = useChatRuntimeAvailability();
|
|
208
210
|
const [slashQuery, setSlashQuery] = useState<string | null>(null);
|
|
@@ -215,7 +217,9 @@ export function ChatInputBarContainer() {
|
|
|
215
217
|
const isModelOptionsEmpty = isNcpChatModelOptionsEmpty(snapshot);
|
|
216
218
|
const inputDisabled = isNcpChatComposerDisabled(snapshot);
|
|
217
219
|
const attachmentSupported = typeof presenter.chatInputManager.addAttachments === 'function';
|
|
218
|
-
const textareaPlaceholder = isModelOptionsEmpty
|
|
220
|
+
const textareaPlaceholder = isModelOptionsEmpty
|
|
221
|
+
? t('chatModelNoOptions')
|
|
222
|
+
: t(isMobile ? 'chatInputPlaceholderCompact' : 'chatInputPlaceholder');
|
|
219
223
|
const slashItems = useMemo(
|
|
220
224
|
() => buildChatSlashItems(skillRecords, slashQuery ?? '', labels.slashTexts, recentSkillValues),
|
|
221
225
|
[labels.slashTexts, recentSkillValues, skillRecords, slashQuery]
|
|
@@ -212,14 +212,14 @@ describe('buildModelToolbarSelect', () => {
|
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
expect(select.value).toBe('minimax/MiniMax-M2.7');
|
|
215
|
-
expect(select.selectedLabel).toBe('MiniMax-M2.7');
|
|
215
|
+
expect(select.selectedLabel).toBe('MiniMax/MiniMax-M2.7');
|
|
216
216
|
expect(select.options[0]).toEqual({
|
|
217
217
|
value: 'minimax/MiniMax-M2.7',
|
|
218
218
|
label: 'MiniMax/MiniMax-M2.7'
|
|
219
219
|
});
|
|
220
220
|
});
|
|
221
221
|
|
|
222
|
-
it('keeps provider
|
|
222
|
+
it('keeps the full provider/model label in shared state while exposing a compact mobile label', () => {
|
|
223
223
|
const select = buildModelToolbarSelect({
|
|
224
224
|
modelOptions: [
|
|
225
225
|
{
|
|
@@ -241,7 +241,7 @@ describe('buildModelToolbarSelect', () => {
|
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
-
expect(select.selectedLabel).toBe('claude-sonnet-4-very-long-name');
|
|
244
|
+
expect(select.selectedLabel).toBe('Anthropic/claude-sonnet-4-very-long-name');
|
|
245
245
|
expect(select.options[0]?.label).toBe('Anthropic/claude-sonnet-4-very-long-name');
|
|
246
246
|
});
|
|
247
247
|
|
|
@@ -113,7 +113,7 @@ export function buildModelToolbarSelect({
|
|
|
113
113
|
value: resolvedValue,
|
|
114
114
|
placeholder: texts.modelSelectPlaceholder,
|
|
115
115
|
selectedLabel: resolvedModelOption
|
|
116
|
-
?
|
|
116
|
+
? formatModelOptionLabel(resolvedModelOption)
|
|
117
117
|
: undefined,
|
|
118
118
|
icon: "sparkles",
|
|
119
119
|
options: modelOptions.map((option) => ({
|
package/src/index.css
CHANGED
|
@@ -220,6 +220,16 @@
|
|
|
220
220
|
--md-code-toolbar-bg: rgba(15, 23, 42, 0.56);
|
|
221
221
|
--md-code-toolbar-border: rgba(148, 163, 184, 0.3);
|
|
222
222
|
--md-code-text: #e5e7eb;
|
|
223
|
+
--md-code-muted: #9ca3af;
|
|
224
|
+
--md-code-keyword: #c084fc;
|
|
225
|
+
--md-code-title: #93c5fd;
|
|
226
|
+
--md-code-string: #86efac;
|
|
227
|
+
--md-code-number: #fbbf24;
|
|
228
|
+
--md-code-comment: #94a3b8;
|
|
229
|
+
--md-code-attr: #67e8f9;
|
|
230
|
+
--md-code-meta: #f0abfc;
|
|
231
|
+
--md-code-deletion: #fca5a5;
|
|
232
|
+
--md-code-addition: #86efac;
|
|
223
233
|
--md-table-head-bg: rgba(148, 163, 184, 0.14);
|
|
224
234
|
|
|
225
235
|
color: var(--md-text);
|
|
@@ -241,6 +251,16 @@
|
|
|
241
251
|
--md-code-toolbar-bg: rgba(2, 6, 23, 0.88);
|
|
242
252
|
--md-code-toolbar-border: rgba(191, 219, 254, 0.26);
|
|
243
253
|
--md-code-text: #e2e8f0;
|
|
254
|
+
--md-code-muted: #a5b4fc;
|
|
255
|
+
--md-code-keyword: #d8b4fe;
|
|
256
|
+
--md-code-title: #bfdbfe;
|
|
257
|
+
--md-code-string: #bbf7d0;
|
|
258
|
+
--md-code-number: #fde68a;
|
|
259
|
+
--md-code-comment: #cbd5e1;
|
|
260
|
+
--md-code-attr: #a5f3fc;
|
|
261
|
+
--md-code-meta: #f5d0fe;
|
|
262
|
+
--md-code-deletion: #fecaca;
|
|
263
|
+
--md-code-addition: #bbf7d0;
|
|
244
264
|
--md-table-head-bg: rgba(191, 219, 254, 0.16);
|
|
245
265
|
}
|
|
246
266
|
|
|
@@ -394,9 +414,12 @@
|
|
|
394
414
|
.chat-codeblock {
|
|
395
415
|
margin: 0.2rem 0 0.1rem;
|
|
396
416
|
border: 1px solid var(--md-code-toolbar-border);
|
|
397
|
-
border-radius: 0.
|
|
417
|
+
border-radius: 0.5rem;
|
|
398
418
|
overflow: hidden;
|
|
399
|
-
background:
|
|
419
|
+
background:
|
|
420
|
+
linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0)),
|
|
421
|
+
var(--md-code-surface);
|
|
422
|
+
box-shadow: 0 12px 34px rgba(15, 23, 42, 0.13);
|
|
400
423
|
}
|
|
401
424
|
|
|
402
425
|
.chat-codeblock-toolbar {
|
|
@@ -426,7 +449,7 @@
|
|
|
426
449
|
font-weight: 600;
|
|
427
450
|
color: var(--md-code-text);
|
|
428
451
|
border: 1px solid var(--md-code-toolbar-border);
|
|
429
|
-
border-radius: 0.
|
|
452
|
+
border-radius: 0.42rem;
|
|
430
453
|
padding: 0.18rem 0.36rem;
|
|
431
454
|
background: transparent;
|
|
432
455
|
cursor: pointer;
|
|
@@ -439,17 +462,86 @@
|
|
|
439
462
|
|
|
440
463
|
.chat-codeblock pre {
|
|
441
464
|
margin: 0;
|
|
442
|
-
padding: 0.
|
|
465
|
+
padding: 0.8rem 0.9rem 0.86rem;
|
|
443
466
|
overflow-x: auto;
|
|
444
467
|
background: transparent;
|
|
468
|
+
scrollbar-color: rgba(148, 163, 184, 0.48) transparent;
|
|
469
|
+
scrollbar-width: thin;
|
|
445
470
|
}
|
|
446
471
|
|
|
447
472
|
.chat-codeblock code {
|
|
448
473
|
display: block;
|
|
449
474
|
min-width: max-content;
|
|
450
475
|
white-space: pre;
|
|
451
|
-
line-height: 1.
|
|
476
|
+
line-height: 1.62;
|
|
452
477
|
color: var(--md-code-text);
|
|
478
|
+
font-size: 0.79rem;
|
|
479
|
+
font-variant-ligatures: none;
|
|
480
|
+
tab-size: 2;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.chat-codeblock .hljs-keyword,
|
|
484
|
+
.chat-codeblock .hljs-built_in,
|
|
485
|
+
.chat-codeblock .hljs-type,
|
|
486
|
+
.chat-codeblock .hljs-literal,
|
|
487
|
+
.chat-codeblock .hljs-selector-tag {
|
|
488
|
+
color: var(--md-code-keyword);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.chat-codeblock .hljs-title,
|
|
492
|
+
.chat-codeblock .hljs-title.function_,
|
|
493
|
+
.chat-codeblock .hljs-title.class_,
|
|
494
|
+
.chat-codeblock .hljs-section,
|
|
495
|
+
.chat-codeblock .hljs-selector-id {
|
|
496
|
+
color: var(--md-code-title);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.chat-codeblock .hljs-string,
|
|
500
|
+
.chat-codeblock .hljs-regexp,
|
|
501
|
+
.chat-codeblock .hljs-symbol,
|
|
502
|
+
.chat-codeblock .hljs-bullet {
|
|
503
|
+
color: var(--md-code-string);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.chat-codeblock .hljs-number,
|
|
507
|
+
.chat-codeblock .hljs-variable,
|
|
508
|
+
.chat-codeblock .hljs-template-variable,
|
|
509
|
+
.chat-codeblock .hljs-params {
|
|
510
|
+
color: var(--md-code-number);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.chat-codeblock .hljs-comment,
|
|
514
|
+
.chat-codeblock .hljs-quote {
|
|
515
|
+
color: var(--md-code-comment);
|
|
516
|
+
font-style: italic;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.chat-codeblock .hljs-attr,
|
|
520
|
+
.chat-codeblock .hljs-attribute,
|
|
521
|
+
.chat-codeblock .hljs-property,
|
|
522
|
+
.chat-codeblock .hljs-name,
|
|
523
|
+
.chat-codeblock .hljs-selector-class {
|
|
524
|
+
color: var(--md-code-attr);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.chat-codeblock .hljs-meta,
|
|
528
|
+
.chat-codeblock .hljs-doctag,
|
|
529
|
+
.chat-codeblock .hljs-tag {
|
|
530
|
+
color: var(--md-code-meta);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.chat-codeblock .hljs-subst,
|
|
534
|
+
.chat-codeblock .hljs-punctuation,
|
|
535
|
+
.chat-codeblock .hljs-operator {
|
|
536
|
+
color: var(--md-code-muted);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
.chat-codeblock .hljs-deletion {
|
|
540
|
+
color: var(--md-code-deletion);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.chat-codeblock .hljs-addition {
|
|
544
|
+
color: var(--md-code-addition);
|
|
453
545
|
}
|
|
454
546
|
|
|
455
547
|
.chat-table-wrap {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { AgentAvatar } from './agent-avatar';
|
|
4
|
+
|
|
5
|
+
describe('AgentAvatar', () => {
|
|
6
|
+
it('uses the configured image for the main agent before fallback', () => {
|
|
7
|
+
render(
|
|
8
|
+
<AgentAvatar
|
|
9
|
+
agentId="main"
|
|
10
|
+
displayName="Main"
|
|
11
|
+
avatarUrl="https://example.com/main-avatar.png"
|
|
12
|
+
/>,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const avatar = screen.getByRole('img', { name: 'Main' });
|
|
16
|
+
expect(avatar.getAttribute('src')).toBe('https://example.com/main-avatar.png');
|
|
17
|
+
expect(avatar.querySelector('svg')).toBeNull();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('uses the bot icon for the main agent fallback', () => {
|
|
21
|
+
render(<AgentAvatar agentId="main" displayName="Main" />);
|
|
22
|
+
|
|
23
|
+
const avatar = screen.getByLabelText('Main');
|
|
24
|
+
expect(avatar.querySelector('svg')).toBeTruthy();
|
|
25
|
+
expect(avatar.textContent).not.toContain('M');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('keeps letter fallback avatars for specialist agents', () => {
|
|
29
|
+
render(<AgentAvatar agentId="engineer" displayName="Engineer" />);
|
|
30
|
+
|
|
31
|
+
expect(screen.getByLabelText('Engineer').textContent).toBe('E');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cn } from '@/shared/lib/utils';
|
|
2
|
+
import { Bot } from 'lucide-react';
|
|
2
3
|
|
|
3
4
|
type AgentAvatarProps = {
|
|
4
5
|
agentId: string;
|
|
@@ -25,14 +26,6 @@ function hashText(value: string): number {
|
|
|
25
26
|
return Math.abs(hash);
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
function resolveLetter(value: string): string {
|
|
29
|
-
const trimmed = value.trim();
|
|
30
|
-
if (!trimmed) {
|
|
31
|
-
return 'A';
|
|
32
|
-
}
|
|
33
|
-
return trimmed.slice(0, 1).toUpperCase();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
29
|
export function AgentAvatar({ agentId, displayName, avatarUrl, className }: AgentAvatarProps) {
|
|
37
30
|
const seed = displayName?.trim() || agentId;
|
|
38
31
|
const [bgClass, textClass] = PALETTE[hashText(agentId) % PALETTE.length] ?? PALETTE[0];
|
|
@@ -57,7 +50,11 @@ export function AgentAvatar({ agentId, displayName, avatarUrl, className }: Agen
|
|
|
57
50
|
)}
|
|
58
51
|
aria-label={displayName?.trim() || agentId}
|
|
59
52
|
>
|
|
60
|
-
{
|
|
53
|
+
{agentId.trim().toLowerCase() === 'main' ? (
|
|
54
|
+
<Bot className="h-[55%] w-[55%]" strokeWidth={2.4} />
|
|
55
|
+
) : (
|
|
56
|
+
(seed.trim() || 'A').slice(0, 1).toUpperCase()
|
|
57
|
+
)}
|
|
61
58
|
</div>
|
|
62
59
|
);
|
|
63
60
|
}
|
|
@@ -67,7 +67,8 @@ export const CHAT_LABELS: Record<string, { zh: string; en: string }> = {
|
|
|
67
67
|
zh: '聊天能力启动失败,请稍后重试或检查服务日志。',
|
|
68
68
|
en: 'Chat startup failed. Please retry in a moment or inspect the service logs.'
|
|
69
69
|
},
|
|
70
|
-
chatInputPlaceholder: { zh: '
|
|
70
|
+
chatInputPlaceholder: { zh: '输入消息,输入 / 选择技能,Enter 发送,Shift + Enter 换行', en: 'Type a message, type / to select skills, Enter to send, Shift + Enter for newline' },
|
|
71
|
+
chatInputPlaceholderCompact: { zh: '发消息...', en: 'Message NextClaw...' },
|
|
71
72
|
chatInputHint: { zh: '支持多轮上下文,默认走当前会话。', en: 'Multi-turn context is preserved in the current session.' },
|
|
72
73
|
chatSlashSectionCommands: { zh: '命令', en: 'Commands' },
|
|
73
74
|
chatSlashSectionSkills: { zh: '技能', en: 'Skills' },
|