@admin-layout/ai-chat-ext-browser 12.2.4-alpha.66
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/LICENSE +21 -0
- package/lib/components/ChatSettingsPanel/ChatSettingsPanel.d.ts +39 -0
- package/lib/components/ChatSettingsPanel/ChatSettingsPanel.d.ts.map +1 -0
- package/lib/components/ChatSettingsPanel/ChatSettingsPanel.js +1191 -0
- package/lib/components/ChatSettingsPanel/ChatSettingsPanel.js.map +1 -0
- package/lib/components/ChatSettingsPanel/ConnectedChatSettingsPanel.d.ts +19 -0
- package/lib/components/ChatSettingsPanel/ConnectedChatSettingsPanel.d.ts.map +1 -0
- package/lib/components/ChatSettingsPanel/ConnectedChatSettingsPanel.js +83 -0
- package/lib/components/ChatSettingsPanel/ConnectedChatSettingsPanel.js.map +1 -0
- package/lib/components/ChatSettingsPanel/index.d.ts +5 -0
- package/lib/components/ChatSettingsPanel/index.d.ts.map +1 -0
- package/lib/components/MessageWidgets/MessageAiAssistant.d.ts +13 -0
- package/lib/components/MessageWidgets/MessageAiAssistant.d.ts.map +1 -0
- package/lib/components/MessageWidgets/MessageAiAssistant.js +79 -0
- package/lib/components/MessageWidgets/MessageAiAssistant.js.map +1 -0
- package/lib/components/MessageWidgets/MessageCodeBlock.d.ts +14 -0
- package/lib/components/MessageWidgets/MessageCodeBlock.d.ts.map +1 -0
- package/lib/components/MessageWidgets/MessageCodeBlock.js +78 -0
- package/lib/components/MessageWidgets/MessageCodeBlock.js.map +1 -0
- package/lib/components/MessageWidgets/MessageService.d.ts +13 -0
- package/lib/components/MessageWidgets/MessageService.d.ts.map +1 -0
- package/lib/components/MessageWidgets/MessageService.js +74 -0
- package/lib/components/MessageWidgets/MessageService.js.map +1 -0
- package/lib/components/MessageWidgets/MessageThinking.d.ts +13 -0
- package/lib/components/MessageWidgets/MessageThinking.d.ts.map +1 -0
- package/lib/components/MessageWidgets/MessageThinking.js +41 -0
- package/lib/components/MessageWidgets/MessageThinking.js.map +1 -0
- package/lib/components/MessageWidgets/MessageToolUse.d.ts +14 -0
- package/lib/components/MessageWidgets/MessageToolUse.d.ts.map +1 -0
- package/lib/components/MessageWidgets/MessageToolUse.js +92 -0
- package/lib/components/MessageWidgets/MessageToolUse.js.map +1 -0
- package/lib/components/MessageWidgets/index.d.ts +11 -0
- package/lib/components/MessageWidgets/index.d.ts.map +1 -0
- package/lib/components/index.d.ts +4 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces/ai-chat.interface.d.ts +80 -0
- package/lib/interfaces/ai-chat.interface.d.ts.map +1 -0
- package/lib/interfaces/index.d.ts +2 -0
- package/lib/interfaces/index.d.ts.map +1 -0
- package/lib/module.d.ts +3 -0
- package/lib/module.d.ts.map +1 -0
- package/lib/module.js +21 -0
- package/lib/module.js.map +1 -0
- package/lib/routes.json +1 -0
- package/lib/slot-fill/chat-settings-fill.d.ts +3 -0
- package/lib/slot-fill/chat-settings-fill.d.ts.map +1 -0
- package/lib/slot-fill/chat-settings-fill.js +22 -0
- package/lib/slot-fill/chat-settings-fill.js.map +1 -0
- package/lib/slot-fill/index.d.ts +7 -0
- package/lib/slot-fill/index.d.ts.map +1 -0
- package/lib/slot-fill/message-ai-assistant-fill.d.ts +3 -0
- package/lib/slot-fill/message-ai-assistant-fill.d.ts.map +1 -0
- package/lib/slot-fill/message-ai-assistant-fill.js +12 -0
- package/lib/slot-fill/message-ai-assistant-fill.js.map +1 -0
- package/lib/slot-fill/message-codeblock-fill.d.ts +3 -0
- package/lib/slot-fill/message-codeblock-fill.d.ts.map +1 -0
- package/lib/slot-fill/message-codeblock-fill.js +18 -0
- package/lib/slot-fill/message-codeblock-fill.js.map +1 -0
- package/lib/slot-fill/message-service-fill.d.ts +3 -0
- package/lib/slot-fill/message-service-fill.d.ts.map +1 -0
- package/lib/slot-fill/message-service-fill.js +12 -0
- package/lib/slot-fill/message-service-fill.js.map +1 -0
- package/lib/slot-fill/message-thinking-fill.d.ts +3 -0
- package/lib/slot-fill/message-thinking-fill.d.ts.map +1 -0
- package/lib/slot-fill/message-thinking-fill.js +18 -0
- package/lib/slot-fill/message-thinking-fill.js.map +1 -0
- package/lib/slot-fill/message-tooluse-fill.d.ts +3 -0
- package/lib/slot-fill/message-tooluse-fill.d.ts.map +1 -0
- package/lib/slot-fill/message-tooluse-fill.js +18 -0
- package/lib/slot-fill/message-tooluse-fill.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,1191 @@
|
|
|
1
|
+
import React,{useState,useMemo,useCallback,useEffect}from'react';import {FiSearch}from'@react-icons/all-files/fi/FiSearch.js';import {FiX}from'@react-icons/all-files/fi/FiX.js';import {FiRefreshCw}from'@react-icons/all-files/fi/FiRefreshCw.js';import {FiChevronDown}from'@react-icons/all-files/fi/FiChevronDown.js';import {FiEdit2}from'@react-icons/all-files/fi/FiEdit2.js';import {FiPlus}from'@react-icons/all-files/fi/FiPlus.js';import {FiTrash2}from'@react-icons/all-files/fi/FiTrash2.js';/**
|
|
2
|
+
* ChatSettingsPanel — VS Code–style settings UI for the messenger inbox.
|
|
3
|
+
*
|
|
4
|
+
* Renders all ChatConfiguration entries as grouped toggle/input controls
|
|
5
|
+
* with search filtering. Reads/writes via the `useChatConfiguration` hook
|
|
6
|
+
* (GraphQL backed) or a lightweight localStorage fallback for offline use.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <ChatSettingsPanel /> // standalone
|
|
10
|
+
* <ChatSettingsPanel channelId="xyz" /> // channel-scoped overrides
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Pre-defined groups that mirror VS Code's settingsLayout.ts
|
|
14
|
+
* (chat/agent, chat/appearance, chat/sessions, chat/tools, chat/mcp, chat/context, chat/inlineChat, chat/miscellaneous).
|
|
15
|
+
*/
|
|
16
|
+
const SETTINGS_GROUPS = [{
|
|
17
|
+
id: 'agent',
|
|
18
|
+
label: 'Agent',
|
|
19
|
+
icon: '🤖',
|
|
20
|
+
keys: ['chat.agent.enabled', 'chat.agent.maxRequests', 'chat.planAgent.defaultModel', 'chat.exploreAgent.defaultModel', 'chat.requestQueuing.defaultAction', 'chat.agentsControl.enabled', 'chat.agentSessionProjection.enabled', 'chat.customAgentInSubagent.enabled', 'chat.exitAfterDelegation', 'chat.checkpoints.enabled', 'chat.checkpoints.showFileChanges', 'chat.editRequests', 'chat.undoRequests.restoreInput', 'chat.editing.autoAcceptDelay', 'chat.editing.confirmEditRequestRemoval', 'chat.editing.confirmEditRequestRetry', 'chat.editing.explainChanges.enabled']
|
|
21
|
+
}, {
|
|
22
|
+
id: 'appearance',
|
|
23
|
+
label: 'Appearance',
|
|
24
|
+
icon: '🎨',
|
|
25
|
+
keys: ['chat.fontSize', 'chat.fontFamily', 'chat.editor.fontSize', 'chat.editor.fontFamily', 'chat.editor.fontWeight', 'chat.editor.wordWrap', 'chat.editor.lineHeight', 'chat.math.enabled', 'chat.inlineReferences.style', 'chat.agent.codeBlockProgress', 'chat.unifiedAgentsBar.enabled', 'chat.agentsControl.clickBehavior', 'chat.tips.enabled', 'chat.upvoteAnimation', 'chat.notifyWindowOnConfirmation', 'chat.notifyWindowOnResponseReceived', 'chat.growthNotification.enabled']
|
|
26
|
+
}, {
|
|
27
|
+
id: 'thinking',
|
|
28
|
+
label: 'Thinking',
|
|
29
|
+
icon: '🧠',
|
|
30
|
+
keys: ['chat.agent.thinkingStyle', 'chat.agent.thinking.generateTitles', 'chat.agent.thinking.collapsedTools', 'chat.agent.thinking.terminalTools', 'chat.agent.thinking.phrases']
|
|
31
|
+
}, {
|
|
32
|
+
id: 'sessions',
|
|
33
|
+
label: 'Sessions',
|
|
34
|
+
icon: '📋',
|
|
35
|
+
keys: ['chat.viewSessions.enabled', 'chat.viewSessions.grouping', 'chat.viewSessions.orientation', 'chat.viewProgressBadge.enabled', 'chat.restoreLastPanelSession']
|
|
36
|
+
}, {
|
|
37
|
+
id: 'tools',
|
|
38
|
+
label: 'Tools',
|
|
39
|
+
icon: '🔧',
|
|
40
|
+
keys: ['chat.extensionTools.enabled', 'chat.tools.usagesTool.enabled', 'chat.tools.renameTool.enabled', 'chat.tools.todos.showWidget', 'chat.tools.terminal.simpleCollapsible', 'chat.tools.autoExpandFailures', 'chat.edits2.enabled', 'chat.repoInfo.enabled']
|
|
41
|
+
}, {
|
|
42
|
+
id: 'autoapprove',
|
|
43
|
+
label: 'Auto-approve',
|
|
44
|
+
icon: '✅',
|
|
45
|
+
keys: ['chat.autoReply', 'chat.tools.global.autoApprove', 'chat.tools.edits.autoApprove', 'chat.tools.urls.autoApprove', 'chat.tools.eligibleForAutoApproval']
|
|
46
|
+
}, {
|
|
47
|
+
id: 'mcp',
|
|
48
|
+
label: 'MCP',
|
|
49
|
+
icon: '🔌',
|
|
50
|
+
keys: ['chat.mcp.access', 'chat.mcp.autostart', 'chat.mcp.apps.enabled', 'chat.mcp.serverSampling', 'chat.mcp.discovery.enabled', 'chat.mcp.gallery.enabled', 'chat.mcp.gallery.serviceUrl']
|
|
51
|
+
}, {
|
|
52
|
+
id: 'context',
|
|
53
|
+
label: 'Context',
|
|
54
|
+
icon: '📎',
|
|
55
|
+
keys: ['chat.detectParticipant.enabled', 'chat.implicitContext.enabled', 'chat.implicitContext.suggestedContext', 'chat.contextUsage.enabled', 'chat.sendElementsToChat.enabled', 'chat.sendElementsToChat.attachCSS', 'chat.sendElementsToChat.attachImages', 'chat.instructionsFilesLocations', 'chat.promptFilesLocations', 'chat.agentFilesLocations', 'chat.agentSkillsLocations', 'chat.hookFilesLocations', 'chat.promptFilesRecommendations', 'chat.useAgentsMdFile', 'chat.useNestedAgentsMdFiles', 'chat.useClaudeMdFile', 'chat.useAgentSkills', 'chat.useSkillAdherencePrompt', 'chat.includeApplyingInstructions', 'chat.includeReferencedInstructions', 'chat.useHooks', 'chat.useClaudeHooks', 'chat.modeFilesLocations']
|
|
56
|
+
}, {
|
|
57
|
+
id: 'inlineChat',
|
|
58
|
+
label: 'Inline Chat',
|
|
59
|
+
icon: '💬',
|
|
60
|
+
keys: ['inlineChat.finishOnType', 'inlineChat.holdToSpeech', 'inlineChat.enableV2', 'inlineChat.defaultModel', 'inlineChat.notebookAgent', 'inlineChat.affordance', 'inlineChat.renderMode', 'inlineChat.fixDiagnostics']
|
|
61
|
+
}, {
|
|
62
|
+
id: 'terminalTools',
|
|
63
|
+
label: 'Terminal Tools',
|
|
64
|
+
icon: '🖥️',
|
|
65
|
+
keys: ['chat.tools.terminal.enableAutoApprove', 'chat.tools.terminal.autoApprove', 'chat.tools.terminal.autoApproveWorkspaceNpmScripts', 'chat.tools.terminal.ignoreDefaultAutoApproveRules', 'chat.tools.terminal.blockDetectedFileWrites', 'chat.tools.terminal.shellIntegrationTimeout', 'chat.tools.terminal.autoReplyToPrompts', 'chat.tools.terminal.outputLocation', 'chat.tools.terminal.sandbox.enabled', 'chat.tools.terminal.sandbox.network', 'chat.tools.terminal.sandbox.linuxFileSystem', 'chat.tools.terminal.sandbox.macFileSystem', 'chat.tools.terminal.preventShellHistory', 'chat.tools.terminal.enforceTimeoutFromModel', 'chat.tools.terminal.terminalProfile.linux', 'chat.tools.terminal.terminalProfile.osx', 'chat.tools.terminal.terminalProfile.windows']
|
|
66
|
+
}, {
|
|
67
|
+
id: 'editor',
|
|
68
|
+
label: 'Editor / Edit Mode',
|
|
69
|
+
icon: '✏️',
|
|
70
|
+
keys: ['chat.editorAssociations', 'chat.editMode.hidden']
|
|
71
|
+
}, {
|
|
72
|
+
id: 'miscellaneous',
|
|
73
|
+
label: 'Miscellaneous',
|
|
74
|
+
icon: '⚙️',
|
|
75
|
+
keys: ['chat.disableAIFeatures', 'chat.allowAnonymousAccess', 'chat.extensionUnification.enabled', 'chat.statusWidget.anonymous', 'chat.plugins.enabled', 'chat.plugins.paths', 'chat.plugins.marketplaces', 'chat.customizationsMenu.enabled', 'chat.customizationsMenu.userStoragePath']
|
|
76
|
+
}];
|
|
77
|
+
/** Fallback built-in metadata. Defaults/types aligned with VS Code main branch. */
|
|
78
|
+
const BUILT_IN_DEFAULTS = {
|
|
79
|
+
// ── Core / Miscellaneous ────────────────────────────────────────
|
|
80
|
+
'chat.disableAIFeatures': {
|
|
81
|
+
default: false,
|
|
82
|
+
type: 'boolean',
|
|
83
|
+
description: 'Disable and hide built-in AI features provided by GitHub Copilot, including chat and inline suggestions'
|
|
84
|
+
},
|
|
85
|
+
'chat.allowAnonymousAccess': {
|
|
86
|
+
default: false,
|
|
87
|
+
type: 'boolean',
|
|
88
|
+
description: 'Controls whether anonymous access is allowed in chat'
|
|
89
|
+
},
|
|
90
|
+
'chat.plugins.enabled': {
|
|
91
|
+
default: true,
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
description: 'Enable agent plugin integration in chat'
|
|
94
|
+
},
|
|
95
|
+
'chat.plugins.paths': {
|
|
96
|
+
default: {},
|
|
97
|
+
type: 'object',
|
|
98
|
+
description: 'Plugin directories to discover (path → enabled)'
|
|
99
|
+
},
|
|
100
|
+
'chat.plugins.marketplaces': {
|
|
101
|
+
default: ['github/copilot-plugins', 'github/awesome-copilot'],
|
|
102
|
+
type: 'array',
|
|
103
|
+
description: 'Plugin marketplaces to query'
|
|
104
|
+
},
|
|
105
|
+
'chat.extensionUnification.enabled': {
|
|
106
|
+
default: true,
|
|
107
|
+
type: 'boolean',
|
|
108
|
+
description: 'Enables the unification of GitHub Copilot extensions'
|
|
109
|
+
},
|
|
110
|
+
'chat.statusWidget.anonymous': {
|
|
111
|
+
default: false,
|
|
112
|
+
type: 'boolean',
|
|
113
|
+
description: 'Show status widget for anonymous users when rate limited'
|
|
114
|
+
},
|
|
115
|
+
// ── Agent ───────────────────────────────────────────────────────
|
|
116
|
+
'chat.agent.enabled': {
|
|
117
|
+
default: true,
|
|
118
|
+
type: 'boolean',
|
|
119
|
+
description: 'When enabled, agent mode can be activated from chat and tools with side effects can be used'
|
|
120
|
+
},
|
|
121
|
+
'chat.agent.maxRequests': {
|
|
122
|
+
default: 50,
|
|
123
|
+
type: 'number',
|
|
124
|
+
description: 'Maximum requests per-turn when using an agent. When reached, asks to continue'
|
|
125
|
+
},
|
|
126
|
+
'chat.planAgent.defaultModel': {
|
|
127
|
+
default: '',
|
|
128
|
+
type: 'string',
|
|
129
|
+
description: 'Default language model for the Plan agent'
|
|
130
|
+
},
|
|
131
|
+
'chat.exploreAgent.defaultModel': {
|
|
132
|
+
default: '',
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'Default language model for the Explore subagent'
|
|
135
|
+
},
|
|
136
|
+
'chat.requestQueuing.defaultAction': {
|
|
137
|
+
default: 'steer',
|
|
138
|
+
type: 'string',
|
|
139
|
+
description: 'Default action for the queue button when a request is in progress'
|
|
140
|
+
},
|
|
141
|
+
'chat.agentsControl.enabled': {
|
|
142
|
+
default: true,
|
|
143
|
+
type: 'boolean',
|
|
144
|
+
description: 'Show the Agent Status indicator in the title bar command center'
|
|
145
|
+
},
|
|
146
|
+
'chat.agentSessionProjection.enabled': {
|
|
147
|
+
default: false,
|
|
148
|
+
type: 'boolean',
|
|
149
|
+
description: 'Enable Agent Session Projection mode for reviewing sessions in a focused workspace'
|
|
150
|
+
},
|
|
151
|
+
'chat.customAgentInSubagent.enabled': {
|
|
152
|
+
default: true,
|
|
153
|
+
type: 'boolean',
|
|
154
|
+
description: 'Whether the runSubagent tool is able to use custom agents'
|
|
155
|
+
},
|
|
156
|
+
'chat.exitAfterDelegation': {
|
|
157
|
+
default: false,
|
|
158
|
+
type: 'boolean',
|
|
159
|
+
description: 'Automatically exit the chat panel after delegating to another session'
|
|
160
|
+
},
|
|
161
|
+
// ── Editor / Edit Mode ──────────────────────────────────────────
|
|
162
|
+
'chat.editorAssociations': {
|
|
163
|
+
default: {},
|
|
164
|
+
type: 'object',
|
|
165
|
+
description: 'Configure glob patterns to editors for opening files from chat'
|
|
166
|
+
},
|
|
167
|
+
'chat.editMode.hidden': {
|
|
168
|
+
default: true,
|
|
169
|
+
type: 'boolean',
|
|
170
|
+
description: 'When enabled, hides the Edit mode from the chat mode picker'
|
|
171
|
+
},
|
|
172
|
+
'chat.edits2.enabled': {
|
|
173
|
+
default: false,
|
|
174
|
+
type: 'boolean',
|
|
175
|
+
description: 'Enable the new Edits mode based on tool-calling'
|
|
176
|
+
},
|
|
177
|
+
'chat.editRequests': {
|
|
178
|
+
default: 'inline',
|
|
179
|
+
type: 'string',
|
|
180
|
+
description: 'Enables editing of requests in the chat. Allows changing request content and resubmitting'
|
|
181
|
+
},
|
|
182
|
+
'chat.editing.autoAcceptDelay': {
|
|
183
|
+
default: 0,
|
|
184
|
+
type: 'number',
|
|
185
|
+
description: 'Delay (seconds, 0–100) after which changes made by chat are automatically accepted. 0 = disabled'
|
|
186
|
+
},
|
|
187
|
+
'chat.editing.confirmEditRequestRemoval': {
|
|
188
|
+
default: true,
|
|
189
|
+
type: 'boolean',
|
|
190
|
+
description: 'Show a confirmation before removing a request and its associated edits'
|
|
191
|
+
},
|
|
192
|
+
'chat.editing.confirmEditRequestRetry': {
|
|
193
|
+
default: true,
|
|
194
|
+
type: 'boolean',
|
|
195
|
+
description: 'Show a confirmation before retrying a request and its associated edits'
|
|
196
|
+
},
|
|
197
|
+
'chat.editing.explainChanges.enabled': {
|
|
198
|
+
default: false,
|
|
199
|
+
type: 'boolean',
|
|
200
|
+
description: 'Show the Explain button in the Chat panel and the Explain Changes context menu in the SCM view'
|
|
201
|
+
},
|
|
202
|
+
// ── Appearance / UI ─────────────────────────────────────────────
|
|
203
|
+
'chat.fontSize': {
|
|
204
|
+
default: 13,
|
|
205
|
+
type: 'number',
|
|
206
|
+
description: 'Controls the font size in pixels in chat messages'
|
|
207
|
+
},
|
|
208
|
+
'chat.fontFamily': {
|
|
209
|
+
default: 'default',
|
|
210
|
+
type: 'string',
|
|
211
|
+
description: 'Controls the font family in chat messages'
|
|
212
|
+
},
|
|
213
|
+
'chat.editor.fontSize': {
|
|
214
|
+
default: 14,
|
|
215
|
+
type: 'number',
|
|
216
|
+
description: 'Controls the font size in pixels in chat codeblocks'
|
|
217
|
+
},
|
|
218
|
+
'chat.editor.fontFamily': {
|
|
219
|
+
default: 'default',
|
|
220
|
+
type: 'string',
|
|
221
|
+
description: 'Controls the font family in chat codeblocks'
|
|
222
|
+
},
|
|
223
|
+
'chat.editor.fontWeight': {
|
|
224
|
+
default: 'default',
|
|
225
|
+
type: 'string',
|
|
226
|
+
description: 'Controls the font weight in chat codeblocks'
|
|
227
|
+
},
|
|
228
|
+
'chat.editor.wordWrap': {
|
|
229
|
+
default: 'off',
|
|
230
|
+
type: 'string',
|
|
231
|
+
description: 'Controls whether lines should wrap in chat codeblocks'
|
|
232
|
+
},
|
|
233
|
+
'chat.editor.lineHeight': {
|
|
234
|
+
default: 0,
|
|
235
|
+
type: 'number',
|
|
236
|
+
description: 'Controls the line height in pixels in chat codeblocks. Use 0 to compute from font size'
|
|
237
|
+
},
|
|
238
|
+
'chat.math.enabled': {
|
|
239
|
+
default: true,
|
|
240
|
+
type: 'boolean',
|
|
241
|
+
description: 'Enable math rendering in chat responses using KaTeX'
|
|
242
|
+
},
|
|
243
|
+
'chat.inlineReferences.style': {
|
|
244
|
+
default: 'box',
|
|
245
|
+
type: 'string',
|
|
246
|
+
description: 'How inline file/symbol references render in chat messages'
|
|
247
|
+
},
|
|
248
|
+
'chat.agent.codeBlockProgress': {
|
|
249
|
+
default: true,
|
|
250
|
+
type: 'boolean',
|
|
251
|
+
description: 'Show a progress animation in the code block pill when applying edits'
|
|
252
|
+
},
|
|
253
|
+
'chat.unifiedAgentsBar.enabled': {
|
|
254
|
+
default: false,
|
|
255
|
+
type: 'boolean',
|
|
256
|
+
description: 'Replaces the command center search box with a unified chat and search widget'
|
|
257
|
+
},
|
|
258
|
+
'chat.agentsControl.clickBehavior': {
|
|
259
|
+
default: 'default',
|
|
260
|
+
type: 'string',
|
|
261
|
+
description: 'Behaviour when clicking on the chat icon in the command center'
|
|
262
|
+
},
|
|
263
|
+
'chat.tips.enabled': {
|
|
264
|
+
default: false,
|
|
265
|
+
type: 'boolean',
|
|
266
|
+
description: 'Show tips above user messages in chat'
|
|
267
|
+
},
|
|
268
|
+
'chat.upvoteAnimation': {
|
|
269
|
+
default: 'floatingThumbs',
|
|
270
|
+
type: 'string',
|
|
271
|
+
description: 'Animation shown when clicking the thumbs up button on a chat response'
|
|
272
|
+
},
|
|
273
|
+
'chat.notifyWindowOnConfirmation': {
|
|
274
|
+
default: 'windowNotFocused',
|
|
275
|
+
type: 'string',
|
|
276
|
+
description: 'OS notification when a confirmation or question needs input'
|
|
277
|
+
},
|
|
278
|
+
'chat.notifyWindowOnResponseReceived': {
|
|
279
|
+
default: 'windowNotFocused',
|
|
280
|
+
type: 'string',
|
|
281
|
+
description: 'OS notification when a chat response is received'
|
|
282
|
+
},
|
|
283
|
+
'chat.growthNotification.enabled': {
|
|
284
|
+
default: false,
|
|
285
|
+
type: 'boolean',
|
|
286
|
+
description: 'Show growth notification to encourage new users to try Copilot'
|
|
287
|
+
},
|
|
288
|
+
'chat.restoreLastPanelSession': {
|
|
289
|
+
default: false,
|
|
290
|
+
type: 'boolean',
|
|
291
|
+
description: 'Restore the last session in panel after restart'
|
|
292
|
+
},
|
|
293
|
+
// ── Thinking ────────────────────────────────────────────────────
|
|
294
|
+
'chat.agent.thinkingStyle': {
|
|
295
|
+
default: 'fixedScrolling',
|
|
296
|
+
type: 'string',
|
|
297
|
+
description: 'How the model thinking output is displayed'
|
|
298
|
+
},
|
|
299
|
+
'chat.agent.thinking.generateTitles': {
|
|
300
|
+
default: true,
|
|
301
|
+
type: 'boolean',
|
|
302
|
+
description: 'Use an LLM to generate summary titles for thinking sections'
|
|
303
|
+
},
|
|
304
|
+
'chat.agent.thinking.collapsedTools': {
|
|
305
|
+
default: 'always',
|
|
306
|
+
type: 'string',
|
|
307
|
+
description: 'How tool calls are displayed in relation to thinking sections'
|
|
308
|
+
},
|
|
309
|
+
'chat.agent.thinking.terminalTools': {
|
|
310
|
+
default: true,
|
|
311
|
+
type: 'boolean',
|
|
312
|
+
description: 'Display terminal tool calls inside the thinking dropdown with a simplified view'
|
|
313
|
+
},
|
|
314
|
+
'chat.agent.thinking.phrases': {
|
|
315
|
+
default: {
|
|
316
|
+
mode: 'append',
|
|
317
|
+
phrases: []
|
|
318
|
+
},
|
|
319
|
+
type: 'object',
|
|
320
|
+
description: 'Customize loading messages shown during agent operations'
|
|
321
|
+
},
|
|
322
|
+
// ── Sessions ────────────────────────────────────────────────────
|
|
323
|
+
'chat.viewSessions.enabled': {
|
|
324
|
+
default: true,
|
|
325
|
+
type: 'boolean',
|
|
326
|
+
description: 'Show chat agent sessions when chat is empty or alongside when wide enough'
|
|
327
|
+
},
|
|
328
|
+
'chat.viewSessions.grouping': {
|
|
329
|
+
default: 'date',
|
|
330
|
+
type: 'string',
|
|
331
|
+
description: 'How sessions are grouped in the list'
|
|
332
|
+
},
|
|
333
|
+
'chat.viewSessions.orientation': {
|
|
334
|
+
default: 'sideBySide',
|
|
335
|
+
type: 'string',
|
|
336
|
+
description: 'Orientation of the chat agent sessions view'
|
|
337
|
+
},
|
|
338
|
+
'chat.viewProgressBadge.enabled': {
|
|
339
|
+
default: false,
|
|
340
|
+
type: 'boolean',
|
|
341
|
+
description: 'Show a progress badge on the chat view when an agent session is in progress'
|
|
342
|
+
},
|
|
343
|
+
// ── Tools ───────────────────────────────────────────────────────
|
|
344
|
+
'chat.extensionTools.enabled': {
|
|
345
|
+
default: true,
|
|
346
|
+
type: 'boolean',
|
|
347
|
+
description: 'Enable using tools contributed by third-party extensions'
|
|
348
|
+
},
|
|
349
|
+
'chat.tools.usagesTool.enabled': {
|
|
350
|
+
default: true,
|
|
351
|
+
type: 'boolean',
|
|
352
|
+
description: 'Enable the usages tool for finding references, definitions, and implementations'
|
|
353
|
+
},
|
|
354
|
+
'chat.tools.renameTool.enabled': {
|
|
355
|
+
default: true,
|
|
356
|
+
type: 'boolean',
|
|
357
|
+
description: 'Enable the rename tool for renaming code symbols across the workspace'
|
|
358
|
+
},
|
|
359
|
+
'chat.tools.todos.showWidget': {
|
|
360
|
+
default: true,
|
|
361
|
+
type: 'boolean',
|
|
362
|
+
description: 'Show the todo list widget above the chat input'
|
|
363
|
+
},
|
|
364
|
+
'chat.tools.terminal.simpleCollapsible': {
|
|
365
|
+
default: false,
|
|
366
|
+
type: 'boolean',
|
|
367
|
+
description: 'Use a simplified collapsible for terminal tool output'
|
|
368
|
+
},
|
|
369
|
+
'chat.tools.autoExpandFailures': {
|
|
370
|
+
default: true,
|
|
371
|
+
type: 'boolean',
|
|
372
|
+
description: 'Auto-expand tool result cards on failure'
|
|
373
|
+
},
|
|
374
|
+
'chat.repoInfo.enabled': {
|
|
375
|
+
default: false,
|
|
376
|
+
type: 'boolean',
|
|
377
|
+
description: 'Capture lightweight repository metadata when a chat request is submitted'
|
|
378
|
+
},
|
|
379
|
+
// ── Auto-approve ────────────────────────────────────────────────
|
|
380
|
+
'chat.autoReply': {
|
|
381
|
+
default: false,
|
|
382
|
+
type: 'boolean',
|
|
383
|
+
description: 'Automatically answer chat question carousels using the current model'
|
|
384
|
+
},
|
|
385
|
+
'chat.tools.global.autoApprove': {
|
|
386
|
+
default: false,
|
|
387
|
+
type: 'boolean',
|
|
388
|
+
description: 'Global auto-approve (YOLO mode) disables manual approval for all tools'
|
|
389
|
+
},
|
|
390
|
+
'chat.tools.edits.autoApprove': {
|
|
391
|
+
default: {},
|
|
392
|
+
type: 'object',
|
|
393
|
+
description: 'Controls auto-approval for edits. Glob patterns map to true/false'
|
|
394
|
+
},
|
|
395
|
+
'chat.tools.urls.autoApprove': {
|
|
396
|
+
default: {},
|
|
397
|
+
type: 'object',
|
|
398
|
+
description: 'Controls which URLs are automatically approved (URL pattern → true/false)'
|
|
399
|
+
},
|
|
400
|
+
'chat.tools.eligibleForAutoApproval': {
|
|
401
|
+
default: {},
|
|
402
|
+
type: 'object',
|
|
403
|
+
description: 'Controls which tools are eligible for automatic approval (tool → true/false)'
|
|
404
|
+
},
|
|
405
|
+
// ── Features ────────────────────────────────────────────────────
|
|
406
|
+
'chat.checkpoints.enabled': {
|
|
407
|
+
default: true,
|
|
408
|
+
type: 'boolean',
|
|
409
|
+
description: 'Enables checkpoints to restore chat to a previous state'
|
|
410
|
+
},
|
|
411
|
+
'chat.checkpoints.showFileChanges': {
|
|
412
|
+
default: false,
|
|
413
|
+
type: 'boolean',
|
|
414
|
+
description: 'Show file changes for chat checkpoints'
|
|
415
|
+
},
|
|
416
|
+
'chat.undoRequests.restoreInput': {
|
|
417
|
+
default: true,
|
|
418
|
+
type: 'boolean',
|
|
419
|
+
description: 'Restore chat input when an undo request is made'
|
|
420
|
+
},
|
|
421
|
+
// ── Context ─────────────────────────────────────────────────────
|
|
422
|
+
'chat.contextUsage.enabled': {
|
|
423
|
+
default: true,
|
|
424
|
+
type: 'boolean',
|
|
425
|
+
description: 'Show the context window usage indicator in the chat input'
|
|
426
|
+
},
|
|
427
|
+
'chat.detectParticipant.enabled': {
|
|
428
|
+
default: true,
|
|
429
|
+
type: 'boolean',
|
|
430
|
+
description: 'Enables chat participant autodetection for panel chat'
|
|
431
|
+
},
|
|
432
|
+
'chat.implicitContext.enabled': {
|
|
433
|
+
default: {
|
|
434
|
+
panel: 'always'
|
|
435
|
+
},
|
|
436
|
+
type: 'object',
|
|
437
|
+
description: 'Automatically use the active editor as chat context'
|
|
438
|
+
},
|
|
439
|
+
'chat.implicitContext.suggestedContext': {
|
|
440
|
+
default: true,
|
|
441
|
+
type: 'boolean',
|
|
442
|
+
description: 'Auto-include context in Ask/Edit modes; suggest as attachment in agent mode'
|
|
443
|
+
},
|
|
444
|
+
'chat.sendElementsToChat.enabled': {
|
|
445
|
+
default: true,
|
|
446
|
+
type: 'boolean',
|
|
447
|
+
description: 'Allow elements to be sent to chat from the Simple Browser'
|
|
448
|
+
},
|
|
449
|
+
'chat.sendElementsToChat.attachCSS': {
|
|
450
|
+
default: true,
|
|
451
|
+
type: 'boolean',
|
|
452
|
+
description: 'Attach CSS of the selected element to chat'
|
|
453
|
+
},
|
|
454
|
+
'chat.sendElementsToChat.attachImages': {
|
|
455
|
+
default: true,
|
|
456
|
+
type: 'boolean',
|
|
457
|
+
description: 'Attach a screenshot of the selected element to chat'
|
|
458
|
+
},
|
|
459
|
+
// ── Prompts / Instructions / Agents ─────────────────────────────
|
|
460
|
+
'chat.instructionsFilesLocations': {
|
|
461
|
+
default: {
|
|
462
|
+
'.github/instructions': true
|
|
463
|
+
},
|
|
464
|
+
type: 'object',
|
|
465
|
+
description: 'Locations of instructions files for Chat sessions'
|
|
466
|
+
},
|
|
467
|
+
'chat.promptFilesLocations': {
|
|
468
|
+
default: {
|
|
469
|
+
'.github/prompts': true
|
|
470
|
+
},
|
|
471
|
+
type: 'object',
|
|
472
|
+
description: 'Locations of reusable prompt files for Chat sessions'
|
|
473
|
+
},
|
|
474
|
+
'chat.modeFilesLocations': {
|
|
475
|
+
default: {
|
|
476
|
+
'.github/chatModes': true
|
|
477
|
+
},
|
|
478
|
+
type: 'object',
|
|
479
|
+
description: 'Locations of custom chat mode files (deprecated — now agents)'
|
|
480
|
+
},
|
|
481
|
+
'chat.agentFilesLocations': {
|
|
482
|
+
default: {
|
|
483
|
+
'.github/agents': true,
|
|
484
|
+
'.claude': true
|
|
485
|
+
},
|
|
486
|
+
type: 'object',
|
|
487
|
+
description: 'Locations of custom agent files'
|
|
488
|
+
},
|
|
489
|
+
'chat.agentSkillsLocations': {
|
|
490
|
+
default: {
|
|
491
|
+
'.github/skills': true
|
|
492
|
+
},
|
|
493
|
+
type: 'object',
|
|
494
|
+
description: 'Locations of agent skills (SKILL.md) for Chat sessions'
|
|
495
|
+
},
|
|
496
|
+
'chat.hookFilesLocations': {
|
|
497
|
+
default: {
|
|
498
|
+
'.github/hooks': true
|
|
499
|
+
},
|
|
500
|
+
type: 'object',
|
|
501
|
+
description: 'Paths to hook configuration files for agent workflow commands'
|
|
502
|
+
},
|
|
503
|
+
'chat.promptFilesRecommendations': {
|
|
504
|
+
default: {},
|
|
505
|
+
type: 'object',
|
|
506
|
+
description: 'Configure which prompt files to recommend in the chat welcome view'
|
|
507
|
+
},
|
|
508
|
+
'chat.useAgentsMdFile': {
|
|
509
|
+
default: true,
|
|
510
|
+
type: 'boolean',
|
|
511
|
+
description: 'Attach instructions from AGENTS.md found in workspace roots to all chat requests'
|
|
512
|
+
},
|
|
513
|
+
'chat.useNestedAgentsMdFiles': {
|
|
514
|
+
default: false,
|
|
515
|
+
type: 'boolean',
|
|
516
|
+
description: 'List instructions from nested AGENTS.md files found in the workspace'
|
|
517
|
+
},
|
|
518
|
+
'chat.useClaudeMdFile': {
|
|
519
|
+
default: true,
|
|
520
|
+
type: 'boolean',
|
|
521
|
+
description: 'Attach instructions from CLAUDE.md found in workspace roots or .claude / ~/.claude folder'
|
|
522
|
+
},
|
|
523
|
+
'chat.useAgentSkills': {
|
|
524
|
+
default: true,
|
|
525
|
+
type: 'boolean',
|
|
526
|
+
description: 'Provide skills as specialized capabilities to chat requests'
|
|
527
|
+
},
|
|
528
|
+
'chat.useSkillAdherencePrompt': {
|
|
529
|
+
default: false,
|
|
530
|
+
type: 'boolean',
|
|
531
|
+
description: 'Use a stronger skill adherence prompt that encourages immediate skill invocation'
|
|
532
|
+
},
|
|
533
|
+
'chat.includeApplyingInstructions': {
|
|
534
|
+
default: true,
|
|
535
|
+
type: 'boolean',
|
|
536
|
+
description: 'Auto-include instructions with a matching applyTo attribute in chat requests'
|
|
537
|
+
},
|
|
538
|
+
'chat.includeReferencedInstructions': {
|
|
539
|
+
default: false,
|
|
540
|
+
type: 'boolean',
|
|
541
|
+
description: 'Auto-include referenced instructions in chat requests'
|
|
542
|
+
},
|
|
543
|
+
'chat.useHooks': {
|
|
544
|
+
default: true,
|
|
545
|
+
type: 'boolean',
|
|
546
|
+
description: 'Execute chat hooks at strategic points during an agent workflow'
|
|
547
|
+
},
|
|
548
|
+
'chat.useClaudeHooks': {
|
|
549
|
+
default: false,
|
|
550
|
+
type: 'boolean',
|
|
551
|
+
description: 'Allow hooks from Claude configuration files to execute'
|
|
552
|
+
},
|
|
553
|
+
// ── MCP (Model Context Protocol) ────────────────────────────────
|
|
554
|
+
'chat.mcp.access': {
|
|
555
|
+
default: 'all',
|
|
556
|
+
type: 'string',
|
|
557
|
+
description: 'Controls access to installed Model Context Protocol servers'
|
|
558
|
+
},
|
|
559
|
+
'chat.mcp.autostart': {
|
|
560
|
+
default: 'newAndOutdated',
|
|
561
|
+
type: 'string',
|
|
562
|
+
description: 'Whether MCP servers auto-start when chat messages are submitted'
|
|
563
|
+
},
|
|
564
|
+
'chat.mcp.apps.enabled': {
|
|
565
|
+
default: true,
|
|
566
|
+
type: 'boolean',
|
|
567
|
+
description: 'Allow MCP servers to provide custom UI for tool invocations'
|
|
568
|
+
},
|
|
569
|
+
'chat.mcp.serverSampling': {
|
|
570
|
+
default: {},
|
|
571
|
+
type: 'object',
|
|
572
|
+
description: 'Configure which models are exposed to MCP servers for sampling'
|
|
573
|
+
},
|
|
574
|
+
'chat.mcp.discovery.enabled': {
|
|
575
|
+
default: {},
|
|
576
|
+
type: 'object',
|
|
577
|
+
description: 'Configure discovery of MCP servers from other applications'
|
|
578
|
+
},
|
|
579
|
+
'chat.mcp.gallery.enabled': {
|
|
580
|
+
default: false,
|
|
581
|
+
type: 'boolean',
|
|
582
|
+
description: 'Enable the default Marketplace for MCP servers'
|
|
583
|
+
},
|
|
584
|
+
'chat.mcp.gallery.serviceUrl': {
|
|
585
|
+
default: '',
|
|
586
|
+
type: 'string',
|
|
587
|
+
description: 'MCP Gallery service URL to connect to'
|
|
588
|
+
},
|
|
589
|
+
// ── Inline Chat ─────────────────────────────────────────────────
|
|
590
|
+
'inlineChat.finishOnType': {
|
|
591
|
+
default: false,
|
|
592
|
+
type: 'boolean',
|
|
593
|
+
description: 'Finish an inline chat session when typing outside of changed regions'
|
|
594
|
+
},
|
|
595
|
+
'inlineChat.holdToSpeech': {
|
|
596
|
+
default: true,
|
|
597
|
+
type: 'boolean',
|
|
598
|
+
description: 'Holding the inline chat keybinding automatically enables speech recognition'
|
|
599
|
+
},
|
|
600
|
+
'inlineChat.enableV2': {
|
|
601
|
+
default: false,
|
|
602
|
+
type: 'boolean',
|
|
603
|
+
description: 'Use the next version of inline chat'
|
|
604
|
+
},
|
|
605
|
+
'inlineChat.defaultModel': {
|
|
606
|
+
default: '',
|
|
607
|
+
type: 'string',
|
|
608
|
+
description: 'Default language model for inline chat'
|
|
609
|
+
},
|
|
610
|
+
'inlineChat.notebookAgent': {
|
|
611
|
+
default: false,
|
|
612
|
+
type: 'boolean',
|
|
613
|
+
description: 'Enable agent-like behavior for inline chat widget in notebooks'
|
|
614
|
+
},
|
|
615
|
+
'inlineChat.affordance': {
|
|
616
|
+
default: 'off',
|
|
617
|
+
type: 'string',
|
|
618
|
+
description: 'Controls whether an inline chat affordance is shown when text is selected'
|
|
619
|
+
},
|
|
620
|
+
'inlineChat.renderMode': {
|
|
621
|
+
default: 'zone',
|
|
622
|
+
type: 'string',
|
|
623
|
+
description: 'Controls how inline chat is rendered'
|
|
624
|
+
},
|
|
625
|
+
'inlineChat.fixDiagnostics': {
|
|
626
|
+
default: true,
|
|
627
|
+
type: 'boolean',
|
|
628
|
+
description: 'Controls whether the Fix action is shown for diagnostics in the editor'
|
|
629
|
+
},
|
|
630
|
+
// ── Terminal Chat Agent Tools ────────────────────────────────────
|
|
631
|
+
'chat.tools.terminal.enableAutoApprove': {
|
|
632
|
+
default: true,
|
|
633
|
+
type: 'boolean',
|
|
634
|
+
description: 'Controls whether to allow auto approval in the run in terminal tool'
|
|
635
|
+
},
|
|
636
|
+
'chat.tools.terminal.autoApprove': {
|
|
637
|
+
default: {},
|
|
638
|
+
type: 'object',
|
|
639
|
+
description: 'Commands/regex patterns controlling terminal tool auto-approval'
|
|
640
|
+
},
|
|
641
|
+
'chat.tools.terminal.autoApproveWorkspaceNpmScripts': {
|
|
642
|
+
default: true,
|
|
643
|
+
type: 'boolean',
|
|
644
|
+
description: 'Auto-approve npm/yarn/pnpm run commands for workspace scripts'
|
|
645
|
+
},
|
|
646
|
+
'chat.tools.terminal.ignoreDefaultAutoApproveRules': {
|
|
647
|
+
default: false,
|
|
648
|
+
type: 'boolean',
|
|
649
|
+
description: 'Ignore built-in default auto-approve rules'
|
|
650
|
+
},
|
|
651
|
+
'chat.tools.terminal.blockDetectedFileWrites': {
|
|
652
|
+
default: 'outsideWorkspace',
|
|
653
|
+
type: 'string',
|
|
654
|
+
description: 'Block detected file write operations in terminal tool'
|
|
655
|
+
},
|
|
656
|
+
'chat.tools.terminal.shellIntegrationTimeout': {
|
|
657
|
+
default: -1,
|
|
658
|
+
type: 'number',
|
|
659
|
+
description: 'Duration (ms) to wait for shell integration detection (-1 = auto)'
|
|
660
|
+
},
|
|
661
|
+
'chat.tools.terminal.autoReplyToPrompts': {
|
|
662
|
+
default: false,
|
|
663
|
+
type: 'boolean',
|
|
664
|
+
description: 'Auto-respond to terminal prompts (experimental, use at your own risk)'
|
|
665
|
+
},
|
|
666
|
+
'chat.tools.terminal.outputLocation': {
|
|
667
|
+
default: 'chat',
|
|
668
|
+
type: 'string',
|
|
669
|
+
description: 'Where to show run-in-terminal output'
|
|
670
|
+
},
|
|
671
|
+
'chat.tools.terminal.sandbox.enabled': {
|
|
672
|
+
default: false,
|
|
673
|
+
type: 'boolean',
|
|
674
|
+
description: 'Run commands in a sandboxed terminal'
|
|
675
|
+
},
|
|
676
|
+
'chat.tools.terminal.sandbox.network': {
|
|
677
|
+
default: {},
|
|
678
|
+
type: 'object',
|
|
679
|
+
description: 'Network access controls for the terminal sandbox'
|
|
680
|
+
},
|
|
681
|
+
'chat.tools.terminal.sandbox.linuxFileSystem': {
|
|
682
|
+
default: {},
|
|
683
|
+
type: 'object',
|
|
684
|
+
description: 'File system access controls for the terminal sandbox on Linux'
|
|
685
|
+
},
|
|
686
|
+
'chat.tools.terminal.sandbox.macFileSystem': {
|
|
687
|
+
default: {},
|
|
688
|
+
type: 'object',
|
|
689
|
+
description: 'File system access controls for the terminal sandbox on macOS'
|
|
690
|
+
},
|
|
691
|
+
'chat.tools.terminal.preventShellHistory': {
|
|
692
|
+
default: true,
|
|
693
|
+
type: 'boolean',
|
|
694
|
+
description: 'Exclude terminal tool commands from shell history'
|
|
695
|
+
},
|
|
696
|
+
'chat.tools.terminal.enforceTimeoutFromModel': {
|
|
697
|
+
default: true,
|
|
698
|
+
type: 'boolean',
|
|
699
|
+
description: 'Enforce the timeout value provided by the model'
|
|
700
|
+
},
|
|
701
|
+
'chat.tools.terminal.terminalProfile.linux': {
|
|
702
|
+
default: null,
|
|
703
|
+
type: 'object',
|
|
704
|
+
description: 'Terminal profile for Linux chat agent terminal tool'
|
|
705
|
+
},
|
|
706
|
+
'chat.tools.terminal.terminalProfile.osx': {
|
|
707
|
+
default: null,
|
|
708
|
+
type: 'object',
|
|
709
|
+
description: 'Terminal profile for macOS chat agent terminal tool'
|
|
710
|
+
},
|
|
711
|
+
'chat.tools.terminal.terminalProfile.windows': {
|
|
712
|
+
default: null,
|
|
713
|
+
type: 'object',
|
|
714
|
+
description: 'Terminal profile for Windows chat agent terminal tool'
|
|
715
|
+
},
|
|
716
|
+
// ── Customization ───────────────────────────────────────────────
|
|
717
|
+
'chat.customizationsMenu.enabled': {
|
|
718
|
+
default: true,
|
|
719
|
+
type: 'boolean',
|
|
720
|
+
description: 'Make the Chat Customizations editor available in the Command Palette'
|
|
721
|
+
},
|
|
722
|
+
'chat.customizationsMenu.userStoragePath': {
|
|
723
|
+
default: '',
|
|
724
|
+
type: 'string',
|
|
725
|
+
description: 'Override the base directory for user-level customization files'
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
/** Enum options for string-type settings. */
|
|
729
|
+
const ENUM_OPTIONS = {
|
|
730
|
+
'chat.requestQueuing.defaultAction': ['queue', 'steer'],
|
|
731
|
+
'chat.inlineReferences.style': ['box', 'link'],
|
|
732
|
+
'chat.agentsControl.clickBehavior': ['default', 'cycle'],
|
|
733
|
+
'chat.agent.thinkingStyle': ['collapsed', 'collapsedPreview', 'fixedScrolling'],
|
|
734
|
+
'chat.agent.thinking.collapsedTools': ['off', 'withThinking', 'always'],
|
|
735
|
+
'chat.notifyWindowOnConfirmation': ['off', 'windowNotFocused', 'always'],
|
|
736
|
+
'chat.notifyWindowOnResponseReceived': ['off', 'windowNotFocused', 'always'],
|
|
737
|
+
'chat.viewSessions.grouping': ['none', 'date', 'agent'],
|
|
738
|
+
'chat.viewSessions.orientation': ['stacked', 'sideBySide'],
|
|
739
|
+
'chat.upvoteAnimation': ['off', 'confetti', 'floatingThumbs', 'pulseWave', 'radiantLines'],
|
|
740
|
+
'chat.editRequests': ['inline', 'hover', 'input', 'none'],
|
|
741
|
+
'chat.editor.wordWrap': ['on', 'off'],
|
|
742
|
+
'chat.mcp.access': ['none', 'registry', 'all'],
|
|
743
|
+
'chat.mcp.autostart': ['never', 'onlyNew', 'newAndOutdated'],
|
|
744
|
+
'inlineChat.affordance': ['off', 'gutter', 'editor'],
|
|
745
|
+
'inlineChat.renderMode': ['zone', 'hover'],
|
|
746
|
+
'chat.tools.terminal.blockDetectedFileWrites': ['never', 'outsideWorkspace', 'all'],
|
|
747
|
+
'chat.tools.terminal.outputLocation': ['terminal', 'chat']
|
|
748
|
+
};
|
|
749
|
+
// ─── Subcomponents ──────────────────────────────────────────────────────────
|
|
750
|
+
/** Toggle switch for booleans. */
|
|
751
|
+
const Toggle = ({
|
|
752
|
+
checked,
|
|
753
|
+
onChange,
|
|
754
|
+
disabled
|
|
755
|
+
}) => React.createElement("button", {
|
|
756
|
+
role: "switch",
|
|
757
|
+
"aria-checked": checked,
|
|
758
|
+
disabled: disabled,
|
|
759
|
+
className: `
|
|
760
|
+
relative inline-flex h-5 w-9 items-center rounded-full transition-colors
|
|
761
|
+
${checked ? 'bg-blue-600' : 'bg-gray-300 dark:bg-gray-600'}
|
|
762
|
+
${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
|
|
763
|
+
`,
|
|
764
|
+
onClick: () => !disabled && onChange(!checked)
|
|
765
|
+
}, React.createElement("span", {
|
|
766
|
+
className: `
|
|
767
|
+
inline-block h-3.5 w-3.5 rounded-full bg-white shadow transition-transform
|
|
768
|
+
${checked ? 'translate-x-[18px]' : 'translate-x-[3px]'}
|
|
769
|
+
`
|
|
770
|
+
}));
|
|
771
|
+
/** Dropdown select for enum strings. */
|
|
772
|
+
const EnumSelect = ({
|
|
773
|
+
value,
|
|
774
|
+
options,
|
|
775
|
+
onChange
|
|
776
|
+
}) => React.createElement("select", {
|
|
777
|
+
value: value,
|
|
778
|
+
onChange: e => onChange(e.target.value),
|
|
779
|
+
className: "text-xs bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600\n rounded px-2 py-1 text-gray-700 dark:text-gray-300 focus:ring-1 focus:ring-blue-500\n focus:outline-none"
|
|
780
|
+
}, options.map(opt => React.createElement("option", {
|
|
781
|
+
key: opt,
|
|
782
|
+
value: opt
|
|
783
|
+
}, opt)));
|
|
784
|
+
/** Text input for strings. */
|
|
785
|
+
const TextInput = ({
|
|
786
|
+
value,
|
|
787
|
+
onChange,
|
|
788
|
+
placeholder
|
|
789
|
+
}) => React.createElement("input", {
|
|
790
|
+
type: "text",
|
|
791
|
+
value: value,
|
|
792
|
+
onChange: e => onChange(e.target.value),
|
|
793
|
+
placeholder: placeholder,
|
|
794
|
+
className: "text-xs bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600\n rounded px-2 py-1 w-full max-w-xs text-gray-700 dark:text-gray-300\n focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
795
|
+
});
|
|
796
|
+
/** Number input. */
|
|
797
|
+
const NumberInput = ({
|
|
798
|
+
value,
|
|
799
|
+
onChange
|
|
800
|
+
}) => React.createElement("input", {
|
|
801
|
+
type: "number",
|
|
802
|
+
value: value,
|
|
803
|
+
onChange: e => onChange(Number(e.target.value)),
|
|
804
|
+
className: "text-xs bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600\n rounded px-2 py-1 w-20 text-gray-700 dark:text-gray-300\n focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
805
|
+
});
|
|
806
|
+
/** Array tag editor (simplified). */
|
|
807
|
+
const ArrayInput = ({
|
|
808
|
+
value,
|
|
809
|
+
onChange,
|
|
810
|
+
placeholder
|
|
811
|
+
}) => {
|
|
812
|
+
const [input, setInput] = useState('');
|
|
813
|
+
const items = Array.isArray(value) ? value.map(String) : [];
|
|
814
|
+
const add = () => {
|
|
815
|
+
const trimmed = input.trim();
|
|
816
|
+
if (trimmed && !items.includes(trimmed)) {
|
|
817
|
+
onChange([...items, trimmed]);
|
|
818
|
+
setInput('');
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
return React.createElement("div", {
|
|
822
|
+
className: "flex flex-col gap-1 w-full max-w-xs"
|
|
823
|
+
}, React.createElement("div", {
|
|
824
|
+
className: "flex gap-1"
|
|
825
|
+
}, React.createElement("input", {
|
|
826
|
+
type: "text",
|
|
827
|
+
value: input,
|
|
828
|
+
onChange: e => setInput(e.target.value),
|
|
829
|
+
onKeyDown: e => e.key === 'Enter' && (e.preventDefault(), add()),
|
|
830
|
+
placeholder: placeholder || 'Add item...',
|
|
831
|
+
className: "text-xs bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600\n rounded px-2 py-1 flex-1 text-gray-700 dark:text-gray-300\n focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
832
|
+
}), React.createElement("button", {
|
|
833
|
+
onClick: add,
|
|
834
|
+
className: "text-xs px-2 py-1 rounded bg-blue-600 text-white hover:bg-blue-700 transition-colors"
|
|
835
|
+
}, "Add")), items.length > 0 && React.createElement("div", {
|
|
836
|
+
className: "flex flex-wrap gap-1"
|
|
837
|
+
}, items.map((item, i) => React.createElement("span", {
|
|
838
|
+
key: i,
|
|
839
|
+
className: "inline-flex items-center gap-1 text-[10px] bg-gray-200 dark:bg-gray-700\n text-gray-700 dark:text-gray-300 rounded px-1.5 py-0.5"
|
|
840
|
+
}, item, React.createElement("button", {
|
|
841
|
+
onClick: () => onChange(items.filter((_, j) => j !== i)),
|
|
842
|
+
className: "text-gray-400 hover:text-red-500"
|
|
843
|
+
}, "\u00D7")))));
|
|
844
|
+
};
|
|
845
|
+
/**
|
|
846
|
+
* Detects whether an object value is a simple Record<string, boolean> (most
|
|
847
|
+
* common pattern: path/glob → enabled). For these we show a friendly key–value
|
|
848
|
+
* pair editor. Everything else falls back to a JSON textarea.
|
|
849
|
+
*/
|
|
850
|
+
const isStringBooleanRecord = v => {
|
|
851
|
+
if (v === null || v === undefined || typeof v !== 'object' || Array.isArray(v)) return false;
|
|
852
|
+
return Object.values(v).every(val => typeof val === 'boolean');
|
|
853
|
+
};
|
|
854
|
+
/** Key–value pair editor for Record<string, boolean> objects. */
|
|
855
|
+
const KeyValueBoolEditor = ({
|
|
856
|
+
value,
|
|
857
|
+
onChange
|
|
858
|
+
}) => {
|
|
859
|
+
const [newKey, setNewKey] = useState('');
|
|
860
|
+
const entries = Object.entries(value);
|
|
861
|
+
const addEntry = () => {
|
|
862
|
+
const trimmed = newKey.trim();
|
|
863
|
+
if (trimmed && !(trimmed in value)) {
|
|
864
|
+
onChange({
|
|
865
|
+
...value,
|
|
866
|
+
[trimmed]: true
|
|
867
|
+
});
|
|
868
|
+
setNewKey('');
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
return React.createElement("div", {
|
|
872
|
+
className: "flex flex-col gap-1 w-full max-w-sm"
|
|
873
|
+
}, entries.map(([k, v]) => React.createElement("div", {
|
|
874
|
+
key: k,
|
|
875
|
+
className: "flex items-center gap-1.5 text-[11px]"
|
|
876
|
+
}, React.createElement("code", {
|
|
877
|
+
className: "flex-1 truncate text-gray-600 dark:text-gray-400 font-mono",
|
|
878
|
+
title: k
|
|
879
|
+
}, k), React.createElement(Toggle, {
|
|
880
|
+
checked: v,
|
|
881
|
+
onChange: checked => onChange({
|
|
882
|
+
...value,
|
|
883
|
+
[k]: checked
|
|
884
|
+
})
|
|
885
|
+
}), React.createElement("button", {
|
|
886
|
+
onClick: () => {
|
|
887
|
+
const next = {
|
|
888
|
+
...value
|
|
889
|
+
};
|
|
890
|
+
delete next[k];
|
|
891
|
+
onChange(next);
|
|
892
|
+
},
|
|
893
|
+
className: "p-0.5 rounded text-gray-400 hover:text-red-500 transition-colors",
|
|
894
|
+
title: "Remove entry"
|
|
895
|
+
}, React.createElement(FiTrash2, {
|
|
896
|
+
className: "w-3 h-3"
|
|
897
|
+
})))), React.createElement("div", {
|
|
898
|
+
className: "flex gap-1 mt-0.5"
|
|
899
|
+
}, React.createElement("input", {
|
|
900
|
+
type: "text",
|
|
901
|
+
value: newKey,
|
|
902
|
+
onChange: e => setNewKey(e.target.value),
|
|
903
|
+
onKeyDown: e => e.key === 'Enter' && (e.preventDefault(), addEntry()),
|
|
904
|
+
placeholder: "Add key\u2026",
|
|
905
|
+
className: "text-xs bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600\n rounded px-2 py-1 flex-1 text-gray-700 dark:text-gray-300\n focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
906
|
+
}), React.createElement("button", {
|
|
907
|
+
onClick: addEntry,
|
|
908
|
+
className: "p-1 rounded bg-blue-600 text-white hover:bg-blue-700 transition-colors",
|
|
909
|
+
title: "Add entry"
|
|
910
|
+
}, React.createElement(FiPlus, {
|
|
911
|
+
className: "w-3 h-3"
|
|
912
|
+
}))));
|
|
913
|
+
};
|
|
914
|
+
/** JSON textarea editor — fallback for complex / mixed-type objects. */
|
|
915
|
+
const JsonEditor = ({
|
|
916
|
+
value,
|
|
917
|
+
onChange
|
|
918
|
+
}) => {
|
|
919
|
+
const [text, setText] = useState(() => JSON.stringify(value, null, 2));
|
|
920
|
+
const [error, setError] = useState(null);
|
|
921
|
+
const [expanded, setExpanded] = useState(false);
|
|
922
|
+
// Sync when external value changes
|
|
923
|
+
useEffect(() => {
|
|
924
|
+
setText(JSON.stringify(value, null, 2));
|
|
925
|
+
setError(null);
|
|
926
|
+
}, [value]);
|
|
927
|
+
const handleBlur = () => {
|
|
928
|
+
try {
|
|
929
|
+
const parsed = JSON.parse(text);
|
|
930
|
+
setError(null);
|
|
931
|
+
onChange(parsed);
|
|
932
|
+
} catch {
|
|
933
|
+
setError('Invalid JSON');
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
if (!expanded) {
|
|
937
|
+
const preview = JSON.stringify(value);
|
|
938
|
+
const short = preview.length > 40 ? preview.slice(0, 37) + '…' : preview;
|
|
939
|
+
return React.createElement("button", {
|
|
940
|
+
onClick: () => setExpanded(true),
|
|
941
|
+
className: "inline-flex items-center gap-1 text-[11px] text-gray-500 dark:text-gray-400\n hover:text-blue-600 dark:hover:text-blue-400 transition-colors",
|
|
942
|
+
title: "Edit as JSON"
|
|
943
|
+
}, React.createElement(FiEdit2, {
|
|
944
|
+
className: "w-3 h-3"
|
|
945
|
+
}), React.createElement("code", {
|
|
946
|
+
className: "font-mono truncate max-w-[180px]"
|
|
947
|
+
}, short));
|
|
948
|
+
}
|
|
949
|
+
return React.createElement("div", {
|
|
950
|
+
className: "flex flex-col gap-1 w-full max-w-sm"
|
|
951
|
+
}, React.createElement("textarea", {
|
|
952
|
+
value: text,
|
|
953
|
+
onChange: e => {
|
|
954
|
+
setText(e.target.value);
|
|
955
|
+
setError(null);
|
|
956
|
+
},
|
|
957
|
+
onBlur: handleBlur,
|
|
958
|
+
rows: Math.min(Math.max(text.split('\n').length, 3), 10),
|
|
959
|
+
spellCheck: false,
|
|
960
|
+
className: `text-[11px] font-mono bg-white dark:bg-gray-800 border rounded
|
|
961
|
+
px-2 py-1.5 w-full text-gray-700 dark:text-gray-300
|
|
962
|
+
focus:ring-1 focus:outline-none resize-y
|
|
963
|
+
${error ? 'border-red-400 focus:ring-red-400' : 'border-gray-300 dark:border-gray-600 focus:ring-blue-500'}`
|
|
964
|
+
}), React.createElement("div", {
|
|
965
|
+
className: "flex items-center justify-between"
|
|
966
|
+
}, error && React.createElement("span", {
|
|
967
|
+
className: "text-[10px] text-red-500"
|
|
968
|
+
}, error), React.createElement("button", {
|
|
969
|
+
onClick: () => setExpanded(false),
|
|
970
|
+
className: "text-[10px] text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto"
|
|
971
|
+
}, "Collapse")));
|
|
972
|
+
};
|
|
973
|
+
/** Composite object editor — uses KeyValueBoolEditor for simple maps, JSON for complex ones. */
|
|
974
|
+
const ObjectEditor = ({
|
|
975
|
+
value,
|
|
976
|
+
onChange
|
|
977
|
+
}) => {
|
|
978
|
+
if (value === null || value === undefined || typeof value === 'object' && Object.keys(value).length === 0) {
|
|
979
|
+
// Empty object or null — show the JSON editor (compact "Edit" button)
|
|
980
|
+
return React.createElement(JsonEditor, {
|
|
981
|
+
value: value ?? {},
|
|
982
|
+
onChange: onChange
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
if (isStringBooleanRecord(value)) {
|
|
986
|
+
return React.createElement(KeyValueBoolEditor, {
|
|
987
|
+
value: value,
|
|
988
|
+
onChange: onChange
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
return React.createElement(JsonEditor, {
|
|
992
|
+
value: value,
|
|
993
|
+
onChange: onChange
|
|
994
|
+
});
|
|
995
|
+
};
|
|
996
|
+
// ─── Main Panel ─────────────────────────────────────────────────────────────
|
|
997
|
+
const ChatSettingsPanel = ({
|
|
998
|
+
entries: externalEntries,
|
|
999
|
+
channelId,
|
|
1000
|
+
onChange,
|
|
1001
|
+
onReset,
|
|
1002
|
+
loading = false,
|
|
1003
|
+
className = '',
|
|
1004
|
+
compact = false
|
|
1005
|
+
}) => {
|
|
1006
|
+
const [search, setSearch] = useState('');
|
|
1007
|
+
const [expandedGroups, setExpandedGroups] = useState(() => new Set(SETTINGS_GROUPS.map(g => g.id)));
|
|
1008
|
+
const [localOverrides, setLocalOverrides] = useState({});
|
|
1009
|
+
const [modifiedKeys, setModifiedKeys] = useState(new Set());
|
|
1010
|
+
// Merge external entries + built-in defaults
|
|
1011
|
+
const entryMap = useMemo(() => {
|
|
1012
|
+
const map = new Map();
|
|
1013
|
+
// Start with built-in defaults
|
|
1014
|
+
for (const [key, meta] of Object.entries(BUILT_IN_DEFAULTS)) {
|
|
1015
|
+
map.set(key, {
|
|
1016
|
+
key,
|
|
1017
|
+
value: meta.default,
|
|
1018
|
+
defaultValue: meta.default,
|
|
1019
|
+
valueType: meta.type,
|
|
1020
|
+
description: meta.description
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
// Overlay external entries (from GraphQL)
|
|
1024
|
+
if (externalEntries) {
|
|
1025
|
+
for (const entry of externalEntries) {
|
|
1026
|
+
map.set(entry.key, entry);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
// Overlay local overrides (unsaved changes)
|
|
1030
|
+
for (const [key, value] of Object.entries(localOverrides)) {
|
|
1031
|
+
const existing = map.get(key);
|
|
1032
|
+
if (existing) {
|
|
1033
|
+
map.set(key, {
|
|
1034
|
+
...existing,
|
|
1035
|
+
value
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return map;
|
|
1040
|
+
}, [externalEntries, localOverrides]);
|
|
1041
|
+
// Filter by search
|
|
1042
|
+
const matchesSearch = useCallback(entry => {
|
|
1043
|
+
if (!search) return true;
|
|
1044
|
+
const q = search.toLowerCase();
|
|
1045
|
+
return entry.key.toLowerCase().includes(q) || entry.description.toLowerCase().includes(q);
|
|
1046
|
+
}, [search]);
|
|
1047
|
+
// Toggle group expand/collapse
|
|
1048
|
+
const toggleGroup = useCallback(groupId => {
|
|
1049
|
+
setExpandedGroups(prev => {
|
|
1050
|
+
const next = new Set(prev);
|
|
1051
|
+
if (next.has(groupId)) next.delete(groupId);else next.add(groupId);
|
|
1052
|
+
return next;
|
|
1053
|
+
});
|
|
1054
|
+
}, []);
|
|
1055
|
+
// Handle value change
|
|
1056
|
+
const handleChange = useCallback((key, value) => {
|
|
1057
|
+
setLocalOverrides(prev => ({
|
|
1058
|
+
...prev,
|
|
1059
|
+
[key]: value
|
|
1060
|
+
}));
|
|
1061
|
+
setModifiedKeys(prev => new Set(prev).add(key));
|
|
1062
|
+
onChange?.(key, value);
|
|
1063
|
+
}, [onChange]);
|
|
1064
|
+
// Handle reset
|
|
1065
|
+
const handleReset = useCallback(key => {
|
|
1066
|
+
setLocalOverrides(prev => {
|
|
1067
|
+
const next = {
|
|
1068
|
+
...prev
|
|
1069
|
+
};
|
|
1070
|
+
delete next[key];
|
|
1071
|
+
return next;
|
|
1072
|
+
});
|
|
1073
|
+
setModifiedKeys(prev => {
|
|
1074
|
+
const next = new Set(prev);
|
|
1075
|
+
next.delete(key);
|
|
1076
|
+
return next;
|
|
1077
|
+
});
|
|
1078
|
+
onReset?.(key);
|
|
1079
|
+
}, [onReset]);
|
|
1080
|
+
// Render the control for a single setting
|
|
1081
|
+
const renderControl = useCallback(entry => {
|
|
1082
|
+
const isModified = modifiedKeys.has(entry.key);
|
|
1083
|
+
const isDefault = JSON.stringify(entry.value) === JSON.stringify(entry.defaultValue);
|
|
1084
|
+
const enumOpts = ENUM_OPTIONS[entry.key];
|
|
1085
|
+
return React.createElement("div", {
|
|
1086
|
+
key: entry.key,
|
|
1087
|
+
className: `
|
|
1088
|
+
flex flex-col gap-1 px-3 py-2.5
|
|
1089
|
+
${isModified ? 'bg-blue-50/50 dark:bg-blue-900/10' : ''}
|
|
1090
|
+
border-b border-gray-100 dark:border-gray-800 last:border-0
|
|
1091
|
+
`
|
|
1092
|
+
}, React.createElement("div", {
|
|
1093
|
+
className: "flex items-start justify-between gap-3"
|
|
1094
|
+
}, React.createElement("div", {
|
|
1095
|
+
className: "flex-1 min-w-0"
|
|
1096
|
+
}, React.createElement("div", {
|
|
1097
|
+
className: "flex items-center gap-1.5"
|
|
1098
|
+
}, React.createElement("code", {
|
|
1099
|
+
className: "text-xs font-mono text-gray-700 dark:text-gray-300 break-all"
|
|
1100
|
+
}, entry.key), !isDefault && React.createElement("span", {
|
|
1101
|
+
className: "text-[9px] px-1 py-0.5 rounded bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 font-medium"
|
|
1102
|
+
}, "Modified")), React.createElement("p", {
|
|
1103
|
+
className: "text-[11px] text-gray-500 dark:text-gray-400 mt-0.5 leading-relaxed"
|
|
1104
|
+
}, entry.description)), React.createElement("div", {
|
|
1105
|
+
className: "flex items-center gap-2 flex-shrink-0"
|
|
1106
|
+
}, entry.valueType === 'boolean' && React.createElement(Toggle, {
|
|
1107
|
+
checked: !!entry.value,
|
|
1108
|
+
onChange: v => handleChange(entry.key, v)
|
|
1109
|
+
}), entry.valueType === 'string' && enumOpts && React.createElement(EnumSelect, {
|
|
1110
|
+
value: String(entry.value ?? ''),
|
|
1111
|
+
options: enumOpts,
|
|
1112
|
+
onChange: v => handleChange(entry.key, v)
|
|
1113
|
+
}), entry.valueType === 'string' && !enumOpts && React.createElement(TextInput, {
|
|
1114
|
+
value: String(entry.value ?? ''),
|
|
1115
|
+
onChange: v => handleChange(entry.key, v),
|
|
1116
|
+
placeholder: String(entry.defaultValue ?? '')
|
|
1117
|
+
}), entry.valueType === 'number' && React.createElement(NumberInput, {
|
|
1118
|
+
value: Number(entry.value ?? 0),
|
|
1119
|
+
onChange: v => handleChange(entry.key, v)
|
|
1120
|
+
}), entry.valueType === 'array' && React.createElement(ArrayInput, {
|
|
1121
|
+
value: Array.isArray(entry.value) ? entry.value : [],
|
|
1122
|
+
onChange: v => handleChange(entry.key, v)
|
|
1123
|
+
}), entry.valueType === 'object' && React.createElement(ObjectEditor, {
|
|
1124
|
+
value: entry.value,
|
|
1125
|
+
onChange: v => handleChange(entry.key, v)
|
|
1126
|
+
}), !isDefault && React.createElement("button", {
|
|
1127
|
+
onClick: () => handleReset(entry.key),
|
|
1128
|
+
title: "Reset to default",
|
|
1129
|
+
className: "p-1 rounded hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
|
|
1130
|
+
}, React.createElement(FiRefreshCw, {
|
|
1131
|
+
className: "w-3 h-3"
|
|
1132
|
+
})))));
|
|
1133
|
+
}, [modifiedKeys, handleChange, handleReset]);
|
|
1134
|
+
return React.createElement("div", {
|
|
1135
|
+
className: `flex flex-col h-full bg-white dark:bg-gray-900 ${className}`
|
|
1136
|
+
}, React.createElement("div", {
|
|
1137
|
+
className: "flex items-center gap-2 px-4 py-3 border-b border-gray-200 dark:border-gray-700"
|
|
1138
|
+
}, React.createElement("span", {
|
|
1139
|
+
className: "text-sm font-semibold text-gray-800 dark:text-gray-200"
|
|
1140
|
+
}, "Chat Settings"), loading && React.createElement(FiRefreshCw, {
|
|
1141
|
+
className: "w-3.5 h-3.5 text-gray-400 animate-spin"
|
|
1142
|
+
}), React.createElement("span", {
|
|
1143
|
+
className: "ml-auto text-[10px] text-gray-400"
|
|
1144
|
+
}, entryMap.size, " settings")), React.createElement("div", {
|
|
1145
|
+
className: "px-3 py-2 border-b border-gray-200 dark:border-gray-700"
|
|
1146
|
+
}, React.createElement("div", {
|
|
1147
|
+
className: "relative"
|
|
1148
|
+
}, React.createElement(FiSearch, {
|
|
1149
|
+
className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-gray-400"
|
|
1150
|
+
}), React.createElement("input", {
|
|
1151
|
+
type: "text",
|
|
1152
|
+
value: search,
|
|
1153
|
+
onChange: e => setSearch(e.target.value),
|
|
1154
|
+
placeholder: "Search settings...",
|
|
1155
|
+
className: "w-full text-xs bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700\n rounded-md pl-8 pr-8 py-1.5 text-gray-700 dark:text-gray-300\n focus:ring-1 focus:ring-blue-500 focus:outline-none focus:bg-white dark:focus:bg-gray-900\n placeholder-gray-400"
|
|
1156
|
+
}), search && React.createElement("button", {
|
|
1157
|
+
onClick: () => setSearch(''),
|
|
1158
|
+
className: "absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
|
|
1159
|
+
}, React.createElement(FiX, {
|
|
1160
|
+
className: "w-3.5 h-3.5"
|
|
1161
|
+
})))), React.createElement("div", {
|
|
1162
|
+
className: "flex-1 overflow-y-auto"
|
|
1163
|
+
}, SETTINGS_GROUPS.map(group => {
|
|
1164
|
+
const groupEntries = group.keys.map(key => entryMap.get(key)).filter(e => !!e && matchesSearch(e));
|
|
1165
|
+
if (groupEntries.length === 0) return null;
|
|
1166
|
+
const isExpanded = expandedGroups.has(group.id);
|
|
1167
|
+
return React.createElement("div", {
|
|
1168
|
+
key: group.id,
|
|
1169
|
+
className: "border-b border-gray-200 dark:border-gray-700 last:border-0"
|
|
1170
|
+
}, React.createElement("button", {
|
|
1171
|
+
className: "flex items-center gap-2 w-full text-left px-4 py-2.5\n hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors",
|
|
1172
|
+
onClick: () => toggleGroup(group.id)
|
|
1173
|
+
}, React.createElement(FiChevronDown, {
|
|
1174
|
+
className: `w-3.5 h-3.5 text-gray-400 transition-transform ${isExpanded ? '' : '-rotate-90'}`
|
|
1175
|
+
}), React.createElement("span", {
|
|
1176
|
+
className: "text-sm"
|
|
1177
|
+
}, group.icon), React.createElement("span", {
|
|
1178
|
+
className: "text-xs font-semibold text-gray-700 dark:text-gray-300"
|
|
1179
|
+
}, group.label), React.createElement("span", {
|
|
1180
|
+
className: "ml-auto text-[10px] text-gray-400"
|
|
1181
|
+
}, groupEntries.length)), isExpanded && React.createElement("div", {
|
|
1182
|
+
className: "bg-gray-50/50 dark:bg-gray-800/20"
|
|
1183
|
+
}, groupEntries.map(renderControl)));
|
|
1184
|
+
}), search && SETTINGS_GROUPS.every(g => g.keys.map(k => entryMap.get(k)).filter(e => !!e && matchesSearch(e)).length === 0) && React.createElement("div", {
|
|
1185
|
+
className: "flex flex-col items-center justify-center py-12 text-gray-400"
|
|
1186
|
+
}, React.createElement(FiSearch, {
|
|
1187
|
+
className: "w-8 h-8 mb-2 opacity-50"
|
|
1188
|
+
}), React.createElement("p", {
|
|
1189
|
+
className: "text-sm"
|
|
1190
|
+
}, "No settings match \"", search, "\""))));
|
|
1191
|
+
};export{ChatSettingsPanel};//# sourceMappingURL=ChatSettingsPanel.js.map
|