dsh-composer-ux 0.2.0 → 0.3.0
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 +32 -0
- package/README.md +16 -3
- package/lib/client.js +621 -151
- package/lib/client.js.map +4 -4
- package/lib/index.js +321 -6
- package/lib/index.js.map +4 -4
- package/package.json +3 -3
package/lib/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/client.tsx", "../src/settings-contract.ts", "../src/client/chords.ts", "../src/client/quick-commands.ts", "../src/client/interceptors.ts", "../src/client/panel.ts", "../src/client/settings-style.ts", "../src/client/quick-style.ts", "../src/client/ContextMenuHost.tsx", "../src/client/styles.ts", "../src/client/PanelResizeHandles.tsx", "../src/client/SettingsSection.tsx", "../src/client/QuickCommandsButton.tsx", "../src/client/QuickCommandsPanel.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Browser half\uFF1A\u6CE8\u518C\u8BBE\u7F6E\u9875\uFF08settings.section\uFF09\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\u62D6\u62FD\n * \u624B\u67C4\uFF08shell.overlay\uFF09\uFF0C\u5E76\u5B89\u88C5\u8F93\u5165\u6846\u62E6\u622A\u5668\uFF08\u952E\u4F4D + \u53F3\u952E\u83DC\u5355\uFF09\u4E0E\u9762\u677F\n * \u6EDA\u52A8\u6837\u5F0F\u3002\n */\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n DEFAULT_SETTINGS, ENABLED_FIELD, HEADER_ENABLED_FIELD, HEADER_NAME_FIELD,\n HEADER_ROUTES_FIELD, HEADER_VALUE_FIELD, MENU_FIELDS, MENU_NATIVE_FIELD, NAMESPACE,\n NEWLINE_KEY_FIELD, OPTIMIZER_TIER_FIELD, PANEL_SCROLL_FIELD, PANEL_RESIZE_FIELD,\n PANEL_WIDTH_FIELD, PANEL_HEIGHT_FIELD, QUICK_PROMPTS_FIELD, SEND_KEY_FIELD, sanitizeSettings,\n type ComposerUxSettings, type MenuState, type OptimizerTier, type QuickPrompt,\n type SettingsField,\n} from './settings-contract.ts'\nimport { installInterceptors, runMenuAction } from './client/interceptors.ts'\nimport { installPanelStyle } from './client/panel.ts'\nimport { installSettingsCardStyle } from './client/settings-style.ts'\nimport { installQuickButtonStyle } from './client/quick-style.ts'\nimport { ContextMenuHost } from './client/ContextMenuHost.tsx'\nimport { PanelResizeHandles } from './client/PanelResizeHandles.tsx'\nimport { SettingsSection } from './client/SettingsSection.tsx'\nimport { QuickCommandsButton, type QuickPanelAnchor } from './client/QuickCommandsButton.tsx'\nimport { QuickCommandsPanel } from './client/QuickCommandsPanel.tsx'\nimport {\n focusComposer, insertIntoDraft, optimizeDraft, replaceDraft, currentDraft,\n} from './client/quick-commands.ts'\n\nexport const name = 'composer-ux'\nexport const inject = ['slots', 'settingsScope']\n\n/** \u5BA2\u6237\u7AEF\u63D2\u4EF6\u5165\u53E3\u3002 */\nexport function apply(ctx: any): void {\n const slots = ctx.slots\n const scope = ctx.settingsScope.bind<ComposerUxSettings>({ namespace: NAMESPACE })\n\n const live = createSnapshotStore<ComposerUxSettings>({ ...DEFAULT_SETTINGS })\n const menu = createSnapshotStore<MenuState | null>(null)\n const panel = createSnapshotStore<QuickPanelAnchor | null>(null)\n const optimizing = createSnapshotStore<boolean>(false)\n const panelNotice = createSnapshotStore<string>('')\n\n const sync = (): void => {\n const snapshot = scope.getSnapshot()\n live.set(snapshot.status === 'ready' && snapshot.value !== undefined\n ? { ...DEFAULT_SETTINGS, ...sanitizeSettings(snapshot.value) }\n : { ...DEFAULT_SETTINGS })\n }\n sync()\n ctx.effect(() => scope.subscribe(sync), 'composer-ux: settings sync')\n\n const setField = (field: SettingsField, value: unknown): void => {\n void scope.set(field, value as never).catch((error: unknown) => {\n console.error('[composer-ux] settings write failed', error)\n })\n }\n const clearField = (field: SettingsField): void => {\n void scope.unset(field).catch((error: unknown) => {\n console.error('[composer-ux] settings clear failed', error)\n })\n }\n const resetAll = (): void => {\n // \u6CE8\u610F\uFF1A\u5BBF\u4E3B\u534A\u7684\u8BB0\u8D26\u5B57\u6BB5\uFF08HOST_OWNED_FIELDS\uFF09\u6545\u610F\u4E0D\u5728\u540D\u5355\u91CC\u2014\u2014\u6E05\u6389\u5B83\u4EEC\u4F1A\u8BA9\n // \u5DF2\u7ECF\u5199\u5165 llm-pi-ai \u7684\u8BF7\u6C42\u5934\u5931\u53BB\u8BB0\u8D26\uFF0C\u4ECE\u800C\u6C38\u8FDC\u64A4\u9500\u4E0D\u6389\u3002\n void scope.mutate(\n [\n ENABLED_FIELD, SEND_KEY_FIELD, NEWLINE_KEY_FIELD, ...MENU_FIELDS,\n MENU_NATIVE_FIELD,\n PANEL_SCROLL_FIELD, PANEL_RESIZE_FIELD, PANEL_WIDTH_FIELD, PANEL_HEIGHT_FIELD,\n HEADER_ENABLED_FIELD, HEADER_NAME_FIELD, HEADER_VALUE_FIELD, HEADER_ROUTES_FIELD,\n QUICK_PROMPTS_FIELD, OPTIMIZER_TIER_FIELD,\n ].map(field => ({ op: 'unset', path: [field] })),\n ).catch((error: unknown) => {\n console.error('[composer-ux] settings reset failed', error)\n })\n }\n\n // \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\u4E0E\u63D0\u793A\u8BCD\u4F18\u5316 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \u9762\u677F\u5E95\u90E8\u7684\u77ED\u63D0\u793A\uFF1B\u5230\u65F6\u81EA\u52A8\u6D88\u5931\uFF08\u4E0E\u53F3\u952E\u83DC\u5355\u7684 note \u540C\u4E00\u5957\u8DEF\uFF09\u3002 */\n let noticeTimer: ReturnType<typeof setTimeout> | undefined\n const note = (message: string, ms = 4500): void => {\n panelNotice.set(message)\n if (noticeTimer !== undefined) clearTimeout(noticeTimer)\n if (message === '') return\n noticeTimer = setTimeout(() => { panelNotice.set('') }, ms)\n }\n ctx.effect(() => () => {\n if (noticeTimer !== undefined) clearTimeout(noticeTimer)\n }, 'composer-ux: quick notice timer')\n\n /** \u5199\u56DE\u6574\u4EFD\u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF08\u7F16\u8F91\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7528\uFF1B\u8BFB\u5F53\u524D\u503C\u518D\u6539\u4E00\u6761\uFF0C\u907F\u514D\u8986\u76D6\u5E76\u53D1\u7F16\u8F91\uFF09\u3002 */\n const writeQuickPrompts = (next: readonly QuickPrompt[]): void => {\n setField(QUICK_PROMPTS_FIELD, next)\n }\n\n const quickActions = {\n toggle: (anchor: { left: number; bottom: number; width: number }): void => {\n if (panel.getSnapshot() !== null) {\n panel.set(null)\n panelNotice.set('')\n return\n }\n panelNotice.set('')\n panel.set(anchor)\n },\n close: (): void => {\n panel.set(null)\n panelNotice.set('')\n },\n insert: (text: string): void => {\n if (insertIntoDraft(text)) focusComposer()\n },\n optimize: (): void => {\n if (optimizing.getSnapshot()) return\n const draft = currentDraft()\n if (draft.trim() === '') {\n note('\u8F93\u5165\u6846\u662F\u7A7A\u7684\uFF1A\u5148\u5199\u70B9\u4EC0\u4E48\uFF0C\u518D\u70B9\u4F18\u5316')\n return\n }\n optimizing.set(true)\n note('\u6B63\u5728\u4F18\u5316\u2026')\n void optimizeDraft(draft, live.getSnapshot().optimizerTier).then(\n (result) => {\n optimizing.set(false)\n if (!result.ok) {\n note(`\u4F18\u5316\u5931\u8D25\uFF1A${result.error ?? '\u672A\u77E5\u539F\u56E0'}`)\n return\n }\n replaceDraft(result.text ?? '')\n focusComposer()\n note(`\u5DF2\u5199\u56DE\u8F93\u5165\u6846\uFF08${result.route}\uFF09\u00B7 Ctrl+Z \u53EF\u8FD8\u539F`)\n },\n (error: unknown) => {\n optimizing.set(false)\n note(`\u4F18\u5316\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`)\n },\n )\n },\n setTier: (tier: OptimizerTier): void => { setField(OPTIMIZER_TIER_FIELD, tier) },\n setAlways: (id: string, value: boolean): void => {\n writeQuickPrompts(live.getSnapshot().quickPrompts.map(\n item => (item.id === id ? { ...item, always: value } : item),\n ))\n },\n }\n\n // \u8BBE\u7F6E\u9875\u6761\u76EE\u3002\n slots.inject('settings.section', () => slots.register({\n name: 'settings.section',\n id: 'composer-ux',\n order: 40,\n label: '\u8F93\u5165\u4F53\u9A8C',\n inject: () => ({\n hooks: { live },\n actions: { setField, clearField, resetAll },\n }),\n }, SettingsSection))\n\n // \u53F3\u952E\u83DC\u5355\u6D6E\u5C42\uFF08shell.overlay \u662F root \u7EA7 list \u69FD\uFF1B\u5149\u6807\u5C42\u672C\u8EAB\u70B9\u51FB\u7A7F\u900F\uFF0C\u83DC\u5355\u81EA\u8425 pointer-events\uFF09\u3002\n slots.inject('shell.overlay', () => slots.register({\n name: 'shell.overlay',\n id: 'composer-ux-menu',\n inject: () => ({\n hooks: { menu, live },\n actions: {\n run: runMenuAction,\n close: () => { menu.set(null) },\n note: (message: string | undefined) => {\n const current = menu.getSnapshot()\n if (current === null) return\n menu.set({ ...current, note: message })\n },\n },\n }),\n }, ContextMenuHost))\n\n // \u8BBE\u7F6E\u9762\u677F\u8FB9\u7F18\u62D6\u62FD\u624B\u67C4\u3002\n slots.inject('shell.overlay', () => slots.register({\n name: 'shell.overlay',\n id: 'composer-ux-panel-resize',\n inject: () => ({ hooks: { live }, actions: { setField } }),\n }, PanelResizeHandles))\n\n // \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\uFF1A\u4E0E\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\u540C\u6392\uFF08order 89 < \u5C55\u5F00\u7684 90\uFF09\u3002\n slots.inject('conversation.input.right', () => slots.register({\n name: 'conversation.input.right',\n id: 'composer-ux-quick',\n order: 89,\n label: '\u5FEB\u6377\u6307\u4EE4',\n inject: () => ({\n hooks: { live, panel },\n actions: { toggle: quickActions.toggle },\n }),\n }, QuickCommandsButton))\n\n // \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5C55\u5F00\u9762\u677F\uFF1A\u8D70 root \u7EA7\u6D6E\u5C42\uFF0C\u4E0D\u53D7\u8F93\u5165\u5361\u7247\u88C1\u526A\u3002\n slots.inject('shell.overlay', () => slots.register({\n name: 'shell.overlay',\n id: 'composer-ux-quick-panel',\n inject: () => ({\n hooks: { live, panel, busy: optimizing, notice: panelNotice },\n actions: quickActions,\n }),\n }, QuickCommandsPanel))\n\n // \u8BBE\u7F6E\u9875\u6298\u53E0\u5361\u7247\u6837\u5F0F\uFF08\u5E38\u9A7B\uFF1B\u53EA\u7BA1\u8BBE\u7F6E\u9875\u5916\u89C2\uFF0C\u4E0E\u603B\u5F00\u5173\u65E0\u5173\uFF09\u3002\n ctx.effect(() => installSettingsCardStyle(), 'composer-ux: settings card style')\n\n // \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\u6837\u5F0F\u8868\uFF08\u4E0E\u65C1\u8FB9\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\u9010\u9879\u5BF9\u9F50\uFF09\u3002\n ctx.effect(() => installQuickButtonStyle(), 'composer-ux: quick button style')\n\n // \u8BBE\u7F6E\u9762\u677F\u5BFC\u822A\u6EDA\u52A8\u6837\u5F0F\uFF08\u968F panelScroll \u5F00\u5173\u5207\u6362\uFF1B\u603B\u5F00\u5173\u5173\u95ED\u65F6\u4E00\u5E76\u505C\u7528\uFF09\u3002\n ctx.effect(\n () => installPanelStyle(\n () => {\n const settings = live.getSnapshot()\n return settings.enabled && settings.panelScroll\n },\n listener => live.subscribe(listener),\n ),\n 'composer-ux: panel style',\n )\n\n // \u952E\u4F4D\u62E6\u622A + \u53F3\u952E\u83DC\u5355\u6253\u5F00\uFF08\u53D7\u603B\u5F00\u5173\u63A7\u5236\uFF1A\u5173\u95ED\u65F6\u5378\u8F7D\u76D1\u542C\u5E76\u5173\u95ED\u5DF2\u5F00\u83DC\u5355\uFF09\u3002\n ctx.effect(() => {\n let dispose: (() => void) | null = null\n const syncInterceptors = (): void => {\n const enabled = live.getSnapshot().enabled\n if (enabled && dispose === null) {\n dispose = installInterceptors({\n settings: () => live.getSnapshot(),\n setMenu: state => { menu.set(state) },\n menuOpen: () => menu.getSnapshot() !== null,\n })\n } else if (!enabled) {\n dispose?.()\n dispose = null\n menu.set(null)\n panel.set(null)\n }\n // \u539F\u751F\u83DC\u5355\u6A21\u5F0F\u542F\u7528\u77AC\u95F4\uFF1A\u6E05\u6389\u53EF\u80FD\u8FD8\u5F00\u7740\u7684\u81EA\u5B9A\u4E49\u83DC\u5355\u3002\n if (live.getSnapshot().menuNative) menu.set(null)\n // \u603B\u5F00\u5173\u5173\u6389\u65F6\u6309\u94AE\u672C\u8EAB\u4E5F\u4F1A\u6D88\u5931\uFF08\u7EC4\u4EF6\u91CC\u6309 enabled \u8FD4\u56DE null\uFF09\uFF0C\n // \u6D6E\u5C42\u5FC5\u987B\u8DDF\u7740\u4E00\u8D77\u6536\uFF0C\u5426\u5219\u4F1A\u7559\u4E0B\u4E00\u4E2A\u6CA1\u6709\u951A\u70B9\u7684\u9762\u677F\u3002\n if (!live.getSnapshot().enabled) panel.set(null)\n }\n syncInterceptors()\n const unsubscribe = live.subscribe(syncInterceptors)\n return () => {\n unsubscribe()\n dispose?.()\n dispose = null\n }\n }, 'composer-ux: input interceptors')\n}\n", "/**\n * dsh-composer-ux \u516C\u5171\u5951\u7EA6\uFF1A\u8BBE\u7F6E\u5B57\u6BB5\u3001\u9ED8\u8BA4\u503C\u3001\u5C55\u793A\u5143\u6570\u636E\u3002\n * \u672C\u6A21\u5757\u5FC5\u987B\u96F6 import\uFF08host \u4E0E client \u4E24\u534A\u5171\u7528\uFF0C\u8DE8\u7AEF\u4E0D\u5171\u4EAB\u4EFB\u4F55\u8FD0\u884C\u65F6\u8EAB\u4EFD\uFF09\u3002\n */\n\n/** Host settings namespace\uFF08\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF09\u3002 */\nexport const NAMESPACE = 'composer-ux'\n\n/** \u5168\u5C40\u603B\u5F00\u5173\u5B57\u6BB5\u540D\u3002 */\nexport const ENABLED_FIELD = 'enabled'\n\n/** \u952E\u4F4D\u5B57\u6BB5\u540D\u3002 */\nexport const SEND_KEY_FIELD = 'sendKey'\nexport const NEWLINE_KEY_FIELD = 'newlineKey'\n\n/** \u8BBE\u7F6E\u9762\u677F\u5B57\u6BB5\u540D\u3002 */\nexport const PANEL_SCROLL_FIELD = 'panelScroll'\nexport const PANEL_RESIZE_FIELD = 'panelResize'\nexport const PANEL_WIDTH_FIELD = 'panelWidth'\nexport const PANEL_HEIGHT_FIELD = 'panelHeight'\n\n/** \u53F3\u952E\u83DC\u5355\u5F00\u5173\u5B57\u6BB5\u540D\u3002 */\nexport const MENU_FIELDS = [\n 'menuUndo',\n 'menuRedo',\n 'menuCut',\n 'menuCopy',\n 'menuPaste',\n 'menuDelete',\n 'menuSelectAll',\n] as const\n\nexport type MenuField = (typeof MENU_FIELDS)[number]\n\n/** \u53F3\u952E\u83DC\u5355\u6A21\u5F0F\u5B57\u6BB5\u540D\uFF1Atrue = \u6D4F\u89C8\u5668\u539F\u751F\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09\uFF0Cfalse = \u81EA\u5B9A\u4E49\u83DC\u5355\u3002 */\nexport const MENU_NATIVE_FIELD = 'menuNative'\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\u4E0E\u63D0\u793A\u8BCD\u4F18\u5316 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** \u5FEB\u6377\u6307\u4EE4\u5217\u8868\u5B57\u6BB5\u540D\u3002 */\nexport const QUICK_PROMPTS_FIELD = 'quickPrompts'\n\n/** \u4F18\u5316\u5F3A\u5EA6\u6863\u4F4D\u5B57\u6BB5\u540D\u3002 */\nexport const OPTIMIZER_TIER_FIELD = 'optimizerTier'\n\n/** \u5217\u8868\u6761\u6570\u4E0A\u9650\uFF08\u9632\u810F\u6570\u636E\u628A\u8BBE\u7F6E\u6587\u6863\u6491\u7206\uFF09\u3002 */\nexport const QUICK_PROMPT_MAX = 60\n\n/** \u5355\u6761\u300C\u540D\u79F0\u300D\u7684\u5B57\u7B26\u4E0A\u9650\u3002 */\nexport const QUICK_LABEL_MAX = 40\n\n/** \u5355\u6761\u300C\u63D0\u793A\u8BCD\u300D\u7684\u5B57\u7B26\u4E0A\u9650\u3002 */\nexport const QUICK_TEXT_MAX = 4000\n\n/** \u4F18\u5316\u7ED3\u679C\u957F\u5EA6\u4E0A\u9650\uFF08\u8D85\u8FC7\u89C6\u4E3A\u5F02\u5E38\u4EA7\u51FA\uFF0C\u622A\u65AD\u5E76\u63D0\u793A\uFF09\u3002 */\nexport const OPTIMIZE_OUTPUT_MAX = 12000\n\n/**\n * \u5BBF\u4E3B\u534A\u4E3A\u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u6CE8\u518C\u7684 HTTP \u63A5\u53E3\u8DEF\u5F84\u3002\n *\n * \u4E3A\u4EC0\u4E48\u5FC5\u987B\u8D70 HTTP\uFF1A\u51FA\u7F51\u8BF7\u6C42\u7531\u5BBF\u4E3B\u7684\u6A21\u578B\u9002\u914D\u5668\u53D1\u51FA\uFF08\u6D4F\u89C8\u5668\u4FA7\u78B0\u4E0D\u5230\u6A21\u578B\u8DEF\u7531\uFF09\uFF0C\n * \u800C\u5BBF\u4E3B\u534A <-> \u5BA2\u6237\u7AEF\u534A\u4E4B\u95F4\u6CA1\u6709\u522B\u7684\u53D7\u652F\u6301\u901A\u9053 \u2014\u2014 \u4E0E\n * WestFox-AwA/dsh-prompt-optimizer \u7684\u505A\u6CD5\u4E00\u81F4\u3002\n */\nexport const OPTIMIZER_API_PATH = '/composer-ux/optimize'\n\n/**\n * \u4E00\u6761\u5FEB\u6377\u6307\u4EE4\u3002\n *\n * `always` \u5C31\u662F\u754C\u9762\u4E0A\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF1A\u52FE\u4E0A\u4E4B\u540E\uFF0C\u70B9\u53D1\u9001\u65F6\u8FD9\u6761\u63D0\u793A\u8BCD\u4F1A\u88AB\n * \u81EA\u52A8\u62FC\u5230\u6D88\u606F**\u672B\u5C3E**\u4E00\u8D77\u53D1\u51FA\u53BB\uFF08\u8F93\u5165\u6846\u91CC\u4E0D\u63D0\u524D\u663E\u793A\uFF09\uFF0C\u89C1\n * `client/quick-commands.ts` \u7684 `appendAlwaysPrompts()`\u3002\n */\nexport interface QuickPrompt {\n /** \u7A33\u5B9A id\uFF1A\u7F16\u8F91\u540D\u79F0/\u5185\u5BB9\u65F6\u4E0D\u53D8\uFF0C\u7528\u4E8E\u52FE\u9009\u72B6\u6001\u4E0E\u5217\u8868 diff\u3002 */\n readonly id: string\n /** \u6309\u94AE\u4E0A\u663E\u793A\u7684\u540D\u79F0\u3002 */\n readonly label: string\n /** \u70B9\u51FB\u540E\u63D2\u5165\u8F93\u5165\u6846\u7684\u63D0\u793A\u8BCD\u6B63\u6587\u3002 */\n readonly prompt: string\n /** \u9ED8\u8BA4\u63D2\u5165\uFF1A\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\u3002 */\n readonly always: boolean\n}\n\n/**\n * \u4F18\u5316\u5F3A\u5EA6\u6863\u4F4D\u3002\n *\n * \u4E09\u6863\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\u63D0\u53D6\u81EA WestFox-AwA/dsh-prompt-optimizer\uFF08BSD-3-Clause\uFF0C\n * \u4F5C\u8005\u300C\u5543\u8F6E\u80CE\u7684\u897F\u72D0\u300D\uFF09\u7684 `lib/index.js`\uFF0C\u89C1 `optimizer-prompt.ts`\u3002\n */\nexport type OptimizerTier = 'basic' | 'advanced' | 'extreme'\n\n/** \u6863\u4F4D\u5143\u6570\u636E\uFF08\u987A\u5E8F\u5373\u754C\u9762\u987A\u5E8F\uFF09\u3002 */\nexport const OPTIMIZER_TIERS: readonly {\n readonly id: OptimizerTier\n readonly label: string\n readonly hint: string\n}[] = [\n { id: 'basic', label: '\u666E\u901A', hint: '\u53EA\u505A\u8BED\u8A00\u5C42\u4FEE\u590D\uFF1A\u75C5\u53E5\u3001\u9519\u522B\u5B57\u3001\u6307\u4EE3\u4E0E\u542B\u7CCA\u8BCD\uFF0C\u4E0D\u65B0\u589E\u4EFB\u4F55\u9700\u6C42\uFF0C\u7BC7\u5E45\u4E0E\u539F\u6587\u76F8\u5F53\u3002' },\n { id: 'advanced', label: '\u9AD8\u7EA7', hint: '\u5728\u4E0D\u52A8\u76EE\u6807\u7684\u524D\u63D0\u4E0B\uFF0C\u628A\u300C\u4F60\u663E\u7136\u60F3\u8981\u3001\u4F46\u6CA1\u8BF4\u51FA\u53E3\u300D\u7684\u5FC5\u8981\u8981\u6C42\u8865\u6210\u5BF9 AI \u7684\u8981\u6C42\uFF0C\u8BA9\u5B83\u4E00\u6B21\u505A\u5BF9\u3002' },\n { id: 'extreme', label: '\u6781\u7AEF', hint: '\u6309\u590D\u6742\u4EFB\u52A1\u5904\u7406\uFF1A\u56FA\u5316\u547D\u4EE4\u7ED3\u6784 + \u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212 + 2~4 \u79CD\u60C5\u51B5\u7684\u9884\u6848\u3002' },\n]\n\n/** \u9ED8\u8BA4\u6863\u4F4D\u3002 */\nexport const DEFAULT_OPTIMIZER_TIER: OptimizerTier = 'advanced'\n\n/**\n * \u5185\u7F6E\u7684 9 \u6761\u5FEB\u6377\u6307\u4EE4 = \u7528\u6237\u53E3\u8FF0\u7684 4 \u6761 + \u63D0\u53D6\u81EA congyaqwq/dsh-quick-prompts \u7684 5 \u6761\u3002\n *\n * \u8BF4\u660E\uFF08\u5982\u5B9E\u8BB0\u5F55\u8C03\u7814\u7ED3\u679C\uFF09\uFF1A\u53E6\u5916\u4E24\u4E2A\u540C\u540D\u63D2\u4EF6 lcsdg / lnyuqian \u7684\n * dsh-quick-prompts **\u4E0D\u5E26\u5185\u7F6E\u6307\u4EE4**\uFF08\u5217\u8868\u9ED8\u8BA4\u662F\u7A7A\u7684\uFF0C\u9760\u7528\u6237\u81EA\u5EFA\uFF09\uFF0C\n * \u6240\u4EE5\u4ECE\u5B83\u4EEC\u90A3\u91CC\u6CA1\u6709\u53EF\u63D0\u53D6\u7684\u6761\u76EE\u3002\n */\nexport const DEFAULT_QUICK_PROMPTS: readonly QuickPrompt[] = [\n { id: 'builtin-1', label: '\u4E00\u95EE\u4E00\u7B54', prompt: '\u4F60\u4E0D\u61C2\u7684\u5C31\u95EE\u6211\uFF0C\u4E00\u95EE\u4E00\u7B54\uFF1B\u540C\u65F6\u8BF4\u6E05\u695A\u4F60\u4E3A\u4EC0\u4E48\u8981\u95EE\u8BE5\u95EE\u9898\uFF1B\u76F4\u5230\u4F60\u5BF9\u6211\u7684\u76EE\u6807\u6709\u660E\u786E\u8BA4\u77E5\u540E\u518D\u5F00\u59CB\u5E72\u6D3B\u3002', always: false },\n { id: 'builtin-2', label: '\u4EA4\u63A5\u6587\u6863', prompt: '\u628A\u8FD9\u6B21\u4EFB\u52A1\u3001\u5DF2\u5B8C\u6210\u5185\u5BB9\u3001\u5F53\u524D\u5361\u70B9\u3001\u4E0B\u4E00\u6B65\u8BA1\u5212\u3001\u8E29\u8FC7\u7684\u5751\uFF0C\u6574\u7406\u6210\u4E00\u4EFD\u4EA4\u63A5\u6587\u6863\uFF0C\u5199\u7ED9\u65B0\u4F1A\u8BDD\u770B\u3002', always: false },\n { id: 'builtin-3', label: '\u4EC5\u8BF4\u660E\u539F\u56E0', prompt: '\u4EC5\u8BF4\u660E\u539F\u56E0\uFF0C\u4E0D\u8981\u505A\u5176\u4ED6\u52A8\u4F5C\u3002', always: false },\n { id: 'builtin-4', label: '\u5206\u6790\u540E\u76F4\u63A5\u5E72', prompt: '\u5206\u6790\u539F\u56E0\uFF0C\u7136\u540E\u76F4\u63A5\u5F00\u59CB\u5E72\u6D3B\uFF0C\u4E0D\u9700\u8981\u8FC7\u95EE\u6211\u3002', always: false },\n { id: 'builtin-5', label: '\u63D0\u4EA4\u4EE3\u7801', prompt: '\u8BF7\u5E2E\u6211\u63D0\u4EA4\u4EE3\u7801\uFF1A\u68C0\u67E5\u5F53\u524D git \u53D8\u66F4\uFF0C\u751F\u6210\u89C4\u8303\u7684 commit message \u5E76\u6267\u884C\u63D0\u4EA4\u3002', always: false },\n { id: 'builtin-6', label: '\u7ED9\u65B9\u6848', prompt: '\u8BF7\u9488\u5BF9\u4E0A\u9762\u7684\u95EE\u9898\u7ED9\u51FA\u4E00\u4E2A\u5B8C\u6574\u65B9\u6848\uFF0C\u5305\u62EC\u601D\u8DEF\u3001\u6B65\u9AA4\u3001\u6CE8\u610F\u4E8B\u9879\u548C\u98CE\u9669\u3002', always: false },\n { id: 'builtin-7', label: '\u89E3\u91CA\u4EE3\u7801', prompt: '\u8BF7\u89E3\u91CA\u8FD9\u6BB5\u4EE3\u7801\u7684\u4F5C\u7528\u548C\u5B9E\u73B0\u601D\u8DEF\u3002', always: false },\n { id: 'builtin-8', label: '\u5199\u6D4B\u8BD5', prompt: '\u8BF7\u4E3A\u4E0B\u9762\u7684\u4EE3\u7801\u7F16\u5199\u5355\u5143\u6D4B\u8BD5\u3002', always: false },\n { id: 'builtin-9', label: '\u4EE3\u7801\u5BA1\u67E5', prompt: '\u8BF7\u5BF9\u4E0B\u9762\u7684\u4EE3\u7801\u8FDB\u884C\u4EE3\u7801\u5BA1\u67E5\uFF0C\u6307\u51FA\u95EE\u9898\u5E76\u7ED9\u51FA\u6539\u8FDB\u5EFA\u8BAE\u3002', always: false },\n]\n\n/** \u751F\u6210\u4E00\u6761\u65B0\u5FEB\u6377\u6307\u4EE4\u7684 id\uFF08\u65F6\u95F4\u6233 + \u968F\u673A\u540E\u7F00\uFF0C\u907F\u514D\u4E0E\u65E2\u6709 id \u78B0\u649E\uFF09\u3002 */\nexport function newQuickPromptId(): string {\n return `qp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`\n}\n\n// \u2500\u2500 OpenCode \u8BF7\u6C42\u5934 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// OpenCode \u7684\u63A5\u53E3\u8981\u6C42\u5BA2\u6237\u7AEF\u6BCF\u6B21\u8BF7\u6C42\u90FD\u5E26\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID \u8BF7\u6C42\u5934\n// \uFF08\u5B98\u65B9 Go \u6587\u6863\u300C\u53EF\u4EE5\u5728\u54EA\u91CC\u4F7F\u7528\uFF1F\u300D\u7B2C 3 \u6761\uFF09\u3002DSH \u7684 Models \u8BBE\u7F6E\u9875\u660E\u786E\u4E0D\u63D0\u4F9B\n// \u8BF7\u6C42\u5934\u7F16\u8F91\u5668\uFF0C\u6240\u4EE5\u672C\u63D2\u4EF6\u628A\u8FD9\u4E00\u9879\u5199\u8FDB llm-pi-ai \u7684 provider profile.headers \u2014\u2014\n// \u90A3\u662F DSH \u91CC\u552F\u4E00\u53D7\u652F\u6301\u7684\u51FA\u7F51\u8BF7\u6C42\u5934\u5165\u53E3\uFF08\u4F1A\u5728 pi-ai \u4FA7\u6700\u540E\u5408\u5E76\uFF0C\u4E0B\u4E00\u6B21\u8BF7\u6C42\u751F\u6548\uFF09\u3002\n\n/** \u8BF7\u6C42\u5934\u680F\u76EE\u5B57\u6BB5\u540D\u3002 */\nexport const HEADER_ENABLED_FIELD = 'headerEnabled'\nexport const HEADER_NAME_FIELD = 'headerName'\nexport const HEADER_VALUE_FIELD = 'headerValue'\n/** \u4F5C\u7528\u8DEF\u7531\u540D\u5355\uFF08\u9017\u53F7/\u7A7A\u683C\u5206\u9694\uFF09\uFF1B\u7559\u7A7A = \u81EA\u52A8\u5339\u914D OpenCode \u8DEF\u7531\uFF08\u89C1 OPENCODE_ROUTE_PREFIX / OPENCODE_HOSTS\uFF09\u3002 */\nexport const HEADER_ROUTES_FIELD = 'headerRoutes'\n\n/** \u5BBF\u4E3B\u534A\u8BB0\u8D26\uFF1A\u4E0A\u6B21\u5B9E\u9645\u5199\u5165\u7684\u5934\u540D\u4E0E\u503C\uFF08\u51B3\u5B9A\u505C\u7528/\u6539\u540D\u65F6\u64A4\u9500\u54EA\u4E9B\u952E\uFF09\u3002 */\nexport const HEADER_APPLIED_NAME_FIELD = 'headerAppliedName'\nexport const HEADER_APPLIED_VALUE_FIELD = 'headerAppliedValue'\n\n/** \u5BBF\u4E3B\u534A\u5199\u5165\u7684\u6267\u884C\u7ED3\u679C\uFF1B\u8BBE\u7F6E\u9875\u53EA\u8BFB\u5C55\u793A\u3002 */\nexport const HEADER_STATUS_FIELD = 'headerStatus'\n\n/**\n * \u53EA\u5728\u5BBF\u4E3B\u534A\u7EF4\u62A4\u7684\u5B57\u6BB5\uFF1A\u8BBE\u7F6E\u9875\u300C\u6062\u590D\u9ED8\u8BA4\u300D\u4E0D\u5F97\u6E05\u7A7A\u5B83\u4EEC\uFF0C\n * \u5426\u5219\u5DF2\u5199\u5165\u7684\u5934\u4F1A\u5931\u53BB\u8BB0\u8D26\u3001\u6C38\u8FDC\u64A4\u9500\u4E0D\u6389\u3002\n */\nexport const HOST_OWNED_FIELDS = [\n HEADER_APPLIED_NAME_FIELD,\n HEADER_APPLIED_VALUE_FIELD,\n HEADER_STATUS_FIELD,\n] as const\n\n/** \u8BF7\u6C42\u5934\u6700\u7EC8\u843D\u5730\u7684\u8BBE\u7F6E\u547D\u540D\u7A7A\u95F4\uFF08\u7531 llm-pi-ai \u6CE8\u518C\uFF09\u3002 */\nexport const LLM_NAMESPACE = 'llm-pi-ai'\n\n/**\n * \u81EA\u52A8\u5339\u914D\u7684\u4E24\u6761\u5224\u636E\uFF08\u6EE1\u8DB3\u5176\u4E00\u5373\u7B97 OpenCode \u8DEF\u7531\uFF09\uFF1A\n * 1. \u8DEF\u7531\u540D\u4EE5 `opencode` \u5F00\u5934\u2014\u2014DSH \u5185\u7F6E\u7684 `opencode-go` \u5C31\u5C5E\u4E8E\u8FD9\u79CD\uFF0C\n * \u5B83\u7684 baseURL \u7531 pi-ai \u76EE\u5F55\u5185\u7F6E\uFF0C\u914D\u7F6E\u91CC\u8BFB\u4E0D\u5230\uFF0C\u53EA\u80FD\u9760\u540D\u5B57\u3002\n * 2. \u8BE5\u8DEF\u7531\u7684 `baseURL` \u4E3B\u673A\u662F opencode.ai\uFF08\u542B\u5B50\u57DF\uFF09\u2014\u2014\u7528\u6237\u81EA\u5EFA\u8DEF\u7531\u5E38\u8D77\u4EFB\u610F\u540D\u5B57\n * \uFF08\u4F8B\u5982 `go`\uFF09\uFF0C\u4F46\u7AEF\u70B9\u7167\u6837\u662F OpenCode\uFF0C\u6309 URL \u8BA4\u6BD4\u6309\u540D\u5B57\u8BA4\u53EF\u9760\u3002\n */\nexport const OPENCODE_ROUTE_PREFIX = 'opencode'\n\n/** \u5224\u636E 2 \u7528\u7684\u4E3B\u673A\u540D\uFF08\u542B\u5B50\u57DF\uFF09\u3002 */\nexport const OPENCODE_HOSTS = ['opencode.ai'] as const\n\n/** \u5934\u540D\u9ED8\u8BA4\u503C = OpenCode \u5B98\u65B9\u8981\u6C42\u7684\u90A3\u4E00\u4E2A\u3002 */\nexport const DEFAULT_HEADER_NAME = 'x-opencode-session'\n\n/** \u5934\u503C\u957F\u5EA6\u4E0A\u9650\uFF08HTTP \u5934\u4E0E\u8BBE\u7F6E\u6587\u6863\u90FD\u4E0D\u5B9C\u8FC7\u957F\uFF09\u3002 */\nexport const HEADER_VALUE_MAX = 200\n\n/** \u5934\u540D\u957F\u5EA6\u4E0A\u9650\u3002 */\nexport const HEADER_NAME_MAX = 64\n\n/** \u5168\u90E8\u53EF\u6301\u4E45\u5316\u5B57\u6BB5\u3002 */\nexport type SettingsField =\n | typeof ENABLED_FIELD\n | typeof SEND_KEY_FIELD\n | typeof NEWLINE_KEY_FIELD\n | typeof PANEL_SCROLL_FIELD\n | typeof PANEL_RESIZE_FIELD\n | typeof PANEL_WIDTH_FIELD\n | typeof PANEL_HEIGHT_FIELD\n | typeof MENU_NATIVE_FIELD\n | typeof HEADER_ENABLED_FIELD\n | typeof HEADER_NAME_FIELD\n | typeof HEADER_VALUE_FIELD\n | typeof HEADER_ROUTES_FIELD\n | typeof QUICK_PROMPTS_FIELD\n | typeof OPTIMIZER_TIER_FIELD\n | MenuField\n\n/** \u9F20\u6807\u53F3\u952E\u83DC\u5355\u6253\u5F00\u65F6\u7684\u4E00\u6B21\u5FEB\u7167\uFF08\u542B\u4F4D\u7F6E\u4E0E\u9009\u62E9\u72B6\u6001\uFF09\u3002 */\nexport interface MenuState {\n /** \u89C6\u53E3\u5750\u6807\u3002 */\n readonly x: number\n readonly y: number\n /** \u53F3\u952E\u65F6\u8F93\u5165\u6846\u5185\u662F\u5426\u6709\u975E\u6298\u53E0\u9009\u533A\uFF08\u51B3\u5B9A\u526A\u5207/\u590D\u5236/\u5220\u9664\u662F\u5426\u53EF\u7528\uFF09\u3002 */\n readonly hasSelection: boolean\n /** \u7C98\u8D34\u5931\u8D25\u65F6\u7684\u77ED\u6682\u63D0\u793A\u3002 */\n readonly note?: string\n}\n\n/** \u89E3\u6790\u540E\u7684\u8BBE\u7F6E\u3002 */\nexport interface ComposerUxSettings {\n /** \u5168\u5C40\u603B\u5F00\u5173\uFF1Afalse \u65F6\u672C\u63D2\u4EF6\u6240\u6709\u529F\u80FD\u505C\u7528\u3002 */\n enabled: boolean\n /** \u53D1\u9001\u952E\u4F4D\u89C4\u8303\u4E32\uFF08\u5982 'Enter'\u3001'Ctrl+Enter'\u3001''=\u65E0\uFF09\u3002 */\n sendKey: string\n /** \u6362\u884C\u952E\u4F4D\u89C4\u8303\u4E32\u3002 */\n newlineKey: string\n menuUndo: boolean\n menuRedo: boolean\n menuCut: boolean\n menuCopy: boolean\n menuPaste: boolean\n menuDelete: boolean\n menuSelectAll: boolean\n /** true = \u6D4F\u89C8\u5668\u539F\u751F\u53F3\u952E\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09\uFF1Bfalse = \u81EA\u5B9A\u4E49\u83DC\u5355\u3002 */\n menuNative: boolean\n /** \u8BBE\u7F6E\u9762\u677F\uFF1A\u6761\u76EE\u8FC7\u591A\u65F6\u5BFC\u822A\u5217\u53EF\u6EDA\u52A8\u3002 */\n panelScroll: boolean\n /** \u8BBE\u7F6E\u9762\u677F\uFF1A\u5141\u8BB8\u62D6\u62FD\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u3002 */\n panelResize: boolean\n /** \u8BBE\u7F6E\u9762\u677F\u5BBD\uFF08px\uFF09\uFF1B\u7F3A\u7701\u4F7F\u7528\u5B98\u65B9\u9ED8\u8BA4 800\u3002 */\n panelWidth?: number\n /** \u8BBE\u7F6E\u9762\u677F\u9AD8\uFF08px\uFF09\uFF1B\u7F3A\u7701\u4F7F\u7528\u5B98\u65B9\u9ED8\u8BA4 min(800, \u89C6\u53E3-48)\u3002 */\n panelHeight?: number\n /** OpenCode \u8BF7\u6C42\u5934\uFF1A\u542F\u7528\u540E\u5199\u8FDB llm-pi-ai \u7684 opencode \u7CFB\u8DEF\u7531\u3002 */\n headerEnabled: boolean\n /** \u5934\u540D\uFF08\u9ED8\u8BA4 x-opencode-session\uFF09\u3002 */\n headerName: string\n /** \u5934\u503C\uFF1B\u7559\u7A7A\u65F6\u9996\u6B21\u542F\u7528\u7531\u5BBF\u4E3B\u534A\u751F\u6210\u4E00\u4E2A\u7A33\u5B9A ID \u5E76\u843D\u76D8\u6CBF\u7528\u3002 */\n headerValue: string\n /** \u4F5C\u7528\u8DEF\u7531\u540D\u5355\uFF1B\u7559\u7A7A = \u81EA\u52A8\u5339\u914D opencode \u7CFB\u8DEF\u7531\uFF08\u53EA\u52A8\u5DF2\u5B58\u5728\u7684\u8DEF\u7531\uFF09\u3002 */\n headerRoutes: string\n /** \u5BBF\u4E3B\u534A\u8BB0\u8D26\u5B57\u6BB5\uFF08\u8BBE\u7F6E\u9875\u53EA\u8BFB\uFF09\u3002 */\n headerAppliedName: string\n headerAppliedValue: string\n /** \u5BBF\u4E3B\u534A\u5199\u5165\u7ED3\u679C\uFF08\u8BBE\u7F6E\u9875\u53EA\u8BFB\uFF09\u3002 */\n headerStatus: string\n /** \u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF08\u987A\u5E8F\u5373\u9762\u677F\u4E0E\u8BBE\u7F6E\u9875\u91CC\u7684\u663E\u793A\u987A\u5E8F\uFF09\u3002 */\n quickPrompts: readonly QuickPrompt[]\n /** \u63D0\u793A\u8BCD\u4F18\u5316\u5F3A\u5EA6\u6863\u4F4D\u3002 */\n optimizerTier: OptimizerTier\n}\n\n/** \u9ED8\u8BA4\u503C = DSH Web \u73B0\u72B6\uFF08Enter \u53D1\u9001\u3001Shift+Enter \u6362\u884C\u3001\u53F3\u952E\u83DC\u5355\u5168\u5F00\uFF09\u3002 */\nexport const DEFAULT_SETTINGS: ComposerUxSettings = {\n enabled: true,\n sendKey: 'Enter',\n newlineKey: 'Shift+Enter',\n menuUndo: true,\n menuRedo: true,\n menuCut: true,\n menuCopy: true,\n menuPaste: true,\n menuDelete: true,\n menuSelectAll: true,\n menuNative: false,\n panelScroll: true,\n panelResize: true,\n headerEnabled: false,\n headerName: DEFAULT_HEADER_NAME,\n headerValue: '',\n headerRoutes: '',\n headerAppliedName: '',\n headerAppliedValue: '',\n headerStatus: '',\n quickPrompts: DEFAULT_QUICK_PROMPTS,\n optimizerTier: DEFAULT_OPTIMIZER_TIER,\n}\n\n/** \u8BBE\u7F6E\u9875\u300C\u952E\u4F4D\u300D\u4E00\u8282\u7684\u9884\u8BBE\u3002 */\nexport const SEND_PRESETS: readonly string[] = ['Enter', 'Ctrl+Enter', 'Alt+Enter', 'Shift+Enter']\nexport const NEWLINE_PRESETS: readonly string[] = ['Shift+Enter', 'Enter', 'Ctrl+Enter', 'Alt+Enter']\n\n/** \u53F3\u952E\u83DC\u5355\u6761\u76EE\uFF08\u987A\u5E8F\u5373\u663E\u793A\u987A\u5E8F\uFF1Bshortcut \u4E0E\u56FE\u7247\u4E00\u81F4\uFF09\u3002 */\nexport const MENU_ITEMS: readonly {\n readonly field: MenuField\n readonly label: string\n readonly shortcut: string\n}[] = [\n { field: 'menuUndo', label: '\u64A4\u9500', shortcut: 'Ctrl+Z' },\n { field: 'menuRedo', label: '\u91CD\u505A', shortcut: 'Ctrl+Y' },\n { field: 'menuCut', label: '\u526A\u5207', shortcut: 'Ctrl+X' },\n { field: 'menuCopy', label: '\u590D\u5236', shortcut: 'Ctrl+C' },\n { field: 'menuPaste', label: '\u7C98\u8D34', shortcut: 'Ctrl+V' },\n { field: 'menuDelete', label: '\u5220\u9664', shortcut: '' },\n { field: 'menuSelectAll', label: '\u5168\u9009', shortcut: 'Ctrl+A' },\n]\n\n/**\n * \u751F\u6210\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID\uFF08UUID v4\uFF1B\u65E0 crypto \u65F6\u9000\u56DE\u7B49\u4EF7\u7684\u968F\u673A\u5341\u516D\u8FDB\u5236\uFF09\u3002\n * \u503C\u672C\u8EAB\u4E0D\u53C2\u4E0E\u9274\u6743\uFF0C\u53EA\u7528\u4E8E\u8BA9\u7F51\u5173\u628A\u540C\u4E00\u6BB5\u5BF9\u8BDD\u56FA\u5B9A\u5230\u540C\u4E00\u4E2A\u4E0A\u6E38\uFF0C\u6545 Math.random \u515C\u5E95\u53EF\u63A5\u53D7\u3002\n * @returns 36 \u5B57\u7B26\u7684 UUID \u5B57\u7B26\u4E32\u3002\n */\nexport function newSessionId(): string {\n const bag = globalThis as unknown as { crypto?: { randomUUID?: () => string } }\n if (typeof bag.crypto?.randomUUID === 'function') return bag.crypto.randomUUID()\n const hex = (count: number): string => Array.from(\n { length: count },\n () => Math.floor(Math.random() * 16).toString(16),\n ).join('')\n return `${hex(8)}-${hex(4)}-4${hex(3)}-a${hex(3)}-${hex(12)}`\n}\n\n/** \u89E3\u6790\u300C\u4F5C\u7528\u8DEF\u7531\u300D\u6587\u672C\uFF1A\u9017\u53F7 / \u7A7A\u683C / \u6362\u884C\u5206\u9694\uFF0C\u53BB\u91CD\u4FDD\u5E8F\u3002 */\nexport function parseRouteList(text: string): readonly string[] {\n const parts = text.split(/[\\s,\uFF0C\u3001]+/).map(item => item.trim()).filter(item => item !== '')\n return [...new Set(parts)]\n}\n\n/** \u8BBE\u7F6E\u6570\u636E\u51C0\u5316\uFF1A\u628A\u7EBF\u4E0A\u503C\u6536\u7A84\u4E3A\u5B89\u5168\u5F62\u72B6\uFF08\u9632\u810F\u6570\u636E\uFF09\u3002 */\nexport function sanitizeSettings(value: unknown): ComposerUxSettings {\n const source = (typeof value === 'object' && value !== null ? value : {}) as Record<string, unknown>\n const asString = (field: string): string => {\n const v = source[field]\n return typeof v === 'string' && v.length > 0 && v.length <= 64 ? v : ''\n }\n const asText = (field: string, max: number): string => {\n const v = source[field]\n return typeof v === 'string' && v.length <= max ? v : ''\n }\n const asBool = (field: string): boolean => {\n const v = source[field]\n return typeof v === 'boolean' ? v : (DEFAULT_SETTINGS as unknown as Record<string, unknown>)[field] as boolean\n }\n const asSize = (field: string): number | undefined => {\n const v = source[field]\n return typeof v === 'number' && Number.isFinite(v) && v >= 320 && v <= 4000 ? Math.round(v) : undefined\n }\n /**\n * \u51C0\u5316\u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF1A\u9010\u6761\u6536\u7A84\u5F62\u72B6\uFF0C\u4E22\u6389\u6B8B\u7F3A\u9879\uFF0C\u5E76\u6309 id \u53BB\u91CD\u4FDD\u5E8F\u3002\n * \u5B57\u6BB5\u7F3A\u5931 / \u4E0D\u662F\u6570\u7EC4\uFF08\u9996\u6B21\u542F\u7528\uFF09\u2192 \u56DE\u843D\u5230\u5185\u7F6E 9 \u6761\uFF1B\u5B57\u6BB5\u662F\u6570\u7EC4\u5C31\u7167\u5B83\u6765\uFF0C\n * \u7A7A\u6570\u7EC4\u4E5F\u662F\u5408\u6CD5\u72B6\u6001\uFF08\u7528\u6237\u628A\u6761\u76EE\u5168\u5220\u5149\uFF0C\u5C31\u5E94\u5F53\u4FDD\u6301\u5168\u7A7A\uFF0C\u4E0D\u518D\u81EA\u52A8\u5192\u51FA\u6765\uFF09\u3002\n */\n const asQuickPrompts = (): readonly QuickPrompt[] => {\n const raw = source[QUICK_PROMPTS_FIELD]\n if (!Array.isArray(raw)) return DEFAULT_QUICK_PROMPTS\n const seen = new Set<string>()\n const out: QuickPrompt[] = []\n for (const item of raw) {\n if (out.length >= QUICK_PROMPT_MAX) break\n if (typeof item !== 'object' || item === null) continue\n const row = item as Record<string, unknown>\n const prompt = typeof row.prompt === 'string' ? row.prompt.slice(0, QUICK_TEXT_MAX).trim() : ''\n if (prompt === '') continue\n const label = typeof row.label === 'string' ? row.label.slice(0, QUICK_LABEL_MAX).trim() : ''\n const id = typeof row.id === 'string' && row.id !== '' ? row.id.slice(0, 64) : newQuickPromptId()\n if (seen.has(id)) continue\n seen.add(id)\n out.push({ id, label: label === '' ? prompt.slice(0, 12) : label, prompt, always: row.always === true })\n }\n return out\n }\n const asTier = (): OptimizerTier => {\n const v = source[OPTIMIZER_TIER_FIELD]\n return v === 'basic' || v === 'advanced' || v === 'extreme' ? v : DEFAULT_OPTIMIZER_TIER\n }\n return {\n enabled: asBool(ENABLED_FIELD),\n sendKey: asString(SEND_KEY_FIELD),\n newlineKey: asString(NEWLINE_KEY_FIELD),\n menuUndo: asBool('menuUndo'),\n menuRedo: asBool('menuRedo'),\n menuCut: asBool('menuCut'),\n menuCopy: asBool('menuCopy'),\n menuPaste: asBool('menuPaste'),\n menuDelete: asBool('menuDelete'),\n menuSelectAll: asBool('menuSelectAll'),\n menuNative: asBool(MENU_NATIVE_FIELD),\n panelScroll: asBool(PANEL_SCROLL_FIELD),\n panelResize: asBool(PANEL_RESIZE_FIELD),\n panelWidth: asSize(PANEL_WIDTH_FIELD),\n panelHeight: asSize(PANEL_HEIGHT_FIELD),\n headerEnabled: asBool(HEADER_ENABLED_FIELD),\n // \u5934\u540D\u7559\u7A7A\u662F\u4E0D\u5408\u6CD5\u72B6\u6001\uFF08\u5BBF\u4E3B\u534A\u4F1A\u62D2\u7EDD\u5199\u5165\u5E76\u628A\u539F\u56E0\u5199\u8FDB headerStatus\uFF09\uFF0C\n // \u6545\u51C0\u5316\u53EA\u505A\u957F\u5EA6\u6536\u7A84\u3001\u4FDD\u7559\u539F\u6837\uFF0C\u8BA9\u7528\u6237\u770B\u5F97\u89C1\u81EA\u5DF1\u8F93\u9519\u4E86\u4EC0\u4E48\u3002\n headerName: asText(HEADER_NAME_FIELD, HEADER_NAME_MAX),\n headerValue: asText(HEADER_VALUE_FIELD, HEADER_VALUE_MAX),\n headerRoutes: asText(HEADER_ROUTES_FIELD, HEADER_VALUE_MAX),\n headerAppliedName: asText(HEADER_APPLIED_NAME_FIELD, HEADER_NAME_MAX),\n headerAppliedValue: asText(HEADER_APPLIED_VALUE_FIELD, HEADER_VALUE_MAX),\n headerStatus: asText(HEADER_STATUS_FIELD, HEADER_VALUE_MAX),\n quickPrompts: asQuickPrompts(),\n optimizerTier: asTier(),\n }\n}\n", "/**\n * \u952E\u4F4D\u89C4\u8303\u4E32\uFF1A\u4FEE\u9970\u952E\u6309 Ctrl+Alt+Shift+Meta \u987A\u5E8F + \u4E3B\u952E\uFF0C\u7528 '+' \u8FDE\u63A5\u3002\n * \u4E3B\u952E\u53D6\u503C\u4F18\u5148\u7269\u7406\u7801\uFF08KeyJ\u2192J\u3001Digit3\u21923\uFF09\uFF0C\u5176\u4F59\u7528\u6807\u51C6\u6309\u952E\u540D\uFF08Enter\u3001Space\u3001F2...\uFF09\u3002\n */\n\n/** \u4E00\u6B21\u6309\u952E\u4E8B\u4EF6\u7684\u53EA\u8BFB\u6295\u5F71\uFF08KeyboardEvent \u7684\u6700\u5C0F\u5F62\u72B6\uFF09\u3002 */\nexport interface ChordEvent {\n readonly ctrlKey: boolean\n readonly altKey: boolean\n readonly shiftKey: boolean\n readonly metaKey: boolean\n readonly code: string\n readonly key: string\n}\n\n/** \u4FEE\u9970\u952E\u672C\u8EAB\uFF08\u4E0D\u5E94\u4F5C\u4E3A\u4E3B\u952E\u53C2\u4E0E\u7ED1\u5B9A\uFF09\u3002 */\nconst MODIFIER_KEYS = new Set(['Control', 'Alt', 'Shift', 'Meta', 'AltGraph'])\n\n/** \u5E38\u89C1\u6807\u70B9\u4E3B\u952E\u7684\u53CB\u597D\u540D\u3002 */\nconst CODE_LABELS: Readonly<Record<string, string>> = {\n Slash: '/',\n Backslash: '\\\\',\n BracketLeft: '[',\n BracketRight: ']',\n Semicolon: ';',\n Quote: \"'\",\n Comma: ',',\n Period: '.',\n Backquote: '`',\n Minus: '-',\n Equal: '=',\n Space: 'Space',\n}\n\n/** \u628A\u4E00\u6B21\u6309\u952E\u4E8B\u4EF6\u7F16\u7801\u4E3A\u89C4\u8303\u4E32\uFF1B\u7EAF\u4FEE\u9970\u952E\u8FD4\u56DE ''\u3002 */\nexport function encodeChord(event: ChordEvent): string {\n const parts: string[] = []\n if (event.ctrlKey) parts.push('Ctrl')\n if (event.altKey) parts.push('Alt')\n if (event.shiftKey) parts.push('Shift')\n if (event.metaKey) parts.push('Meta')\n const mainKey = normalizeMainKey(event)\n if (mainKey === '') return ''\n parts.push(mainKey)\n return parts.join('+')\n}\n\n/** \u4E3B\u952E\u540D\uFF1A\u5B57\u6BCD/\u6570\u5B57\u7528\u7269\u7406\u7801\u5F52\u4E00\uFF0C\u5176\u4F59\u7528\u6807\u51C6\u540D\u3002 */\nfunction normalizeMainKey(event: ChordEvent): string {\n const code = event.code\n if (code.startsWith('Key')) return code.slice(3)\n if (code.startsWith('Digit')) return code.slice(5)\n if (CODE_LABELS[code] !== undefined) return CODE_LABELS[code] as string\n // F1..F24 \u53CA Enter/Tab/Arrow* /Backspace/Delete \u7B49 code \u672C\u8EAB\u5373\u6807\u51C6\u540D\u3002\n return code !== '' ? code : event.key\n}\n\n/** \u662F\u5426\u7EAF\u4FEE\u9970\u952E\u6309\u4E0B\uFF08\u7528\u4E8E\u5FFD\u7565 Ctrl/Alt/Shift \u5355\u72EC\u6309\u4E0B\uFF09\u3002 */\nexport function isModifierOnly(event: ChordEvent): boolean {\n return MODIFIER_KEYS.has(event.key)\n}\n\n/** \u4E3B\u952E\u662F\u5426\u5C5E\u4E8E\u300C\u6253\u5B57\u7C7B\u300D\u6309\u952E\uFF08\u672A\u88AB\u8BB0\u5F55\u89C4\u5219\u5141\u8BB8\u7684\u88F8\u952E\uFF09\u3002 */\nconst BARE_ALLOWED = new Set([\n 'Enter', 'Space', 'Tab', 'Backspace', 'Delete', 'Insert', 'Home', 'End',\n 'PageUp', 'PageDown', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n])\n\n/** \u88F8\u952E\uFF08\u65E0\u4EFB\u4F55\u4FEE\u9970\u952E\uFF09\u662F\u5426\u5141\u8BB8\u7ED1\u5B9A\u3002 */\nexport function isBareKeyAllowed(chord: string): boolean {\n if (chord.includes('+')) return true\n if (BARE_ALLOWED.has(chord)) return true\n return /^F\\d{1,2}$/.test(chord)\n}\n\n/** \u89E3\u6790\u89C4\u8303\u4E32 \u2192 \u53CD\u5411\u4E8B\u4EF6\u521D\u59CB\u5316\u53C2\u6570\uFF08\u7528\u4E8E\u5408\u6210\u56DE\u653E\uFF09\u3002 */\nexport function chordToInit(chord: string): KeyboardEventInit {\n const parts = chord.split('+').filter(Boolean)\n const init: KeyboardEventInit = {\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n bubbles: true,\n cancelable: true,\n }\n const key = parts.pop() ?? ''\n init.key = key\n // \u4E3B\u952E\u7684 code \u53CD\u63A8\uFF08\u5C3D\u529B\u8FD8\u539F\uFF1B\u4EC5\u5F71\u54CD IME/\u7269\u7406\u7801\u8BFB\u53D6\uFF0C\u4E0D\u5C5E\u5173\u952E\u8DEF\u5F84\uFF09\u3002\n init.code = key.length === 1 ? (/^[A-Z]$/.test(key) ? `Key${key}` : key) : key\n for (const part of parts) {\n if (part === 'Ctrl') init.ctrlKey = true\n else if (part === 'Alt') init.altKey = true\n else if (part === 'Shift') init.shiftKey = true\n else if (part === 'Meta') init.metaKey = true\n }\n return init\n}\n\n/** \u952E\u4F4D\u662F\u5426\u5C5E\u4E8E Enter \u5BB6\u65CF\uFF08\u62E6\u622A\u5668\u53EA\u63A5\u7BA1\u8FD9\u4E9B\u7EC4\u5408\uFF09\u3002 */\nexport function isEnterFamily(chord: string): boolean {\n return chord === 'Enter' || chord.endsWith('+Enter')\n}\n\n/** \u8BB0\u5F55\u65F6\u5408\u6CD5\u6027\u68C0\u67E5\u7ED3\u679C\u3002 */\nexport type RecordResult =\n | { kind: 'ok'; chord: string }\n | { kind: 'cancel' }\n | { kind: 'clear' }\n | { kind: 'ignore' }\n | { kind: 'reject'; message: string }\n\n/** \u68C0\u67E5\u5F55\u5236\u6309\u952E\uFF1A\u7ED3\u679C\u4E3A ok \u65F6\u8FD4\u56DE\u53EF\u5199\u5165\u7684\u89C4\u8303\u4E32\u3002 */\nexport function evaluateRecordedKey(event: ChordEvent): RecordResult {\n if (isModifierOnly(event)) return { kind: 'ignore' }\n if (event.code === 'Escape' || event.key === 'Escape') return { kind: 'cancel' }\n // Backspace/Delete = \u6E05\u9664\u7ED1\u5B9A\uFF08\u4E0E\u300C\u65E0\u300D\u7B49\u4EF7\uFF0C\u4F46\u8BED\u4E49\u66F4\u660E\u663E\uFF09\u3002\n if (event.code === 'Backspace' || event.code === 'Delete') return { kind: 'clear' }\n const chord = encodeChord(event)\n if (chord === '') return { kind: 'ignore' }\n if (!isBareKeyAllowed(chord)) {\n return {\n kind: 'reject',\n message: '\u5355\u4E2A\u5B57\u6BCD/\u6570\u5B57\u952E\u4F1A\u4E0E\u6253\u5B57\u51B2\u7A81\uFF0C\u8BF7\u914D\u5408 Ctrl / Alt / Shift \u4F7F\u7528\uFF0C\u6216\u9009\u62E9 Enter\u3002',\n }\n }\n return { kind: 'ok', chord }\n}\n\n/** \u952E\u4F4D\u663E\u793A\u6587\u672C\uFF1A'' \u2192 \u65E0\u3002 */\nexport function displayChord(chord: string): string {\n return chord === '' ? '\u65E0' : chord\n}\n", "/**\n * \u5FEB\u6377\u6307\u4EE4\u4E0E\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u8FD0\u884C\u65F6\u6865\u63A5\u3002\n *\n * \u4E3A\u4EC0\u4E48\u9700\u8981\u8FD9\u4E2A\u6A21\u5757\uFF1A\u8F93\u5165\u6846\u62E6\u622A\u5668\uFF08interceptors.ts\uFF09\u6D3B\u5728\u7EAF DOM / \u6355\u83B7\u9636\u6BB5\u91CC\uFF0C\n * \u62FF\u4E0D\u5230 React \u69FD\u4F4D\u624D\u6709\u7684 `inputActions` \u4E0E InputState \u8349\u7A3F\uFF1B\u800C\u300C\u70B9\u53D1\u9001\u65F6\u81EA\u52A8\u628A\n * \u63D0\u793A\u8BCD\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\u300D\u4E24\u6837\u90FD\u8981\u7528 \u2014\u2014 \u5F97\u77E5\u9053\u5F53\u524D\u8349\u7A3F\u662F\u4EC0\u4E48\uFF0C\u518D\u628A\u9644\u52A0\u540E\u7684\u6574\u6BB5\u5199\n * \u56DE\u7F16\u8F91\u5668\u3002\u4E8E\u662F\u7531 `conversation.input.right` \u7684\u6309\u94AE\u7EC4\u4EF6\u5728\u6BCF\u6B21\u6E32\u67D3\u65F6\u628A\u8FD9\u4E24\u6837\u4E1C\u897F\n * \u6295\u9012\u5230\u8FD9\u91CC\uFF0C\u62E6\u622A\u5668\u540C\u6B65\u8BFB\u53D6\u3002\n *\n * \u672C\u6A21\u5757\u96F6 React \u4F9D\u8D56\uFF0C\u53EF\u88AB\u62E6\u622A\u5668\u4E0E\u7EC4\u4EF6\u5171\u7528\u3002\n */\nimport type { QuickPrompt } from '../settings-contract.ts'\nimport { OPTIMIZER_API_PATH } from '../settings-contract.ts'\n\n/** \u5B98\u65B9\u516C\u5F00\u8F93\u5165\u52A8\u4F5C\u91CC\u672C\u6A21\u5757\u7528\u5230\u7684\u4E24\u4E2A\uFF08\u89C1 DSH \u7684 InputActions \u5951\u7EA6\uFF09\u3002 */\nexport interface InputActionsLike {\n /** \u6574\u4F53\u66FF\u6362\u8349\u7A3F\uFF08\u5B98\u65B9\u652F\u6301\u7684\u7A0B\u5E8F\u5316\u5199\u5165\u8DEF\u5F84\uFF09\u3002 */\n setDraft: (text: string) => void\n}\n\n/** \u8349\u7A3F\u6765\u6E90\uFF1A\u69FD\u4F4D\u5FEB\u7167\uFF08\u6743\u5A01\uFF09> DOM \u515C\u5E95\u3002 */\ninterface BridgeState {\n actions: InputActionsLike | null\n draft: string\n sessionId: string\n}\n\n/** \u8F93\u5165\u6846\u6839\u5143\u7D20\u7684\u9009\u62E9\u5668\uFF08\u4E0E interceptors.ts \u4FDD\u6301\u4E00\u81F4\uFF09\u3002 */\nconst COMPOSER_SELECTOR = '[data-composer-input]'\n\n/** \u8F93\u5165\u5361\u7247\u9009\u62E9\u5668\uFF08\u5B98\u65B9\u5728 InputBar \u4E0A\u5199\u7684\u6807\u8BB0\uFF09\u3002 */\nconst CARD_SELECTOR = '[data-composer-card]'\n\nconst state: BridgeState = { actions: null, draft: '', sessionId: '' }\n\n/**\n * \u69FD\u4F4D\u7EC4\u4EF6\u6BCF\u6B21\u6E32\u67D3\u6295\u9012\u4E00\u6B21\u6865\u63A5\u6570\u636E\u3002\n * @param next - \u672C\u4F1A\u8BDD\u7684\u8F93\u5165\u52A8\u4F5C\u3001\u5F53\u524D\u8349\u7A3F\u4E0E\u670D\u52A1\u7AEF\u4F1A\u8BDD id\u3002\n */\nexport function publishInputBridge(next: {\n readonly actions: InputActionsLike | null\n readonly draft: string\n readonly sessionId: string\n}): void {\n state.actions = next.actions\n state.draft = next.draft\n state.sessionId = next.sessionId\n}\n\n/**\n * \u5378\u8F7D\u65F6\u64A4\u4E0B\u6865\u63A5\uFF0C\u907F\u514D\u300C\u5207\u8D70\u7684\u4F1A\u8BDD\u300D\u7559\u4E0B\u7684\u65E7 actions \u88AB\u540E\u7EED\u624B\u52BF\u8BEF\u7528\u3002\n * \u53EA\u6E05\u81EA\u5DF1\u90A3\u4EFD\uFF1A\u540C\u4E00\u4E2A\u4F1A\u8BDD\u53EF\u80FD\u5148\u540E\u6302\u8F7D\u591A\u4E2A\u69FD\u4F4D\u6761\u76EE\u3002\n * @param sessionId - \u5378\u8F7D\u65B9\u6240\u5C5E\u4F1A\u8BDD id\u3002\n */\nexport function releaseInputBridge(sessionId: string): void {\n if (state.sessionId !== sessionId) return\n state.actions = null\n state.draft = ''\n state.sessionId = ''\n}\n\n/** DOM \u515C\u5E95\u8BFB\u8349\u7A3F\uFF08\u69FD\u4F4D\u672A\u6302\u8F7D\u65F6\u7684\u6700\u540E\u624B\u6BB5\uFF09\u3002 */\nfunction draftFromDom(): string {\n const el = document.querySelector(COMPOSER_SELECTOR)\n if (!(el instanceof HTMLElement)) return ''\n return el.innerText.replace(/\\n+$/, '')\n}\n\n/** \u5F53\u524D\u8349\u7A3F\uFF1A\u6709\u69FD\u4F4D\u5C31\u4FE1\u69FD\u4F4D\u5FEB\u7167\uFF0C\u5426\u5219\u8BFB DOM\u3002 */\nexport function currentDraft(): string {\n return state.actions === null ? draftFromDom() : state.draft\n}\n\n/** \u5F53\u524D\u4F1A\u8BDD id\uFF08'' = \u65E0\u4F1A\u8BDD\uFF09\u3002 */\nexport function currentSessionId(): string {\n return state.sessionId\n}\n\n/** \u53D6\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u6761\u76EE\uFF08\u4FDD\u6301\u5217\u8868\u987A\u5E8F\uFF0C\u4E22\u6389\u7A7A\u5185\u5BB9\uFF09\u3002 */\nexport function alwaysPrompts(prompts: readonly QuickPrompt[]): readonly QuickPrompt[] {\n return prompts.filter(item => item.always === true && item.prompt.trim() !== '')\n}\n\n/**\n * \u628A\u52FE\u4E86\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u6761\u76EE\u62FC\u5230\u539F\u6587**\u672B\u5C3E**\u3002\n *\n * \u89C4\u5219\uFF08\u4E0E\u7528\u6237\u786E\u8BA4\u8FC7\u7684\u8BED\u4E49\u4E00\u81F4\uFF09\uFF1A\n * - \u591A\u6761\u6309\u5217\u8868\u987A\u5E8F\u62FC\u63A5\uFF0C\u6761\u76EE\u4E4B\u95F4\u7A7A\u4E00\u884C\uFF1B\n * - \u539F\u6587\u4E3A\u7A7A\u65F6**\u4E0D\u9644\u52A0** \u2014\u2014 \u6CA1\u6709\u300C\u4F60\u7684\u6D88\u606F\u300D\u53EF\u9644\u52A0\uFF0C\u6B64\u65F6\u5E94\u5F53\u4EA4\u8FD8\u5B98\u65B9\u539F\u8BED\u4E49\n * \uFF08\u7A7A\u8F93\u5165\u7684 Enter \u5728\u5B98\u65B9\u90A3\u91CC\u662F\u522B\u7684\u52A8\u4F5C\uFF0C\u62A2\u8FC7\u6765\u4F1A\u8BA9\u4EBA\u610F\u5916\uFF09\uFF1B\n * - \u4E00\u6761\u90FD\u6CA1\u52FE\u65F6\u8FD4\u56DE null\uFF1B\n * - **\u5DF2\u7ECF\u4EE5\u540C\u4E00\u6BB5\u540E\u7F00\u7ED3\u5C3E\u65F6\u8FD4\u56DE null\uFF08\u5E42\u7B49\uFF09** \u2014\u2014 \u4E07\u4E00\u53D1\u9001\u90A3\u4E00\u6B65\u6CA1\u6210\uFF0C\u7B2C\u4E8C\u6B21\n * \u70B9\u51FB\u4E0D\u4F1A\u628A\u540C\u4E00\u6BB5\u63D0\u793A\u8BCD\u518D\u53E0\u4E00\u904D\uFF0C\u800C\u662F\u76F4\u63A5\u653E\u884C\u5B98\u65B9\u53D1\u9001\uFF080.2.0 \u7684\u5931\u63A7\u75C7\u72B6\u5C31\u662F\n * \u300C\u4E00\u76F4\u70B9\u4E00\u76F4\u63D2\u5165\u300D\uFF0C\u8FD9\u6761\u62A4\u680F\u8BA9\u5B83\u53D8\u6210\u300C\u518D\u70B9\u4E00\u6B21\u5C31\u53D1\u51FA\u53BB\u300D\uFF09\u3002\n * @param draft - \u5F53\u524D\u8349\u7A3F\u539F\u6587\u3002\n * @param prompts - \u5B8C\u6574\u5FEB\u6377\u6307\u4EE4\u5217\u8868\u3002\n * @returns \u62FC\u63A5\u540E\u7684\u5B8C\u6574\u8349\u7A3F\uFF1B\u65E0\u9700\u9644\u52A0\u65F6\u4E3A null\u3002\n */\nexport function withAlwaysPrompts(draft: string, prompts: readonly QuickPrompt[]): string | null {\n const picked = alwaysPrompts(prompts)\n if (picked.length === 0) return null\n const base = draft.replace(/\\s+$/, '')\n if (base === '') return null\n const suffix = picked.map(item => item.prompt.trim()).join('\\n\\n')\n if (base.endsWith(suffix)) return null\n return `${base}\\n\\n${suffix}`\n}\n\n/**\n * \u628A\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u5199\u56DE\u7F16\u8F91\u5668\u3002\n *\n * \u53EA\u8D1F\u8D23\u5199\u5165\uFF0C\u4E0D\u8D1F\u8D23\u53D1\u9001\uFF1A\u53D1\u9001\u52A8\u4F5C\u4EA4\u8FD8\u5B98\u65B9\u624B\u52BF\uFF08\u89C1 interceptors.ts \u7684\u4E24\u6761\u8DEF\u5F84\uFF09\uFF0C\n * \u8FD9\u6837\u300C\u53D1\u9001 / \u6392\u961F / \u6253\u65AD\u300D\u7684\u8BED\u4E49\u5B8C\u5168\u7531\u5B98\u65B9\u51B3\u5B9A\uFF0C\u672C\u63D2\u4EF6\u4E0D\u505A\u7B2C\u4E8C\u5957\u5224\u65AD\u3002\n * @param prompts - \u5B8C\u6574\u5FEB\u6377\u6307\u4EE4\u5217\u8868\u3002\n * @returns true = \u5DF2\u5199\u5165\uFF08\u8C03\u7528\u65B9\u5E94\u7EE7\u7EED\u8D70\u5B98\u65B9\u53D1\u9001\u624B\u52BF\uFF09\uFF1Bfalse = \u65E0\u9700\u9644\u52A0\u3002\n */\nexport function applyAlwaysPrompts(prompts: readonly QuickPrompt[]): boolean {\n const actions = state.actions\n if (actions === null) return false\n const next = withAlwaysPrompts(currentDraft(), prompts)\n if (next === null) return false\n actions.setDraft(next)\n return true\n}\n\n/** \u628A\u4E00\u6BB5\u6587\u672C\u63D2\u8FDB\u8F93\u5165\u6846\uFF08\u6761\u76EE\u70B9\u51FB\u63D2\u5165\u7528\uFF1B\u539F\u6709\u5185\u5BB9\u4FDD\u7559\uFF0C\u65B0\u5185\u5BB9\u53E6\u8D77\u4E00\u884C\uFF09\u3002 */\nexport function insertIntoDraft(text: string): boolean {\n const actions = state.actions\n const body = text.trim()\n if (actions === null || body === '') return false\n const draft = currentDraft()\n const next = draft.trim() === '' ? body : `${draft.replace(/\\s+$/, '')}\\n${body}`\n actions.setDraft(next)\n return true\n}\n\n/** \u6574\u4F53\u66FF\u6362\u8349\u7A3F\uFF08\u4F18\u5316\u7ED3\u679C\u5199\u56DE\u7528\uFF09\u3002 */\nexport function replaceDraft(text: string): boolean {\n const actions = state.actions\n if (actions === null) return false\n actions.setDraft(text)\n return true\n}\n\n/** \u628A\u7126\u70B9\u4EA4\u8FD8\u8F93\u5165\u6846\uFF08\u63D2\u5165/\u5199\u56DE\u4E4B\u540E\u8C03\u7528\uFF0C\u65B9\u4FBF\u63A5\u7740\u6253\u5B57\uFF09\u3002 */\nexport function focusComposer(): void {\n const el = document.querySelector(COMPOSER_SELECTOR)\n if (el instanceof HTMLElement) el.focus({ preventScroll: true })\n}\n\n/**\n * \u627E\u51FA\u8FD9\u6B21\u70B9\u51FB\u843D\u5728\u7684**\u5B98\u65B9\u53D1\u9001\u4E3B\u6309\u94AE**\uFF1B\u4E0D\u662F\u53D1\u9001\u952E\u65F6\u8FD4\u56DE null\u3002\n *\n * \u4E3A\u4EC0\u4E48\u8FD4\u56DE\u5143\u7D20\u800C\u4E0D\u662F\u5E03\u5C14\uFF1A\u8C03\u7528\u65B9\u8981\u62FF\u5B83**\u91CD\u653E\u4E00\u6B21\u70B9\u51FB**\uFF08\u89C1 interceptors.ts\uFF09\u3002\n * \u8FD9\u91CC\u5FC5\u987B\u8FD4\u56DE\u771F\u6B63\u7684 `<button>`\uFF0C\u800C\u4E0D\u662F `event.target` \u2014\u2014 \u53D1\u9001\u952E\u662F\u4E2A\u5706\u5F62\u6309\u94AE\uFF0C\n * \u89C6\u89C9\u4E2D\u5FC3\u5C31\u662F\u91CC\u9762\u7684 `<svg>` / `<path>`\uFF0C\u800C **SVG \u5143\u7D20\u6CA1\u6709 `.click()`**\u3002\n * 0.2.0 \u5C31\u662F\u56E0\u4E3A\u628A `event.target` \u5F53\u6309\u94AE\u7528\u3001`click()` \u629B TypeError \u800C\u6CA1\u53D1\u9001\uFF0C\n * \u75C7\u72B6\u662F\u300C\u70B9\u4E86\u53EA\u63D2\u5165\u3001\u4E0D\u53D1\u9001\uFF0C\u4E00\u76F4\u70B9\u4E00\u76F4\u63D2\u5165\u300D\u3002\n *\n * \u4E3A\u4EC0\u4E48\u6562\u6309\u7ED3\u6784\u5224\u522B\uFF1A\u53D1\u9001\u952E\u4E0E\u505C\u6B62\u952E\u5171\u7528\u540C\u4E00\u4E2A\u4F4D\u7F6E\uFF08\u5361\u7247\u91CC\u6700\u540E\u4E00\u4E2A button\uFF09\uFF0C\n * \u53EA\u80FD\u9760\u56FE\u5F62\u533A\u5206 \u2014\u2014 \u505C\u6B62\u6E32\u67D3 `<rect>`\uFF08\u65B9\u5757\uFF09\uFF0C\u53D1\u9001\u6E32\u67D3 `<path>`\uFF08\u7BAD\u5934\uFF09\u3002\n * \u6309\u56FE\u5F62\u5224\u522B\u4E0E\u754C\u9762\u6587\u6848\u3001\u8BED\u8A00\u90FD\u65E0\u5173\uFF0C\u4E2D\u82F1\u6587\u73AF\u5883\u4E00\u81F4\u3002\n * @param target - \u4E8B\u4EF6\u76EE\u6807\uFF08\u53EF\u80FD\u662F\u6309\u94AE\u672C\u8EAB\uFF0C\u4E5F\u53EF\u80FD\u662F\u5B83\u5185\u90E8\u7684\u56FE\u6807\uFF09\u3002\n * @returns \u5B98\u65B9\u53D1\u9001\u4E3B\u6309\u94AE\uFF1B\u65E0\u6CD5\u786E\u5B9A\u65F6 null\uFF08\u6B64\u65F6\u8C03\u7528\u65B9\u5FC5\u987B**\u4E0D\u62E6\u622A**\uFF09\u3002\n */\nexport function sendButtonOf(target: EventTarget | null): HTMLButtonElement | null {\n if (!(target instanceof Element)) return null\n const card = target.closest(CARD_SELECTOR)\n if (card === null) return null\n const buttons = card.querySelectorAll('button')\n if (buttons.length === 0) return null\n const last = buttons[buttons.length - 1]!\n // \u5FC5\u987B\u662F\u771F\u6B63\u7684 <button>\uFF1A\u62FF\u5230\u7684\u82E5\u662F svg\uFF0C\u91CD\u653E\u70B9\u51FB\u4F1A\u5931\u8D25\u3002\n if (!(last instanceof HTMLButtonElement)) return null\n if (last !== target && !last.contains(target)) return null\n if (last.disabled) return null\n // \u505C\u6B62\u952E\uFF1A\u65B9\u5757\u56FE\u6807\u3002\u53D1\u9001\u952E\uFF1A\u7BAD\u5934 path\u3002\n if (last.querySelector('svg rect') !== null) return null\n if (last.querySelector('svg path') === null) return null\n return last\n}\n\n/** \u4E00\u6B21\u4F18\u5316\u7684\u7ED3\u679C\u3002 */\nexport interface OptimizeOutcome {\n readonly ok: boolean\n /** \u6210\u529F\u65F6\uFF1A\u4F18\u5316\u540E\u7684\u6B63\u6587\u3002 */\n readonly text?: string\n /** \u5931\u8D25\u65F6\uFF1A\u7ED9\u7528\u6237\u770B\u7684\u4E00\u53E5\u8BDD\u539F\u56E0\u3002 */\n readonly error?: string\n /** \u6210\u529F\u65F6\uFF1A\u5B9E\u9645\u4F7F\u7528\u7684\u8DEF\u7531\uFF08\u7528\u4E8E\u300C\u4F18\u5316\u6CA1\u751F\u6548\u300D\u65F6\u7684\u6392\u67E5\uFF09\u3002 */\n readonly route?: string\n}\n\n/**\n * \u8BF7\u5BBF\u4E3B\u534A\u8DD1\u4E00\u6B21\u72EC\u7ACB\u4F18\u5316\u3002\n *\n * \u4E3A\u4EC0\u4E48\u662F\u4E00\u6B21 HTTP \u5F80\u8FD4\uFF1A\u51FA\u7F51\u8BF7\u6C42\u7531\u5BBF\u4E3B\u7684\u6A21\u578B\u9002\u914D\u5668\u53D1\u51FA\uFF0C\u6D4F\u89C8\u5668\u4FA7\u78B0\u4E0D\u5230\u6A21\u578B\u8DEF\u7531\uFF1B\n * \u5BBF\u4E3B <-> \u5BA2\u6237\u7AEF\u4E4B\u95F4\u6CA1\u6709\u522B\u7684\u53D7\u652F\u6301\u901A\u9053\uFF08\u4E0E WestFox \u7684\u63D2\u4EF6\u540C\u6784\uFF09\u3002\n * @param text - \u8F93\u5165\u6846\u91CC\u7684\u539F\u6587\u3002\n * @param tier - \u5F3A\u5EA6\u6863\u4F4D\u3002\n * @returns \u4F18\u5316\u7ED3\u679C\uFF1B\u7F51\u7EDC\u5C42\u5931\u8D25\u4E5F\u5F52\u4E00\u6210 `ok: false` \u800C\u4E0D\u629B\u3002\n */\nexport async function optimizeDraft(text: string, tier: string): Promise<OptimizeOutcome> {\n const body = text.trim()\n if (body === '') return { ok: false, error: '\u8F93\u5165\u6846\u662F\u7A7A\u7684\uFF0C\u5148\u5199\u70B9\u4EC0\u4E48\u518D\u4F18\u5316' }\n let response: Response\n try {\n response = await fetch(OPTIMIZER_API_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ text: body, tier }),\n })\n } catch (error) {\n return { ok: false, error: `\u8FDE\u4E0D\u4E0A\u5BBF\u4E3B\u534A\u7684\u4F18\u5316\u63A5\u53E3\uFF1A${error instanceof Error ? error.message : String(error)}` }\n }\n if (!response.ok) {\n return { ok: false, error: `\u5BBF\u4E3B\u534A\u8FD4\u56DE HTTP ${response.status}\uFF08\u63D2\u4EF6\u53EF\u80FD\u8FD8\u6CA1\u91CD\u542F\u751F\u6548\uFF09` }\n }\n let payload: unknown\n try {\n payload = await response.json()\n } catch {\n return { ok: false, error: '\u5BBF\u4E3B\u534A\u8FD4\u56DE\u7684\u4E0D\u662F JSON' }\n }\n const record = (typeof payload === 'object' && payload !== null ? payload : {}) as Record<string, unknown>\n if (record.ok !== true) {\n const message = typeof record.error === 'string' && record.error !== '' ? record.error : '\u4F18\u5316\u5931\u8D25'\n return { ok: false, error: message }\n }\n const optimized = typeof record.text === 'string' ? record.text.trim() : ''\n if (optimized === '') return { ok: false, error: '\u6A21\u578B\u6CA1\u6709\u4EA7\u51FA\u4EFB\u4F55\u5185\u5BB9' }\n const route = `${String(record.provider ?? '')}/${String(record.model ?? '')}`\n return { ok: true, text: optimized, route }\n}\n", "/** \u8F93\u5165\u6846\u62E6\u622A\u5668\uFF1A\u63A5\u7BA1 Enter \u5BB6\u65CF\u952E\u4F4D\uFF08\u53D1\u9001/\u6362\u884C\uFF09\u4E0E\u53F3\u952E\u83DC\u5355\u3002\n * \u4E0E React \u65E0\u5173\uFF1A\u57FA\u4E8E\u300C\u6355\u83B7\u9636\u6BB5 + \u76EE\u6807\u9650\u5B9A + \u5408\u6210\u56DE\u653E\u300D\u7684\u62E6\u622A\u6A21\u578B\u3002\n *\n * \u952E\u4F4D\u89C4\u5219\uFF08\u603B\u62EC\uFF09\uFF1A\n * - \u8BB0\u5F55\u76EE\u6807\u53EA\u5728\u4E3B\u804A\u5929\u8F93\u5165\u6846 [data-composer-input] \u5185\uFF1B\n * - IME \u7EC4\u5408\u671F\u95F4\uFF08isComposing / keyCode 229\uFF09\u4E00\u5F8B\u653E\u884C\uFF0C\u7EDD\u4E0D\u5F71\u54CD\u4E2D\u6587\u8F93\u5165\uFF1B\n * - '/' '@' \u89E6\u53D1\u5668\u83DC\u5355\u6216\u4EFB\u4F55\u8F93\u5165\u6846 overlay \u6253\u5F00\u65F6\u653E\u884C Enter\uFF0C\u8BA9\u83DC\u5355\u4EF2\u88C1\u4F18\u5148\uFF1B\n * - \u547D\u4E2D\u300C\u53D1\u9001\u952E\u4F4D\u300D\u2192 \u56DE\u653E\u5E26 Ctrl \u52A0\u901F\u8BED\u4E49\u4E4B\u5916\u7684\u666E\u901A Enter\uFF08\u8D70\u5B98\u65B9\u63D0\u4EA4\u7BA1\u7EBF\uFF09\uFF1B\n * - \u547D\u4E2D\u300C\u6362\u884C\u952E\u4F4D\u300D\u2192 \u56DE\u653E Shift+Enter\uFF08\u5B98\u65B9\u6362\u884C\u7BA1\u7EBF\uFF09\uFF1B\n * - Ctrl+Enter / Meta+Enter \u82E5\u672A\u88AB\u7ED1\u5B9A\uFF0C\u5219\u56DE\u653E\u539F\u7EC4\u5408\uFF0C\u4FDD\u7559\u5B98\u65B9\u300C\u52A0\u901F\u63D0\u4EA4\u300D\u884C\u4E3A\uFF1B\n * - \u5176\u4F59 Enter \u5BB6\u65CF\u7EC4\u5408\uFF1A\u6D88\u8017\u4F46\u4E0D\u52A8\u4F5C\uFF08\u7528\u6237\u663E\u5F0F\u53D6\u6D88\u7684\u539F\u751F\u8BED\u4E49\uFF09\u3002\n *\n * \u5173\u952E\u5B88\u536B\uFF1A\u5408\u6210\u56DE\u653E\u4E8B\u4EF6\u4E5F\u5FC5\u987B\u7ECF\u8FC7 window \u6355\u83B7\u76D1\u542C\u5668\uFF0C\u56E0\u6B64\u56DE\u653E\u671F\u95F4\u7528\n * \u540C\u6B65\u6807\u5FD7\u8DF3\u8FC7\u81EA\u8EAB\u62E6\u622A\uFF0C\u5426\u5219\u53D1\u9001/\u6362\u884C\u56DE\u653E\u4F1A\u65E0\u9650\u81EA\u89E6\u53D1\u3002\n */\nimport {\n chordToInit, encodeChord, isEnterFamily, type ChordEvent,\n} from './chords.ts'\nimport { applyAlwaysPrompts, sendButtonOf } from './quick-commands.ts'\nimport type { ComposerUxSettings, MenuState } from '../settings-contract.ts'\n\nexport interface InterceptorDeps {\n /** \u540C\u6B65\u8BFB\u53D6\u5F53\u524D\u89E3\u6790\u540E\u7684\u8BBE\u7F6E\uFF08\u62E6\u622A\u5668\u975E React \u73AF\u5883\uFF09\u3002 */\n readonly settings: () => ComposerUxSettings\n /** \u6253\u5F00 / \u5173\u95ED\u53F3\u952E\u83DC\u5355\u3002 */\n readonly setMenu: (state: MenuState | null) => void\n /** \u81EA\u5B9A\u4E49\u83DC\u5355\u5F53\u524D\u662F\u5426\u6253\u5F00\uFF08\u539F\u751F\u83DC\u5355\u6A21\u5F0F\u4E0B\u9700\u8981\u6E05\u6389\uFF09\u3002 */\n readonly menuOpen: () => boolean\n}\n\nconst INPUT_SELECTOR = '[data-composer-input]'\nconst OVERLAY_SELECTOR = '[data-trigger-menu], [data-conversation-composer-overlay]'\n\n/** \u76EE\u6807\u662F\u5426\u843D\u5728\u4E3B\u804A\u5929\u8F93\u5165\u6846\u53CA\u5176\u5185\u90E8\u3002 */\nfunction findComposerRoot(target: EventTarget | null): HTMLElement | null {\n if (!(target instanceof Element)) return null\n return target.closest<HTMLElement>(INPUT_SELECTOR)\n}\n\n/** \u89E6\u53D1\u5668\u83DC\u5355\uFF08'/' '@'\uFF09\u6216\u8F93\u5165\u6846 overlay \u662F\u5426\u6253\u5F00\u3002 */\nfunction overlayOpen(): boolean {\n return document.querySelector(OVERLAY_SELECTOR) !== null\n}\n\n/** \u56DE\u653E\u8FDB\u884C\u4E2D\u6807\u5FD7\uFF1A\u5408\u6210\u4E8B\u4EF6\u56DE\u5230\u6355\u83B7\u76D1\u542C\u5668\u65F6\u8DF3\u8FC7\u81EA\u8EAB\u62E6\u622A\u3002 */\nlet replaying = false\n\n/** \u5B98\u65B9\u53D1\u9001\u6309\u94AE\u7684\u300C\u5148\u5199\u56DE\u3001\u518D\u91CD\u653E\u300D\u6807\u5FD7\uFF08\u907F\u514D\u5408\u6210\u70B9\u51FB\u88AB\u81EA\u5DF1\u518D\u62E6\u4E00\u6B21\uFF09\u3002 */\nlet replayingSendClick = false\n\n/** \u53F3\u952E\u65F6\u9884\u8BFB\u6210\u529F\u7684\u526A\u8D34\u677F\u6587\u672C\u7F13\u5B58\uFF08null = \u672A\u9884\u8BFB/\u9884\u8BFB\u5931\u8D25\uFF09\u3002 */\nlet pasteCache: string | null = null\n\n/** \u5728\u53F3\u952E\u624B\u52BF\u91CC\u53D1\u8D77\u4E00\u6B21\u9759\u9ED8\u9884\u8BFB\uFF1A\u6388\u6743\u6D6E\u7A97\u6B64\u523B\u51FA\u73B0\uFF0C\u7528\u6237\u987A\u624B\u70B9\u4E00\u6B21\u5373\u53EF\u3002 */\nfunction prefetchClipboard(): void {\n pasteCache = null\n const readText = (navigator as Navigator & { clipboard?: { readText?: () => Promise<string> } }).clipboard?.readText\n if (typeof readText !== 'function') return\n readText.call(navigator.clipboard).then(\n (text: string) => { pasteCache = text },\n () => { pasteCache = null },\n )\n}\n\n/** \u5411\u8F93\u5165\u6846\u6839\u5143\u7D20\u6D3E\u53D1\u5408\u6210\u6309\u952E\uFF08\u89E6\u53D1 Lexical \u81EA\u8EAB\u952E\u76D8\u7BA1\u7EBF\uFF09\u3002 */\nfunction dispatchKey(root: HTMLElement, init: KeyboardEventInit): void {\n replaying = true\n try {\n root.dispatchEvent(new KeyboardEvent('keydown', init))\n } finally {\n replaying = false\n }\n}\n\n/** \u662F\u5426\u8FDB\u5165 IME \u7EC4\u5408\uFF08\u5408\u6210\u4E8B\u4EF6\u9700\u4E0E\u771F\u5B9E\u6309\u952E\u8D70\u540C\u4E00\u5B88\u536B\uFF09\u3002 */\nfunction composing(event: KeyboardEvent): boolean {\n // oxlint-disable-next-line typescript/no-deprecated\n return event.isComposing || event.keyCode === 229\n}\n\n/** \u5B89\u88C5\u4E24\u4E2A\u6355\u83B7\u9636\u6BB5\u62E6\u622A\u5668\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\u3002 */\nexport function installInterceptors(deps: InterceptorDeps): () => void {\n const onKeyDown = (event: KeyboardEvent): void => {\n if (replaying) return\n const root = findComposerRoot(event.target)\n if (root === null) return\n if (composing(event)) return\n const chord = encodeChord(event as unknown as ChordEvent)\n if (!isEnterFamily(chord)) return\n // \u83DC\u5355/overlay \u6253\u5F00\u65F6\uFF0CEnter \u8981\u7ED9\u83DC\u5355\u4EF2\u88C1\uFF08\u8865\u5168\u9009\u62E9\u3001\u5F39\u5C42\u5173\u95ED\uFF09\u8BA9\u8DEF\u3002\n if (overlayOpen()) return\n\n const settings = deps.settings()\n const gesture = chord === settings.sendKey\n ? 'send'\n : chord === settings.newlineKey\n ? 'newline'\n : (chord === 'Ctrl+Enter' || chord === 'Meta+Enter') ? 'accelerated'\n : 'none'\n\n event.preventDefault()\n event.stopPropagation()\n // \u957F\u6309\u8FDE\u53D1\uFF1A\u6D88\u8017\u4E00\u6B21\u5373\u53EF\uFF08\u53D1\u9001\u9632\u673A\u67AA\u95E8\u4E0E\u5B98\u65B9\u4E00\u81F4\uFF0C\u6362\u884C\u8FDE\u53D1\u65E0\u610F\u4E49\uFF09\u3002\n if (event.repeat) return\n\n if (gesture === 'send') {\n // \u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF1A\u5148\u628A\u52FE\u9009\u7684\u63D0\u793A\u8BCD\u5199\u56DE\u7F16\u8F91\u5668\u672B\u5C3E\uFF0C\u518D\u56DE\u653E\u53D1\u9001\u624B\u52BF \u2014\u2014\n // \u5B98\u65B9\u624B\u52BF\u7167\u65E7\uFF08\u542B\u8FD0\u884C\u4E2D\u300C\u6392\u961F / \u6253\u65AD\u300D\u7684\u5224\u5B9A\uFF09\uFF0C\u672C\u63D2\u4EF6\u4E0D\u505A\u7B2C\u4E8C\u5957\u5224\u65AD\u3002\n // \u539F\u6587\u4E3A\u7A7A\u65F6 applyAlwaysPrompts \u8FD4\u56DE false\uFF0C\u4E00\u5207\u7167\u65E7\u3002\n applyAlwaysPrompts(settings.quickPrompts)\n dispatchKey(root, chordToInit('Enter'))\n } else if (gesture === 'newline') {\n dispatchKey(root, chordToInit('Shift+Enter'))\n } else if (gesture === 'accelerated') {\n dispatchKey(root, chordToInit('Ctrl+Enter'))\n }\n // gesture === 'none'\uFF1A\u6D88\u8017\u4F46\u65E0\u52A8\u4F5C\u3002\n }\n\n const onContextMenu = (event: MouseEvent): void => {\n const root = findComposerRoot(event.target)\n if (root === null) return\n // \u539F\u751F\u83DC\u5355\u6A21\u5F0F\uFF1A\u4E0D\u8BA9\u7B2C\u4E09\u65B9\u63D2\u4EF6\uFF08\u5982 dsh-paste-input-plus \u7684\u300C\u53EA\u6709\u590D\u5236\u300D\u83DC\u5355\uFF09\n // \u5403\u6389 contextmenu\u2014\u2014\u6211\u4EEC\u6392\u5728 capture \u9636\u6BB5\u5148\u6267\u884C\uFF0CstopImmediatePropagation \u540E\n // \u4E8B\u4EF6\u5230\u4E0D\u4E86 bubble \u9636\u6BB5\u7684\u63D2\u4EF6\u76D1\u542C\u5668\uFF1B\u4F46\u4E0D preventDefault\uFF0C\u6D4F\u89C8\u5668\u539F\u751F\u83DC\u5355\u7167\u5E38\u51FA\u73B0\u3002\n if (deps.settings().menuNative) {\n if (deps.menuOpen()) deps.setMenu(null)\n event.stopImmediatePropagation()\n event.stopPropagation()\n return\n }\n event.preventDefault()\n event.stopPropagation()\n const selection = window.getSelection()\n const hasSelection = selection !== null\n && !selection.isCollapsed\n && selection.anchorNode !== null\n && root.contains(selection.anchorNode)\n deps.setMenu({ x: event.clientX, y: event.clientY, hasSelection })\n // \u8D81\u7740\u53F3\u952E\u7684\u7528\u6237\u624B\u52BF\u8FD8\u5728\uFF0C\u9759\u9ED8\u9884\u8BFB\u526A\u8D34\u677F\uFF08\u6388\u6743\u6D6E\u7A97\u6B64\u523B\u5F39\u51FA\uFF0C\u70B9\u4E00\u6B21\u5373\u56FA\u5316\uFF09\u3002\n prefetchClipboard()\n }\n\n /**\n * \u5B98\u65B9\u300C\u53D1\u9001\u300D\u6309\u94AE\u4E0A\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u3002\n *\n * \u5B98\u65B9\u4E3B\u6309\u94AE\u8D70\u7684\u662F\u5305\u5185\u90E8\u7684 keyboard.submit\uFF08\u6CA1\u6709\u5BF9\u5916\u7684\u62E6\u622A\u94A9\u5B50\uFF09\uFF0C\u6240\u4EE5\u53EA\u80FD\u5728\n * \u6355\u83B7\u9636\u6BB5\u8BA4\u4E0B\u8FD9\u6B21\u70B9\u51FB\u3002\u8BA4\u4E0B\u4E4B\u540E\u4E0D\u53BB\u81EA\u5DF1\u8C03 submit \u2014\u2014 \u800C\u662F\u5148\u628A\u9644\u52A0\u5185\u5BB9\u5199\u56DE\u7F16\u8F91\u5668\u3001\n * \u518D\u7528\u540C\u4E00\u4E2A\u6309\u94AE\u91CD\u653E\u4E00\u6B21\u70B9\u51FB\uFF0C\u8BA9\u5B98\u65B9\u7684 primarySubmitMode\uFF08\u53D1\u9001 / \u6392\u961F / \u6253\u65AD\uFF09\n * \u539F\u6837\u751F\u6548\u3002\n *\n * \u4E24\u6761\u5FC5\u987B\u5B88\u4F4F\u7684\u7EAA\u5F8B\uFF080.2.0 \u5728\u8FD9\u4E24\u5904\u90FD\u51FA\u8FC7\u4E8B\uFF09\uFF1A\n * 1. \u91CD\u653E\u7684\u5FC5\u987B\u662F `sendButtonOf()` \u8FD4\u56DE\u7684**\u771F <button>**\uFF0C\u4E0D\u80FD\u662F event.target\n * \u2014\u2014 \u70B9\u5728\u5706\u5F62\u6309\u94AE\u7684\u89C6\u89C9\u4E2D\u5FC3\u65F6 target \u662F\u5185\u90E8\u7684 svg\uFF0Csvg \u6CA1\u6709 `.click()`\uFF0C\n * \u4F1A\u629B TypeError\uFF0C\u7ED3\u679C\u5C31\u662F\u300C\u5DF2\u63D2\u5165\u4F46\u6CA1\u53D1\u9001\u300D\u3002\n * 2. \u53EA\u6709\u5728\u786E\u8BA4\u80FD\u91CD\u653E\u4E4B\u540E\u624D preventDefault/stopPropagation\uFF1B\u62FF\u4E0D\u5230\u6309\u94AE\u5C31\u76F4\u63A5\n * \u653E\u884C\uFF0C\u7EDD\u4E0D\u628A\u7528\u6237\u8FD9\u6B21\u70B9\u51FB\u541E\u6389\u3002\n */\n const onClickSend = (event: MouseEvent): void => {\n if (replayingSendClick) return\n const button = sendButtonOf(event.target)\n if (button === null) return\n if (!applyAlwaysPrompts(deps.settings().quickPrompts)) return\n event.preventDefault()\n event.stopPropagation()\n replayingSendClick = true\n try {\n button.click()\n } finally {\n replayingSendClick = false\n }\n }\n\n window.addEventListener('keydown', onKeyDown, true)\n window.addEventListener('contextmenu', onContextMenu, true)\n window.addEventListener('click', onClickSend, true)\n return () => {\n window.removeEventListener('keydown', onKeyDown, true)\n window.removeEventListener('contextmenu', onContextMenu, true)\n window.removeEventListener('click', onClickSend, true)\n }\n}\n\n/** \u53F3\u952E\u83DC\u5355\u52A8\u4F5C id\uFF08\u4E0E MENU_ITEMS \u5BF9\u5E94\uFF09\u3002 */\nexport type MenuActionId = 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'delete' | 'selectAll'\n\nexport interface MenuActionResult {\n readonly ok: boolean\n readonly message?: string\n}\n\n/** \u5728\u5F53\u524D\u8F93\u5165\u6846\u4E0A\u6267\u884C\u4E00\u4E2A\u53F3\u952E\u83DC\u5355\u52A8\u4F5C\u3002 */\nexport async function runMenuAction(id: MenuActionId): Promise<MenuActionResult> {\n const root = document.querySelector<HTMLElement>(INPUT_SELECTOR)\n if (root === null) return { ok: false, message: '\u627E\u4E0D\u5230\u8F93\u5165\u6846' }\n if (!document.activeElement || !root.contains(document.activeElement)) {\n if (root.isConnected) {\n root.focus({ preventScroll: true })\n }\n }\n switch (id) {\n case 'undo':\n dispatchKey(root, chordToInit('Ctrl+Z'))\n return { ok: true }\n case 'redo':\n dispatchKey(root, chordToInit('Ctrl+Y'))\n return { ok: true }\n case 'copy':\n return { ok: document.execCommand('copy') }\n case 'cut':\n return { ok: document.execCommand('cut') }\n case 'delete':\n return { ok: document.execCommand('delete') }\n case 'selectAll':\n return { ok: document.execCommand('selectAll') }\n case 'paste':\n return pasteText(root)\n }\n}\n\n/** \u5E26\u8D85\u65F6\u7684 Promise\uFF08\u7528\u4E8E\u7B49\u5F85\u526A\u8D34\u677F\u6388\u6743\u5F39\u7A97\uFF09\u3002 */\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => { reject(new Error('clipboard-read timeout')) }, ms)\n promise.then(\n (value) => { clearTimeout(timer); resolve(value) },\n (error: unknown) => { clearTimeout(timer); reject(error) },\n )\n })\n}\n\nfunction isClipboardTimeout(error: unknown): boolean {\n return error instanceof Error && error.message === 'clipboard-read timeout'\n}\n\n/** Firefox\uFF1A\u526A\u8D34\u677F\u6388\u6743\u4E0D\u8FDB\u7AD9\u70B9\u6743\u9650\u9762\u677F\uFF0C\u53EA\u80FD\u9760 about:config \u5168\u5C40\u5141\u8BB8\u4E00\u6B21\u3002 */\nfunction isFirefox(): boolean {\n return typeof navigator !== 'undefined' && /Firefox\\//.test(navigator.userAgent)\n}\n\n/** Firefox \u4E00\u6B21\u6027\u914D\u7F6E\u6307\u5F15\uFF08\u5168\u5C40\u5141\u8BB8\u8BFB\u526A\u8D34\u677F\uFF0Cafter:config \u65B0\u5EFA\u6574\u6570\uFF0C\u6539\u5B8C\u7ACB\u5373\u751F\u6548\uFF09\u3002 */\nconst FIREFOX_TIP = 'Firefox \u6BCF\u6B21\u8BFB\u526A\u8D34\u677F\u90FD\u8981\u70B9\u300C\u7C98\u8D34(P)\u300D\u786E\u8BA4\uFF1A\u5730\u5740\u680F\u8F93\u5165 about:config \u2192 \u63A5\u53D7\u98CE\u9669\u7EE7\u7EED \u2192 \u53F3\u952E\u65B0\u5EFA\u300C\u6574\u6570\u300D\u2192 \u540D\u79F0\u586B permissions.default.clipboard-read \u2192 \u503C\u586B 1 \u2192 \u91CD\u8FDB DSH\uFF1B\u4E4B\u540E\u70B9\u4E00\u6B21\u7C98\u8D34\u5373\u6210\u529F\uFF08\u6216\u76F4\u63A5 Ctrl+V\uFF09'\n\n/** \u7C98\u8D34\uFF1A\u8BFB\u526A\u8D34\u677F\u540E\u5728\u5149\u6807\u5904\u63D2\u5165\u7EAF\u6587\u672C\u3002\n * \u6D4F\u89C8\u5668\u5B89\u5168\u6A21\u578B\uFF1A\u5199\u526A\u8D34\u677F\uFF08\u590D\u5236/\u526A\u5207\uFF09\u514D\u6388\u6743\uFF0C\u8BFB\u526A\u8D34\u677F\uFF08\u7C98\u8D34\uFF09\u5FC5\u987B\u6388\u6743\uFF0C\n * \u4EFB\u4F55\u7F51\u9875\u90FD\u65E0\u6CD5\u7ED5\u8FC7\u2014\u2014\u4F46\u9996\u6B21\u6388\u6743\u540E\u6D4F\u89C8\u5668\u4F1A\u8BB0\u4F4F\u8BE5\u7AD9\u70B9\uFF0C\u4E4B\u540E\u9759\u9ED8\u53EF\u7528\u3002\n * \u4F18\u5148\u4F7F\u7528\u53F3\u952E\u65F6\u9884\u8BFB\u7684\u7F13\u5B58\uFF08\u6388\u6743\u5DF2\u88AB\u70B9\u51FB\u8FC7\u4E00\u6B21\uFF0C\u65E0\u611F\uFF09\uFF0C\u5931\u8D25\u518D\u5B9E\u65F6\u8BFB\u53D6\u3002\n */\nasync function pasteText(root: HTMLElement): Promise<MenuActionResult> {\n const insertText = (text: string): MenuActionResult => {\n if (!document.activeElement || !root.contains(document.activeElement)) {\n root.focus({ preventScroll: true })\n }\n if (text === '') return { ok: true }\n return { ok: document.execCommand('insertText', false, text) }\n }\n // \u7F13\u5B58\u547D\u4E2D\uFF1A\u53F3\u952E\u65F6\u6388\u6743\u5DF2\u5B8C\u6210\uFF0C\u76F4\u63A5\u63D2\u5165\uFF08\u53EF\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32\uFF0C\u6B64\u65F6\u8D70\u5B9E\u65F6\u8BFB\u53D6\uFF09\u3002\n if (pasteCache !== null && pasteCache !== '') {\n const text = pasteCache\n pasteCache = null\n return insertText(text)\n }\n if (typeof navigator === 'undefined' || navigator.clipboard === undefined\n || typeof navigator.clipboard.readText !== 'function') {\n return { ok: false, message: '\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u8BFB\u53D6\u526A\u8D34\u677F\uFF0C\u8BF7\u7528 Ctrl+V \u7C98\u8D34' }\n }\n // \u6743\u9650\u9884\u68C0\uFF1A\u5DF2\u88AB\u660E\u786E\u62D2\u7EDD\u65F6\u76F4\u63A5\u7ED9\u6062\u590D\u6307\u5F15\uFF08\u907F\u514D\u5047\u6B7B\u6216\u8BEF\u5BFC\uFF09\u3002\n const permissions = (navigator as {\n permissions?: { query?: (descriptor: { name: string }) => Promise<{ state: string }> }\n }).permissions\n if (permissions?.query) {\n try {\n const result = await permissions.query({ name: 'clipboard-read' })\n if (result.state === 'denied') {\n if (isFirefox()) return { ok: false, message: FIREFOX_TIP }\n return {\n ok: false,\n message: '\u6D4F\u89C8\u5668\u5DF2\u62D2\u7EDD\u526A\u8D34\u677F\u8BFB\u53D6\uFF1A\u70B9\u51FB\u5730\u5740\u680F\u5DE6\u4FA7\u56FE\u6807 \u2192 \u7AD9\u70B9\u8BBE\u7F6E \u2192 \u526A\u8D34\u677F \u2192 \u5141\u8BB8\uFF1B\u6216\u76F4\u63A5\u6309 Ctrl+V',\n }\n }\n } catch {\n // \u4E0D\u652F\u6301\u8BE5\u6743\u9650\u67E5\u8BE2\uFF1A\u7EE7\u7EED\u5C1D\u8BD5\u8BFB\u53D6\u3002\n }\n }\n let text: string\n try {\n // \u7B49\u5F85\u6388\u6743\u5F39\u7A97\u53EF\u80FD\u8F83\u4E45\uFF08\u8981\u7528\u6237\u70B9\u51FB\uFF09\uFF0C\u4E0D\u7528\u77ED\u8D85\u65F6\u8BEF\u62A5\u5931\u8D25\uFF1B15 \u79D2\u65E0\u54CD\u5E94\n // \u624D\u63D0\u793A\uFF0C\u907F\u514D\u83DC\u5355\u6C38\u4E45\u6302\u8D77\u3002\n text = await withTimeout(navigator.clipboard.readText(), 15000)\n } catch (error) {\n if (isFirefox()) {\n return { ok: false, message: FIREFOX_TIP }\n }\n if (isClipboardTimeout(error)) {\n return {\n ok: false,\n message: '\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF1A\u8BF7\u5728\u5F39\u51FA\u63D0\u793A\u4E2D\u9009\u62E9\u300C\u5141\u8BB8\u300D\uFF08\u82E5\u672A\u51FA\u73B0\uFF0C\u70B9\u5730\u5740\u680F\u5DE6\u4FA7\u56FE\u6807\u5F00\u542F\uFF09\uFF0C\u6216\u6309 Ctrl+V',\n }\n }\n return {\n ok: false,\n message: '\u672A\u83B7\u526A\u8D34\u677F\u8BFB\u53D6\u6388\u6743\uFF1A\u70B9\u51FB\u5730\u5740\u680F\u5DE6\u4FA7\u56FE\u6807 \u2192 \u7AD9\u70B9\u8BBE\u7F6E \u2192 \u526A\u8D34\u677F \u2192 \u5141\u8BB8\uFF1B\u6216\u76F4\u63A5\u6309 Ctrl+V \u7C98\u8D34',\n }\n }\n if (!document.activeElement || !root.contains(document.activeElement)) {\n root.focus({ preventScroll: true })\n }\n if (text === '') return { ok: true }\n return { ok: document.execCommand('insertText', false, text) }\n}\n", "/**\r\n * \u8BBE\u7F6E\u9762\u677F\u589E\u5F3A\uFF1A\u5BFC\u822A\u5217\u6EDA\u52A8\u6837\u5F0F + \u9762\u677F\u5C3A\u5BF8\u8C03\u6574\u624B\u67C4\u3002\r\n *\r\n * \u5B98\u65B9\u9762\u677F\u7ED3\u6784\uFF08ui-settings-general SettingsRoot\uFF09\uFF1A\r\n * .overlay\uFF08position:fixed; inset:0; **z-index:1000**\uFF09\r\n * \u251C\u2500\u2500 .mask\uFF08position:absolute; inset:0\uFF09\u2500\u2500 \u5168\u5C4F\u906E\u7F69\r\n * \u2514\u2500\u2500 [role=\"dialog\"][aria-modal=\"true\"] \u2500\u2500 .panel\uFF08position:relative; width:800; overflow:hidden\uFF09\r\n * \u251C\u2500\u2500 <nav> \u2500\u2500 \u6807\u9898 + navList\uFF08\u6761\u76EE\u8F83\u591A\u65F6\u6EA2\u51FA\uFF09\r\n * \u2514\u2500\u2500 <div> \u2500\u2500 header + .options\uFF08\u672C\u8EAB overflow-y:auto\uFF09\r\n *\r\n * \u26A0\uFE0F \u5C42\u53E0\u4E0A\u4E0B\u6587\u9677\u9631\uFF080.2.0 \u6574\u6BB5\u529F\u80FD\u56E0\u6B64\u5931\u6548\uFF0C\u52A1\u5FC5\u8BB0\u4F4F\uFF09\uFF1A\r\n * \u672C\u63D2\u4EF6\u80FD\u6302\u6D6E\u5C42\u7684\u4F4D\u7F6E\u53EA\u6709 `shell.overlay`\uFF0C\u800C\u5B83\u88AB\u5B98\u65B9\u5C01\u5728\r\n * `ui-layout` \u7684 `.overlayLayer { position:absolute; inset:0; z-index:20 }` \u91CC \u2014\u2014\r\n * `position` + `z-index` \u4F7F\u5B83**\u81EA\u6210\u5C42\u53E0\u4E0A\u4E0B\u6587**\uFF0C\u91CC\u9762\u7684\u5143\u7D20\u518D\u600E\u4E48\u628A z-index\r\n * \u5199\u6210 9998 \u4E5F**\u9003\u4E0D\u51FA\u53BB**\uFF0C\u6C38\u8FDC\u6392\u5728\u8BBE\u7F6E\u5F39\u7A97\uFF081000\uFF09\u4E0B\u9762\uFF0C\u88AB\u5168\u5C4F\u906E\u7F69\u5403\u6389\u9F20\u6807\u3002\r\n * \u6240\u4EE5\uFF1A**\u51E1\u662F\u7ED9\u8BBE\u7F6E\u5F39\u7A97\u505A\u6D6E\u5C42\uFF0C\u5FC5\u987B\u628A\u624B\u67C4\u6302\u8FDB\u9762\u677F\u5185\u90E8**\uFF08`createPortal` \u5230\r\n * panel\uFF09\uFF0C\u800C\u4E0D\u662F\u5728 shell.overlay \u91CC\u5BF9\u51C6\u5750\u6807\u753B\u3002\r\n */\r\nimport type { CSSProperties } from 'react'\r\n\r\n/** \u8BBE\u7F6E\u5BF9\u8BDD\u6846\u9009\u62E9\u5668\uFF08\u9762\u677F\u4E3A\u300C\u5E26 nav \u5B50\u5143\u7D20\u7684 aria-modal \u5BF9\u8BDD\u6846\u300D\uFF0C\u5728\u5E94\u7528\r\n * \u91CC\u552F\u4E00\uFF1A\u5176\u5B83\u5BF9\u8BDD\u6846\uFF08\u5BA1\u6279\u3001\u6A21\u578B\u7F16\u8F91\u5668\u7B49\uFF09\u4E0D\u4EE5 nav \u4E3A\u76F4\u63A5\u5B50\u5143\u7D20\uFF09\u3002 */\r\nexport const PANEL_SELECTOR = '[role=\"dialog\"][aria-modal=\"true\"]:has(> nav)'\r\n\r\n\r\n/** \u624B\u67C4\u5C42\u7C7B\u540D\uFF08\u7531\u4E0B\u65B9\u6CE8\u5165\u6837\u5F0F\u8868\u5B9A\u4E49\uFF09\u3002 */\r\nexport const RESIZE_LAYER_CLASS = 'dsh-ux-resize-layer'\r\n/** \u56DB\u8FB9\u63CF\u8FB9\uFF08\u7EAF\u89C6\u89C9\uFF0C\u4E0D\u5403\u6307\u9488\uFF09\u3002 */\r\nexport const RESIZE_OUTLINE_CLASS = 'dsh-ux-resize-outline'\r\n/** \u53EF\u62D6\u62FD\u7684\u8FB9\u3002 */\r\nexport const RESIZE_EDGE_CLASS = 'dsh-ux-resize-edge'\r\n/** \u53EF\u62D6\u62FD\u7684\u53F3\u4E0B\u89D2\u6293\u624B\u3002 */\r\nexport const RESIZE_GRIP_CLASS = 'dsh-ux-resize-grip'\r\n\r\n/** \u53EF\u62D6\u62FD\u7684\u4F4D\u7F6E\u3002 */\r\nexport type ResizeEdge = 'left' | 'right' | 'top' | 'bottom' | 'br'\r\n\r\n/** \u8FB9\u7684\u6293\u53D6\u5E26\u5BBD\uFF08\u53EF\u89C1\u63CF\u8FB9\u662F 1px\uFF0C\u8FD9 8px \u662F\"\u597D\u6293\"\u7684\u4F59\u91CF\uFF09\u3002 */\r\nconst BAND = 8\r\n/** \u8FB9\u6761\u4E24\u7AEF\u907F\u8BA9\u91CF\uFF0C\u8BA9\u5706\u89D2\u5904\u4E0D\u51FA\u73B0\u538B\u7EBF\u7684\u76F4\u89D2\u3002 */\r\nconst INSET = 14\r\n/** \u53F3\u4E0B\u89D2\u6293\u624B\u5C3A\u5BF8\u3002 */\r\nconst GRIP = 26\r\n\r\n/**\r\n * \u4E00\u6761\u624B\u67C4\u5728**\u9762\u677F\u5185\u90E8**\u7684\u7EDD\u5BF9\u5B9A\u4F4D\u76D2\u3002\r\n *\r\n * \u523B\u610F\u4E0D\u4F7F\u7528\u89C6\u53E3\u5750\u6807\uFF1A\u624B\u67C4\u662F\u9762\u677F\u7684\u5B50\u5143\u7D20\uFF08\u6302\u8FDB\u9762\u677F\u5185\u90E8\uFF09\uFF0C\u6240\u4EE5\u5B9A\u4F4D\u5168\u90E8\u76F8\u5BF9\r\n * \u9762\u677F\u672C\u8EAB \u2014\u2014 \u9762\u677F\u79FB\u52A8\u3001\u6EDA\u52A8\u3001\u6539\u5C3A\u5BF8\u90FD\u4F1A\u81EA\u52A8\u8DDF\u968F\uFF0C\u4E0D\u9700\u8981\u4EFB\u4F55\u91CD\u7B97\u6216\u8F6E\u8BE2\u3002\r\n * @param edge - \u8FB9\u6216\u53F3\u4E0B\u89D2\u3002\r\n * @returns \u8BE5\u624B\u67C4\u7684 CSS \u5B9A\u4F4D\u5C5E\u6027\u3002\r\n */\r\nexport function handleBox(edge: ResizeEdge): CSSProperties {\r\n switch (edge) {\r\n case 'left': return { left: 0, top: INSET, bottom: INSET, width: BAND, cursor: 'ew-resize' }\r\n case 'right': return { right: 0, top: INSET, bottom: INSET, width: BAND, cursor: 'ew-resize' }\r\n case 'top': return { top: 0, left: INSET, right: INSET, height: BAND, cursor: 'ns-resize' }\r\n case 'bottom': return { bottom: 0, left: INSET, right: INSET, height: BAND, cursor: 'ns-resize' }\r\n case 'br': return { right: 8, bottom: 8, width: GRIP, height: GRIP, cursor: 'nwse-resize' }\r\n }\r\n}\r\n\r\n/** \u56DB\u8FB9\u63CF\u8FB9\u5C42\uFF1A\u8D34\u7740\u9762\u677F\u5706\u89D2\u753B\u4E00\u5708 1px \u7EC6\u7EBF\uFF08\u7EAF\u89C6\u89C9\uFF0C`pointer-events: none`\uFF09\u3002 */\r\nexport const RESIZE_OUTLINE_STYLE: CSSProperties = {\r\n position: 'absolute',\r\n inset: 0,\r\n // \u8DDF\u968F\u9762\u677F\u81EA\u8EAB\u7684\u5706\u89D2\uFF08\u5B98\u65B9 .panel \u662F 32px\uFF09\u2014\u2014\u7528 inherit \u800C\u4E0D\u662F\u5199\u6B7B\u6570\u5B57\uFF0C\r\n // \u5B98\u65B9\u6539\u5706\u89D2\u65F6\u8FD9\u91CC\u81EA\u52A8\u8DDF\u4E0A\u3002\r\n borderRadius: 'inherit',\r\n border: '1px solid rgba(127, 127, 137, .28)',\r\n pointerEvents: 'none',\r\n}\r\n\r\n/** \u6CE8\u5165\u7684\u6EDA\u52A8\u6837\u5F0F\uFF08\u7531 html.dsh-ux-panel-scroll \u95E8\u63A7\uFF09\u3002 */\r\nconst PANEL_CSS = `\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) { min-height: 320px; }\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav {\r\n min-height: 0;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child {\r\n flex: 1 1 auto;\r\n min-height: 0;\r\n overflow-y: auto;\r\n overscroll-behavior: contain;\r\n scrollbar-width: thin;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar {\r\n width: 8px;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb {\r\n background: var(--dsh-scrollbar-thumb, var(--dsw-alias-scrollbar-bg-l2));\r\n border-radius: 8px;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb:hover {\r\n background: var(--dsh-scrollbar-thumb-hover, var(--dsw-alias-scrollbar-hover-l2));\r\n}\r\n`\r\n\r\n/**\r\n * \u5C3A\u5BF8\u624B\u67C4\u6837\u5F0F\u3002\r\n *\r\n * \u624B\u67C4\u5C42\u6302\u5728**\u8BBE\u7F6E\u9762\u677F\u5185\u90E8**\uFF08\u89C1\u6587\u4EF6\u5934\u7684\u5C42\u53E0\u4E0A\u4E0B\u6587\u8BF4\u660E\uFF09\uFF0C\u6240\u4EE5\u8FD9\u4E9B\u89C4\u5219\u91CC\u7684\r\n * \u5B9A\u4F4D\u4E00\u5F8B\u76F8\u5BF9\u9762\u677F\uFF1B`pointer-events` \u5728\u5C42\u4E0A\u5173\u6389\u3001\u53EA\u5728\u5177\u4F53\u624B\u67C4\u4E0A\u6253\u5F00\uFF0C\r\n * \u514D\u5F97\u6574\u5C42\u5403\u6389\u9762\u677F\u672C\u8EAB\u7684\u70B9\u51FB\u3002\r\n */\r\nconst RESIZE_CSS = `\r\n.${RESIZE_LAYER_CLASS} { position: absolute; inset: 0; pointer-events: none; }\r\n.${RESIZE_EDGE_CLASS}, .${RESIZE_GRIP_CLASS} {\r\n position: absolute;\r\n pointer-events: auto;\r\n background: transparent;\r\n border-radius: 6px;\r\n transition: background-color .12s ease, color .12s ease;\r\n touch-action: none;\r\n}\r\n.${RESIZE_EDGE_CLASS}:hover { background: rgba(127, 127, 137, .22); }\r\n.${RESIZE_EDGE_CLASS}[data-active=\"true\"] { background: rgba(127, 127, 137, .3); }\r\n.${RESIZE_GRIP_CLASS} {\r\n display: flex;\r\n align-items: flex-end;\r\n justify-content: flex-end;\r\n padding: 3px;\r\n color: rgba(127, 127, 137, .55);\r\n}\r\n.${RESIZE_GRIP_CLASS}:hover { color: rgba(127, 127, 137, .95); background: rgba(127, 127, 137, .16); }\r\n`\r\n\r\n/** \u6CE8\u5165\u6837\u5F0F\u8868\u9A71\u52A8\u6EDA\u52A8\u5F00\u5173\uFF08\u968F\u8BBE\u7F6E\u53D8\u5316\u5373\u65F6\u66F4\u65B0\uFF09\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\u3002 */\r\nexport function installPanelStyle(\r\n settings: () => boolean,\r\n subscribe: (listener: () => void) => () => void,\r\n): () => void {\r\n const tag = document.createElement('style')\r\n tag.dataset.plugin = 'dsh-composer-ux-panel'\r\n tag.textContent = `${PANEL_CSS}\\n${RESIZE_CSS}`\r\n document.head.appendChild(tag)\r\n const applyClass = (): void => {\r\n document.documentElement.classList.toggle('dsh-ux-panel-scroll', settings())\r\n }\r\n applyClass()\r\n const unsubscribe = subscribe(applyClass)\r\n return () => {\r\n unsubscribe()\r\n tag.remove()\r\n document.documentElement.classList.remove('dsh-ux-panel-scroll')\r\n }\r\n}\r\n\r\n/** \u67E5\u8BE2\u5F53\u524D\u6253\u5F00\u7684\u8BBE\u7F6E\u5BF9\u8BDD\u6846\u3002 */\r\nexport function findSettingsPanel(): HTMLElement | null {\r\n return document.querySelector<HTMLElement>(PANEL_SELECTOR)\r\n}\r\n\r\n/** \u5C3A\u5BF8\u8303\u56F4\u94B3\u5236\uFF08\u4E0E host schema \u4E00\u81F4\uFF09\u3002 */\r\nexport function clampPanelWidth(width: number): number {\r\n return Math.max(560, Math.min(width, Math.max(800, window.innerWidth - 48)))\r\n}\r\n\r\nexport function clampPanelHeight(height: number): number {\r\n return Math.max(320, Math.min(height, Math.max(400, window.innerHeight - 48)))\r\n}\r\n\r\n/** \u6301\u4E45\u5316\u5C3A\u5BF8\uFF08\u5199\u5165\u8BBE\u7F6E\uFF1B\u5931\u8D25\u9759\u9ED8\u2014\u2014\u4E0B\u6B21\u6253\u5F00\u56DE\u9000\u9ED8\u8BA4\uFF09\u3002 */\r\nexport function persistPanelSize(\r\n width: number,\r\n height: number,\r\n setField: (field: string, value: boolean | number) => void,\r\n): void {\r\n setField('panelWidth', clampPanelWidth(width))\r\n setField('panelHeight', clampPanelHeight(height))\r\n}\r\n", "/**\n * \u8BBE\u7F6E\u9875\u6298\u53E0\u5361\u7247\u6837\u5F0F\u3002\n *\n * \u89C2\u611F\u5BF9\u9F50\u793E\u533A\u63D2\u4EF6 @linxin666/dsh-web-all \u7684 SettingsCard\uFF1A12px \u5706\u89D2\u3001\n * 1px \u63CF\u8FB9\uFF08hover \u53D8 --dsw-alias-label-dimmed\uFF09\u3001\u5C55\u5F00\u65F6\u6362\u5E95\u8272\u5E76\u663E\u793A\u5206\u9694\u7EBF\u3001\n * \u53F3\u4FA7 chevron \u65CB\u8F6C 180\u00B0\u3002\u7C7B\u540D\u7EDF\u4E00 dsh-ux- \u524D\u7F00\uFF0C\u907F\u514D\u4E0E\u5BBF\u4E3B CSS Modules \u51B2\u7A81\u3002\n */\n\nconst CARD_CSS = `\n.dsh-ux-card {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 12px;\n margin-bottom: 12px;\n transition: border-color .16s, background .16s;\n}\n.dsh-ux-card:hover { border-color: var(--dsw-alias-label-dimmed); }\n.dsh-ux-cardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dsh-ux-cardHeader {\n appearance: none;\n box-sizing: border-box;\n width: 100%;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: 0 0;\n border: 0;\n border-radius: 12px;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n}\n.dsh-ux-cardHeader:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.dsh-ux-cardHeaderStatic {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n}\n.dsh-ux-cardHeadText {\n display: flex;\n flex-direction: column;\n flex: 1;\n gap: 4px;\n min-width: 0;\n}\n.dsh-ux-cardName {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n margin: 0;\n}\n.dsh-ux-cardDescription {\n color: var(--dsw-alias-label-secondary);\n font-size: 13px;\n line-height: 1.5;\n margin: 0;\n}\n.dsh-ux-cardChevron {\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n transition: transform .16s;\n}\n.dsh-ux-cardChevronOpen { transform: rotate(180deg); }\n.dsh-ux-cardBody {\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin: 0 16px;\n padding-bottom: 8px;\n}\n`\n\n/** \u6CE8\u5165\u5361\u7247\u6837\u5F0F\u8868\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\uFF08\u968F\u63D2\u4EF6 fiber \u56DE\u6536\uFF09\u3002 */\nexport function installSettingsCardStyle(): () => void {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-composer-ux-settings'\n tag.textContent = CARD_CSS\n document.head.appendChild(tag)\n return () => { tag.remove() }\n}\n", "/**\n * \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\u7684\u6837\u5F0F\u8868\u3002\n *\n * \u4E3A\u4EC0\u4E48\u4E0D\u7528\u884C\u5185\u6837\u5F0F\uFF08React `style`\uFF09\uFF1A\u5B83\u8868\u8FBE\u4E0D\u4E86 `:hover` / `[aria-expanded]`\n * \u8FD9\u7C7B\u72B6\u6001\uFF0C\u800C\u300C\u548C\u65C1\u8FB9\u7684\u5B98\u65B9\u6309\u94AE\u957F\u5F97\u4E00\u6837\u300D\u6070\u6070\u8981\u9760 hover \u4E0E\u5E38\u6001\u900F\u660E\u5EA6\u3002\n *\n * \u53C2\u6570\u9010\u9879\u5BF9\u9F50\u793E\u533A\u63D2\u4EF6 `dsh-composer-expand` \u7684 `.cpex-btn`\uFF08\u540C\u4E00\u4E2A\u69FD\u4F4D\n * `conversation.input.right`\u3001\u540C\u4E00\u4E2A order \u90BB\u4F4D\uFF09\u2014\u2014 \u4E24\u4E2A\u6309\u94AE\u5E76\u6392\uFF0C\u5FC5\u987B\u540C\u9AD8\u3001\n * \u540C\u5706\u89D2\u3001\u540C\u5185\u8FB9\u8DDD\u3001\u540C\u8FB9\u6846\u3001\u540C\u5E38\u6001\u900F\u660E\u5EA6\uFF0C\u5426\u5219\u4E00\u773C\u5C31\u770B\u5F97\u51FA\u662F\u4E24\u5BB6\u4EBA\u505A\u7684\u3002\n * \u7279\u522B\u8BB0\u4E00\u7B14\uFF1A\u8FB9\u6846**\u4E0D\u7528**\u4E3B\u9898\u4EE4\u724C `--dsw-alias-border-l2`\uFF08\u5B83\u66F4\u4EAE\uFF0C\u4F1A\u5448\u73B0\u6210\n * \u7528\u6237\u622A\u56FE\u91CC\u90A3\u5708\u7A81\u5140\u7684\u767D\u7EBF\uFF09\uFF0C\u800C\u662F\u548C\u5BF9\u65B9\u4E00\u6837\u7528\u4E2D\u6027\u534A\u900F\u660E\u7070\uFF0C\u660E\u6697\u4E3B\u9898\u4E0B\u90FD\u534F\u8C03\u3002\n */\n\n/** \u5165\u53E3\u6309\u94AE\u7684\u57FA\u7840\u7C7B\u540D\u3002 */\nexport const QUICK_BUTTON_CLASS = 'composer-ux-quick-button'\n\n/** \u4E0E .cpex-btn \u9010\u9879\u5BF9\u9F50\u3002 */\nconst QUICK_BUTTON_CSS = `\n.${QUICK_BUTTON_CLASS} {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 24px;\n border: 1px solid rgba(127, 127, 137, .35);\n background: transparent;\n color: inherit;\n border-radius: 999px;\n padding: 0 9px;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n opacity: .75;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n transition: opacity .12s ease, background-color .12s ease;\n}\n.${QUICK_BUTTON_CLASS}:hover { opacity: 1; background: rgba(127, 127, 137, .12); }\n.${QUICK_BUTTON_CLASS}[aria-expanded=\"true\"] {\n opacity: 1;\n background: rgba(127, 127, 137, .18);\n border-color: rgba(127, 127, 137, .6);\n}\n.${QUICK_BUTTON_CLASS} svg { flex: 0 0 auto; }\n`\n\n/** \u6CE8\u5165\u5165\u53E3\u6309\u94AE\u6837\u5F0F\u8868\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\uFF08\u968F\u63D2\u4EF6 fiber \u56DE\u6536\uFF09\u3002 */\nexport function installQuickButtonStyle(): () => void {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-composer-ux-quick-button'\n tag.textContent = QUICK_BUTTON_CSS\n document.head.appendChild(tag)\n return () => { tag.remove() }\n}\n", "/**\n * \u53F3\u952E\u83DC\u5355\u5BBF\u4E3B\uFF1A\u6CE8\u518C\u8FDB shell.overlay\uFF08root \u7EA7 list \u69FD\uFF09\uFF0C\u83DC\u5355\u6253\u5F00\u65F6\u6E32\u67D3\n * \u4E00\u4E2A fixed \u5B9A\u4F4D\u7684\u6D6E\u5C42\uFF1B\u5173\u95ED\u65F6\u6E32\u67D3 null\u3002\n */\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n MENU_ITEMS, type ComposerUxSettings, type MenuState, type MenuField,\n} from '../settings-contract.ts'\nimport type { MenuActionId } from './interceptors.ts'\nimport { menu, menuItem, menuItemDim, menuNote, menuSeparator, menuShortcut } from './styles.ts'\n\n/** \u53F3\u952E\u83DC\u5355\u6CE8\u5165\u9762\u3002 */\nexport interface ContextMenuInjected {\n hooks: {\n /** \u83DC\u5355\u6253\u5F00\u72B6\u6001\uFF08null = \u5173\u95ED\uFF09\u3002 */\n menu: SnapshotStore<MenuState | null>\n /** \u5F53\u524D\u8BBE\u7F6E\uFF08\u51B3\u5B9A\u54EA\u4E9B\u83DC\u5355\u9879\u542F\u7528\uFF09\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n }\n actions: {\n /** \u6267\u884C\u4E00\u4E2A\u83DC\u5355\u52A8\u4F5C\uFF1Bresolve \u6210\u529F\u4E0E\u5426\u3002 */\n run: (id: MenuActionId) => Promise<{ ok: boolean; message?: string }>\n /** \u5173\u95ED\u83DC\u5355\u3002 */\n close: () => void\n /** \u5728\u83DC\u5355\u4E0A\u6302\u4E00\u6BB5\u77ED\u6682\u63D0\u793A\uFF08\u4FDD\u7559\u83DC\u5355\u6253\u5F00\uFF09\u3002 */\n note: (message: string | undefined) => void\n }\n}\n\nexport type ContextMenuHostProps =\n PropsRuntime<'shell.overlay'>\n & InjectFace<ContextMenuInjected>\n\n/** \u83DC\u5355\u7EC4\uFF1A\u4E0E\u56FE\u7247\u4E00\u81F4\u7684\u4E09\u7EC4\u5206\u9694\u5E03\u5C40\u3002 */\nconst GROUPS: readonly { readonly label: string; readonly shortcut: string; readonly field: MenuField; readonly id: MenuActionId | 'disabledOnly' }[][] = [\n [\n { label: '\u64A4\u9500', shortcut: 'Ctrl+Z', field: 'menuUndo', id: 'undo' },\n { label: '\u91CD\u505A', shortcut: 'Ctrl+Y', field: 'menuRedo', id: 'redo' },\n ],\n [\n { label: '\u526A\u5207', shortcut: 'Ctrl+X', field: 'menuCut', id: 'cut' },\n { label: '\u590D\u5236', shortcut: 'Ctrl+C', field: 'menuCopy', id: 'copy' },\n { label: '\u7C98\u8D34', shortcut: 'Ctrl+V', field: 'menuPaste', id: 'paste' },\n { label: '\u5220\u9664', shortcut: '', field: 'menuDelete', id: 'delete' },\n ],\n [\n { label: '\u5168\u9009', shortcut: 'Ctrl+A', field: 'menuSelectAll', id: 'selectAll' },\n ],\n]\n\nconst ITEM_STYLES: Record<MenuActionId, 'always' | 'selection'> = {\n undo: 'always',\n redo: 'always',\n cut: 'selection',\n copy: 'selection',\n paste: 'always',\n delete: 'selection',\n selectAll: 'always',\n}\n\n/** \u4E0E\u89C6\u53E3\u8FB9\u754C\u4FDD\u6301 8px\u3002 */\nfunction clamp(value: number, size: number, viewport: number): number {\n return Math.max(8, Math.min(value, viewport - size - 8))\n}\n\n/** \u6E32\u67D3\u53F3\u952E\u83DC\u5355\uFF1B\u65E0\u83DC\u5355\u65F6\u8FD4\u56DE null\u3002 */\nexport function ContextMenuHost({ useMenu, useLive, actions }: ContextMenuHostProps) {\n const menuState = useMenu(item => item)\n const settings = useLive(item => item)\n const ref = useRef<HTMLDivElement | null>(null)\n const [position, setPosition] = useState<{ x: number; y: number } | null>(null)\n\n // \u6253\u5F00\u540E\u6309\u5B9E\u9645\u5C3A\u5BF8\u94B3\u5236\u5728\u89C6\u53E3\u5185\u3002\n useLayoutEffect(() => {\n if (menuState === null) {\n setPosition(null)\n return\n }\n const el = ref.current\n if (el === null) return\n const rect = el.getBoundingClientRect()\n setPosition({\n x: clamp(menuState.x, rect.width, window.innerWidth),\n y: clamp(menuState.y, rect.height, window.innerHeight),\n })\n }, [menuState?.x, menuState?.y])\n\n // \u5916\u90E8\u70B9\u51FB / Escape / \u6EDA\u52A8 / \u7A97\u53E3\u53D8\u5316\u65F6\u5173\u95ED\u3002\n useEffect(() => {\n if (menuState === null) return\n const onPointerDown = (event: PointerEvent): void => {\n if (ref.current !== null && event.target instanceof Node && ref.current.contains(event.target)) return\n actions.close()\n }\n const onEscape = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n event.preventDefault()\n event.stopPropagation()\n actions.close()\n }\n window.addEventListener('pointerdown', onPointerDown, true)\n window.addEventListener('keydown', onEscape, true)\n window.addEventListener('scroll', actions.close, true)\n window.addEventListener('resize', actions.close)\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, true)\n window.removeEventListener('keydown', onEscape, true)\n window.removeEventListener('scroll', actions.close, true)\n window.removeEventListener('resize', actions.close)\n }\n }, [menuState === null, actions])\n\n // \u63D0\u793A 3 \u79D2\u540E\u6E05\u9664\u3002\n useEffect(() => {\n if (menuState?.note === undefined) return\n const timer = setTimeout(() => { actions.note(undefined) }, 3000)\n return () => { clearTimeout(timer) }\n }, [menuState?.note])\n\n if (menuState === null) return null\n\n const onItemClick = (id: MenuActionId): void => {\n // \u7C98\u8D34\u82E5\u7F13\u5B58\u672A\u547D\u4E2D\u4F1A\u5B9E\u65F6\u8BFB\u53D6\u526A\u8D34\u677F\uFF0C\u53EF\u80FD\u77ED\u6682\u7B49\u5F85\u6388\u6743\uFF0C\u7ED9\u51FA\u8FDB\u884C\u4E2D\u53CD\u9988\u3002\n if (id === 'paste') actions.note('\u6B63\u5728\u8BFB\u53D6\u526A\u8D34\u677F\u2026')\n // \u4E0D\u8BA9\u6309\u94AE\u62A2\u8D70\u7126\u70B9\uFF0C\u4FDD\u7559\u8F93\u5165\u6846\u9009\u533A\u3002\n void actions.run(id).then((result) => {\n if (result.ok) actions.close()\n else actions.note(result.message ?? '\u64CD\u4F5C\u5931\u8D25')\n })\n }\n\n const groups = GROUPS\n .map(group => group.filter(item => settings[item.field] === true))\n .filter(group => group.length > 0)\n\n return (\n <div\n ref={ref}\n role=\"menu\"\n style={{\n ...menu,\n left: position?.x ?? menuState.x,\n top: position?.y ?? menuState.y,\n }}\n >\n {groups.map((group, groupIndex) => (\n <React.Fragment key={group[0]!.field}>\n {groupIndex > 0 && <div role=\"separator\" style={menuSeparator} />}\n {group.map(item => {\n const needsSelection = ITEM_STYLES[item.id] === 'selection'\n const disabled = needsSelection && !menuState.hasSelection\n const style = disabled ? menuItemDim : menuItem\n return (\n <button\n key={item.field}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n style={style}\n onMouseDown={(event) => { event.preventDefault() }}\n onClick={() => { onItemClick(item.id) }}\n >\n <span>{item.label}</span>\n {item.shortcut !== '' && <span style={menuShortcut}>{item.shortcut}</span>}\n </button>\n )\n })}\n </React.Fragment>\n ))}\n {menuState.note !== undefined && <div style={menuNote}>{menuState.note}</div>}\n </div>\n )\n}\n", "/**\n * \u5185\u8054\u6837\u5F0F\u5DE5\u5177\uFF1A\u53EA\u4F7F\u7528 DSH Web \u7684 --dsw-* \u8BBE\u8BA1\u4EE4\u724C\uFF0C\u6DF1\u6D45\u4E3B\u9898\u81EA\u9002\u5E94\u3002\n */\nimport type { CSSProperties } from 'react'\n\n/** \u9875\u9762\u5361\u7247\u3002 */\nexport const card: CSSProperties = {\n background: 'var(--dsw-alias-bg-layer-2)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: '14px 16px',\n marginBottom: 12,\n}\n\n/** \u5361\u7247\u6807\u9898\u3002 */\nexport const cardTitle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 14,\n fontWeight: 600,\n margin: '0 0 4px',\n}\n\n/** \u8BF4\u660E\u6587\u5B57\u3002 */\nexport const description: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 12,\n lineHeight: 1.6,\n margin: '0 0 12px',\n}\n\n/** \u8BBE\u7F6E\u884C\u3002 */\nexport const row: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n minHeight: 40,\n padding: '7px 0',\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n}\n\n/** \u884C\u5185\u6807\u7B7E\u533A\u3002 */\nexport const rowText: CSSProperties = {\n minWidth: 0,\n flex: 1,\n}\n\n/** \u884C\u6807\u9898\u3002 */\nexport const rowTitle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 13,\n lineHeight: 1.4,\n}\n\n/** \u884C\u8BF4\u660E\u3002 */\nexport const rowDesc: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1.4,\n marginTop: 2,\n}\n\n/** \u952E\u4F4D\u663E\u793A\u80F6\u56CA\u3002 */\nexport const kbd: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 6,\n padding: '3px 8px',\n fontSize: 12,\n fontFamily: 'var(--dsw-font-family)',\n whiteSpace: 'nowrap',\n}\n\n/** \u9884\u8BBE/\u52A8\u4F5C\u5C0F\u6309\u94AE\u3002 */\nexport const pill: CSSProperties = {\n background: 'var(--dsw-alias-interactive-bg-hover)',\n color: 'var(--dsw-alias-label-secondary)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 999,\n padding: '4px 10px',\n fontSize: 12,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n}\n\n/** \u9009\u4E2D\u6001\u6309\u94AE\u3002 */\nexport const pillActive: CSSProperties = {\n ...pill,\n color: 'var(--dsw-alias-button-primary-fill)',\n borderColor: 'var(--dsw-alias-button-primary-fill)',\n}\n\n/** \u5355\u884C\u6587\u672C\u8F93\u5165\uFF08\u8DDF\u968F\u4E3B\u9898\u4EE4\u724C\uFF09\u3002 */\nexport const textInput: CSSProperties = {\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n padding: '6px 9px',\n fontSize: 12,\n lineHeight: 1.4,\n width: '100%',\n minWidth: 0,\n boxSizing: 'border-box',\n flex: 1,\n}\n\n/** \u63D0\u793A/\u9519\u8BEF\u6587\u5B57\u3002 */\nexport const hintError: CSSProperties = {\n color: 'var(--dsw-alias-state-error-primary)',\n fontSize: 12,\n lineHeight: 1.5,\n margin: '6px 0 0',\n}\n\n/** \u63D0\u793A\u6587\u5B57\uFF08\u4E2D\u6027\uFF09\u3002 */\nexport const hintInfo: CSSProperties = {\n color: 'var(--dsw-alias-label-secondary)',\n fontSize: 12,\n lineHeight: 1.5,\n margin: '6px 0 0',\n}\n\n/** \u83DC\u5355\uFF08\u4E0E\u56FE\u7247\u4E00\u81F4\u7684\u6DF1\u8272\u5706\u89D2\u83DC\u5355\uFF09\uFF1B\u80CC\u666F\u53D6\u81EA\u5B98\u65B9\u83DC\u5355\u4EE4\u724C\u3002 */\nexport const menu: CSSProperties = {\n position: 'fixed',\n zIndex: 9999,\n minWidth: 200,\n background: 'var(--dsw-specific-menu)',\n border: '0.5px solid var(--dsw-alias-border-l1)',\n borderRadius: 10,\n boxShadow: 'var(--dsw-elevation-prominent)',\n padding: 5,\n pointerEvents: 'auto',\n userSelect: 'none',\n}\n\n/** \u83DC\u5355\u9879\u3002 */\nexport const menuItem: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 24,\n padding: '6px 10px',\n borderRadius: 6,\n fontSize: 13,\n color: 'var(--dsw-alias-label-primary)',\n cursor: 'pointer',\n background: 'transparent',\n border: 'none',\n width: '100%',\n textAlign: 'left',\n}\n\nexport const menuItemDim: CSSProperties = {\n ...menuItem,\n color: 'var(--dsw-alias-label-dimmed)',\n cursor: 'default',\n}\n\n/** \u83DC\u5355\u9879\u5FEB\u6377\u952E\u3002 */\nexport const menuShortcut: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 12,\n fontFamily: 'var(--dsw-font-family)',\n}\n\n/** \u83DC\u5355\u5206\u9694\u7EBF\u3002 */\nexport const menuSeparator: CSSProperties = {\n height: 0,\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n margin: '4px 8px',\n}\n\n/** \u83DC\u5355\u5E95\u90E8\u63D0\u793A\u3002 */\nexport const menuNote: CSSProperties = {\n color: 'var(--dsw-alias-state-warn-label)',\n fontSize: 11,\n lineHeight: 1.4,\n padding: '4px 10px 2px',\n}\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\uFF1A\u8F93\u5165\u5361\u7247\u91CC\u7684\u5165\u53E3\u6309\u94AE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// \u6309\u94AE\u6837\u5F0F**\u6545\u610F\u4E0D\u653E\u5728\u8FD9\u91CC**\uFF1A\u5B83\u9700\u8981 hover \u4E0E\u5C55\u5F00\u6001\uFF0C\u884C\u5185\u6837\u5F0F\u8868\u8FBE\u4E0D\u4E86\uFF0C\u800C\u4E14\n// \u8981\u4E0E\u65C1\u8FB9\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\uFF08dsh-composer-expand \u7684 .cpex-btn\uFF09\u9010\u9879\u5BF9\u9F50\u3002\n// \u89C1 `quick-style.ts` \u7684\u6CE8\u5165\u6837\u5F0F\u8868\u3002\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\uFF1A\u5C55\u5F00\u9762\u677F \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** \u9762\u677F\u5BB9\u5668\uFF08fixed \u5B9A\u4F4D\uFF0C\u951A\u70B9\u5728\u5165\u53E3\u6309\u94AE\u4E0A\u65B9\uFF09\u3002 */\nexport const quickPanel: CSSProperties = {\n position: 'fixed',\n zIndex: 9999,\n width: 420,\n maxWidth: 'calc(100vw - 24px)',\n maxHeight: 'min(60vh, 520px)',\n display: 'flex',\n flexDirection: 'column',\n background: 'var(--dsw-specific-menu)',\n border: '0.5px solid var(--dsw-alias-border-l1)',\n borderRadius: 12,\n boxShadow: 'var(--dsw-elevation-prominent)',\n pointerEvents: 'auto',\n overflow: 'hidden',\n}\n\n/** \u9762\u677F\u9876\u90E8\u533A\uFF08\u6807\u9898 + \u6863\u4F4D + \u4F18\u5316\u6309\u94AE\uFF09\u3002 */\nexport const quickPanelHead: CSSProperties = {\n padding: '10px 12px 8px',\n borderBottom: '0.5px solid var(--dsw-alias-border-l2)',\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n}\n\n/** \u9762\u677F\u6807\u9898\u884C\u3002 */\nexport const quickPanelTitleRow: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n}\n\n/** \u9762\u677F\u6807\u9898\u3002 */\nexport const quickPanelTitle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 13,\n fontWeight: 600,\n}\n\n/** \u6863\u4F4D\u5206\u6BB5\u63A7\u4EF6\u3002 */\nexport const quickTierRow: CSSProperties = {\n display: 'inline-flex',\n gap: 2,\n padding: 2,\n borderRadius: 999,\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n}\n\n/** \u5355\u4E2A\u6863\u4F4D\u6309\u94AE\u3002 */\nexport const quickTierButton: CSSProperties = {\n border: 'none',\n background: 'transparent',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n padding: '4px 8px',\n borderRadius: 999,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n}\n\n/** \u9009\u4E2D\u6863\u4F4D\u3002\n * \u524D\u666F\u5FC5\u987B\u7528\u914D\u5BF9\u4EE4\u724C `label-primary-foreground`\uFF1A`button-primary-fill` \u53D6\u81EA\n * `brand-primary`\uFF0C\u6D45\u8272\u4E3B\u9898\u4E0B\u662F\u58A8\u8272/\u6DF1\u8272\uFF0C**\u6DF1\u8272\u4E3B\u9898\u4E0B\u5B83\u662F\u767D**\u2014\u2014\u6B64\u65F6\u5199\u6B7B\n * `#fff` \u5C31\u662F\u767D\u5E95\u767D\u5B57\uFF080.2.0 \u771F\u8E29\u8FC7\uFF09\u3002\u5B98\u65B9 ui-primitives/Button \u7684\u6210\u5BF9\u5199\u6CD5\n * \u5C31\u662F fill + label-primary-foreground\u3002 */\nexport const quickTierButtonActive: CSSProperties = {\n ...quickTierButton,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\n\n/** \u4E3B\u884C\u52A8\u6309\u94AE\uFF08\u4F18\u5316\u63D0\u793A\u8BCD\uFF09\u3002\u540C\u4E0A\uFF1Afill \u4E0E\u524D\u666F\u5FC5\u987B\u6210\u5BF9\u3002 */\nexport const quickPrimaryButton: CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 6,\n width: '100%',\n padding: '7px 12px',\n borderRadius: 8,\n border: '0.5px solid var(--dsw-alias-button-primary-fill)',\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n fontSize: 12,\n cursor: 'pointer',\n}\n\n/** \u4E3B\u884C\u52A8\u6309\u94AE\uFF08\u4E0D\u53EF\u7528\uFF09\uFF1A\u4E0E\u5B98\u65B9 .primary:disabled \u4E00\u81F4\u7528 0.4\u3002 */\nexport const quickPrimaryButtonDisabled: CSSProperties = {\n ...quickPrimaryButton,\n opacity: 0.4,\n cursor: 'default',\n}\n\n/** \u6761\u76EE\u5217\u8868\u5BB9\u5668\uFF08\u53EF\u6EDA\u52A8\uFF09\u3002 */\nexport const quickList: CSSProperties = {\n overflowY: 'auto',\n padding: '6px 6px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n}\n\n/** \u4E00\u6761\u5FEB\u6377\u6307\u4EE4\u3002\n * \u6CE8\u610F\uFF1A\u8FD9\u4E00\u884C\u91CC\u8FD8\u6709\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u52FE\u9009\u6846\uFF0C\u6240\u4EE5\u6309\u94AE\u5FC5\u987B\u53EF\u88AB\u538B\u7F29\n * \uFF08flex 1 1 auto + minWidth 0\uFF09\uFF0C\u5426\u5219\u957F\u9884\u89C8\u4F1A\u628A\u52FE\u9009\u6846\u6324\u51FA\u9762\u677F\n * \uFF08width:100% \u4F1A\u5403\u6EE1\u6574\u884C\uFF0C0.2.0 \u771F\u8E29\u8FC7\uFF09\u3002 */\nexport const quickItem: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '5px 8px',\n borderRadius: 7,\n cursor: 'pointer',\n background: 'transparent',\n border: 'none',\n flex: '1 1 auto',\n minWidth: 0,\n textAlign: 'left',\n}\n\n/** \u6761\u76EE\u540D\u79F0\u3002 */\nexport const quickItemLabel: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 12,\n flex: '0 0 auto',\n whiteSpace: 'nowrap',\n}\n\n/** \u6761\u76EE\u5185\u5BB9\u9884\u89C8\u3002 */\nexport const quickItemPreview: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n flex: '1 1 auto',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n}\n\n/** \u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u52FE\u9009\u533A\u3002 */\nexport const quickAlwaysLabel: CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n flex: '0 0 auto',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n whiteSpace: 'nowrap',\n cursor: 'pointer',\n}\n\n/** \u52FE\u9009\u6846\u3002 */\nexport const quickAlwaysBox: CSSProperties = {\n margin: 0,\n cursor: 'pointer',\n}\n\n/** \u9762\u677F\u5E95\u90E8\u63D0\u793A\u6761\u3002 */\nexport const quickPanelFoot: CSSProperties = {\n padding: '5px 12px 7px',\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n}\n\n/** \u9762\u677F\u91CC\u7684\u63D0\u793A\u6587\u5B57\u3002 */\nexport const quickNotice: CSSProperties = {\n color: 'var(--dsw-alias-state-warn-label)',\n fontSize: 11,\n lineHeight: 1.4,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n}\n\n/** \u9762\u677F\u91CC\u7684\u6B21\u8981\u8BF4\u660E\u3002 */\nexport const quickFootHint: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n whiteSpace: 'nowrap',\n flex: '0 0 auto',\n}\n\n/** \u7A7A\u5217\u8868\u5360\u4F4D\u3002 */\nexport const quickEmpty: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 12,\n lineHeight: 1.6,\n padding: '14px 10px',\n textAlign: 'center',\n}\n", "/**\n * \u8BBE\u7F6E\u9762\u677F\u5C3A\u5BF8\u624B\u67C4\uFF1A\u56DB\u8FB9\u53EF\u62D6 + \u53F3\u4E0B\u89D2\u6293\u624B\u3002\n *\n * **\u4E3A\u4EC0\u4E48\u7528 `createPortal` \u6302\u8FDB\u9762\u677F\u5185\u90E8\uFF0C\u800C\u4E0D\u662F\u5728 `shell.overlay` \u91CC\u5BF9\u51C6\u5750\u6807\u753B**\n * \uFF080.2.0 \u6574\u6BB5\u529F\u80FD\u5931\u6548\u7684\u539F\u56E0\uFF0C\u52A1\u5FC5\u522B\u6539\u56DE\u53BB\uFF09\uFF1A\n * `shell.overlay` \u88AB\u5B98\u65B9\u5C01\u5728 `ui-layout` \u7684\n * `.overlayLayer { position:absolute; inset:0; z-index:20 }` \u91CC\u3002`position` +\n * `z-index` \u8BA9\u5B83**\u81EA\u6210\u5C42\u53E0\u4E0A\u4E0B\u6587**\uFF0C\u91CC\u9762\u7684\u5143\u7D20\u65E0\u8BBA z-index \u5199\u591A\u5927\u90FD\u51FA\u4E0D\u53BB\uFF0C\n * \u6C38\u8FDC\u6392\u5728\u8BBE\u7F6E\u5F39\u7A97\uFF08`.overlay` z-index:1000\uFF09\u4E0B\u9762\uFF0C\u88AB\u5168\u5C4F\u906E\u7F69\n * \uFF08`.mask { position:absolute; inset:0 }`\uFF09\u5403\u6389\u9F20\u6807 \u21D2 \u624B\u67C4\u6839\u672C\u6293\u4E0D\u5230\u3002\n * \u6302\u8FDB\u9762\u677F\u5185\u90E8\u5C31\u5B8C\u5168\u4E0D\u9700\u8981\u6BD4\u5C42\u53E0\uFF1A\u5B83\u5728\u6700\u9AD8\u90A3\u4E00\u5C42\u7684**\u91CC\u9762**\u3002\n *\n * \u9644\u5E26\u597D\u5904\uFF1A\u5B9A\u4F4D\u7531\u300C\u89C6\u53E3\u5750\u6807 + \u8F6E\u8BE2\u91CD\u7B97\u300D\u53D8\u6210\u300C\u9762\u677F\u5185\u7684\u7EDD\u5BF9\u5B9A\u4F4D\u300D\uFF0C\u9762\u677F\u79FB\u52A8/\n * \u6EDA\u52A8/\u6539\u5C3A\u5BF8\u90FD\u81EA\u52A8\u8DDF\u968F\uFF0C\u4E0D\u518D\u9700\u8981 250ms \u7684\u77E9\u5F62\u91CD\u7B97\uFF08\u8F6E\u8BE2\u53EA\u7528\u6765\u53D1\u73B0\u9762\u677F\u51FA\u73B0\uFF09\u3002\n *\n * \u672C\u7EC4\u4EF6\u4ECD\u6CE8\u518C\u5728 `shell.overlay`\u2014\u2014\u5B83\u53EA\u662F**\u6E32\u67D3\u51FA\u53E3**\u5728\u90A3\u91CC\uFF08\u4E3A\u4E86\u62FF\u5230\n * `useLive` \u4E0E\u5199\u5165\u52A8\u4F5C\uFF09\uFF0C\u5B9E\u9645 DOM \u901A\u8FC7 portal \u843D\u5728\u9762\u677F\u5185\u3002\n */\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { PANEL_HEIGHT_FIELD, PANEL_WIDTH_FIELD, type ComposerUxSettings } from '../settings-contract.ts'\nimport {\n RESIZE_EDGE_CLASS, RESIZE_GRIP_CLASS, RESIZE_LAYER_CLASS, RESIZE_OUTLINE_CLASS,\n RESIZE_OUTLINE_STYLE, clampPanelHeight, clampPanelWidth, findSettingsPanel, handleBox,\n type ResizeEdge,\n} from './panel.ts'\n\nexport interface PanelResizeInjected {\n hooks: { live: SnapshotStore<ComposerUxSettings> }\n actions: {\n /** \u5199\u4E00\u4E2A\u5B57\u6BB5\uFF08boolean \u6216 number\uFF09\u3002 */\n setField: (field: string, value: boolean | number) => void\n }\n}\n\nexport type PanelResizeProps = PropsRuntime<'shell.overlay'> & InjectFace<PanelResizeInjected>\n\n/** \u62D6\u62FD\u8D77\u59CB\u72B6\u6001\uFF08move/up \u95ED\u5305\u5171\u4EAB\uFF09\u3002 */\ninterface DragStart {\n readonly edge: ResizeEdge\n readonly x: number\n readonly y: number\n readonly left: number\n readonly top: number\n readonly width: number\n readonly height: number\n}\n\n/** \u53EF\u62D6\u62FD\u7684\u56DB\u8FB9 + \u53F3\u4E0B\u89D2\u3002 */\nconst EDGES: readonly ResizeEdge[] = ['left', 'right', 'top', 'bottom', 'br']\n\n/** \u6E32\u67D3\u8BBE\u7F6E\u9762\u677F\u5C3A\u5BF8\u624B\u67C4\uFF1B\u65E0\u9762\u677F\u6216\u5F00\u5173\u5173\u95ED\u65F6\u4E0D\u6E32\u67D3\u3002 */\nexport function PanelResizeHandles({ useLive, actions }: PanelResizeProps) {\n const settings = useLive(value => ({\n enabled: value.enabled,\n panelResize: value.panelResize,\n panelWidth: value.panelWidth,\n panelHeight: value.panelHeight,\n }))\n const enabled = settings.enabled === true && settings.panelResize === true\n const [panel, setPanel] = useState<HTMLElement | null>(null)\n const [active, setActive] = useState<ResizeEdge | null>(null)\n const dragRef = useRef<DragStart | null>(null)\n\n // \u53D1\u73B0/\u5931\u53BB\u8BBE\u7F6E\u5BF9\u8BDD\u6846\uFF08\u5B98\u65B9 shell \u5143\u7D20\u6302\u8F7D React \u611F\u77E5\u4E0D\u5230\uFF0C\u6545\u8F6E\u8BE2\uFF1B\n // \u53EA\u5728\u300C\u6709\u6CA1\u6709\u9762\u677F\u300D\u771F\u7684\u53D8\u5316\u65F6\u624D setState\uFF0C\u907F\u514D\u65E0\u8C13\u91CD\u6E32\u67D3\uFF09\u3002\n useEffect(() => {\n if (!enabled) {\n setPanel(null)\n return\n }\n let current: HTMLElement | null = null\n const probe = (): void => {\n const found = findSettingsPanel()\n if (found === current) return\n current = found\n setPanel(found)\n }\n probe()\n const timer = setInterval(probe, 250)\n return () => { clearInterval(timer) }\n }, [enabled])\n\n // \u5957\u7528\u6301\u4E45\u5316\u5C3A\u5BF8\uFF1A\u9762\u677F\u51FA\u73B0\u65F6\u3001\u4EE5\u53CA**\u5C3A\u5BF8\u8BBE\u7F6E\u53D8\u5316\u65F6**\uFF08\u8FD9\u6837\u8BBE\u7F6E\u9875\u91CC\u70B9\n // \u300C\u5C3A\u5BF8\u9884\u8BBE\u300D\u5F53\u573A\u5C31\u53D8\uFF0C\u4E0D\u5FC5\u5173\u6389\u8BBE\u7F6E\u518D\u91CD\u5F00\uFF09\u3002\u8BBE\u7F6E\u88AB\u6E05\u7A7A\u65F6\u79FB\u9664\u5185\u8054\u6837\u5F0F\uFF0C\n // \u56DE\u843D\u5230\u5B98\u65B9\u9ED8\u8BA4 800\u3002\n useEffect(() => {\n if (panel === null) return\n const width = settings.panelWidth\n const height = settings.panelHeight\n if (width === undefined) panel.style.removeProperty('width')\n else panel.style.width = `${clampPanelWidth(width)}px`\n if (height === undefined) panel.style.removeProperty('height')\n else panel.style.height = `${clampPanelHeight(height)}px`\n }, [panel, settings.panelWidth, settings.panelHeight])\n\n if (!enabled || panel === null) return null\n\n const onPointerDown = (edge: ResizeEdge, event: React.PointerEvent): void => {\n event.preventDefault()\n event.stopPropagation()\n const el = panel\n const rect = el.getBoundingClientRect()\n // \u628A\u300C\u5C45\u4E2D flex \u5B50\u9879\u300D\u8F6C\u6210\u56FA\u5B9A\u5B9A\u4F4D\u540E\u518D\u62D6\uFF1A\u5C45\u4E2D\u7684\u5143\u7D20\u4E00\u6539\u5BBD\u5EA6\u4F1A**\u4E24\u4FA7\u540C\u65F6\n // \u4F38\u7F29**\uFF0C\u62D6\u53F3\u8FB9\u5DE6\u8FB9\u4E5F\u8DDF\u7740\u52A8\uFF0C\u624B\u611F\u662F\u9519\u7684\u3002\u8F6C\u6210 fixed \u4E4B\u540E\u62D6\u54EA\u8FB9\u5C31\u53EA\u52A8\u54EA\u8FB9\u3002\n el.style.position = 'fixed'\n el.style.margin = '0'\n el.style.left = `${rect.left}px`\n el.style.top = `${rect.top}px`\n el.style.width = `${rect.width}px`\n el.style.height = `${rect.height}px`\n\n const start: DragStart = {\n edge, x: event.clientX, y: event.clientY,\n left: rect.left, top: rect.top, width: rect.width, height: rect.height,\n }\n dragRef.current = start\n setActive(edge)\n document.body.style.cursor = String(handleBox(edge).cursor ?? 'default')\n document.body.style.userSelect = 'none'\n\n const onMove = (move: PointerEvent): void => {\n if (dragRef.current !== start) return\n move.preventDefault()\n const dx = move.clientX - start.x\n const dy = move.clientY - start.y\n let { left, top, width, height } = start\n if (edge === 'right' || edge === 'br') width = clampPanelWidth(start.width + dx)\n if (edge === 'bottom' || edge === 'br') height = clampPanelHeight(start.height + dy)\n if (edge === 'left') {\n width = clampPanelWidth(start.width - dx)\n left = start.left + (start.width - width)\n }\n if (edge === 'top') {\n height = clampPanelHeight(start.height - dy)\n top = start.top + (start.height - height)\n }\n el.style.left = `${Math.round(left)}px`\n el.style.top = `${Math.round(top)}px`\n el.style.width = `${Math.round(width)}px`\n el.style.height = `${Math.round(height)}px`\n }\n const onUp = (): void => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n dragRef.current = null\n setActive(null)\n const box = el.getBoundingClientRect()\n actions.setField(PANEL_WIDTH_FIELD, Math.round(clampPanelWidth(box.width)))\n actions.setField(PANEL_HEIGHT_FIELD, Math.round(clampPanelHeight(box.height)))\n document.body.style.removeProperty('cursor')\n document.body.style.removeProperty('user-select')\n }\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n }\n\n return createPortal(\n <div className={RESIZE_LAYER_CLASS} data-composer-ux-resize>\n <div className={RESIZE_OUTLINE_CLASS} style={RESIZE_OUTLINE_STYLE} />\n {EDGES.map(edge => (\n <div\n key={edge}\n className={edge === 'br' ? RESIZE_GRIP_CLASS : RESIZE_EDGE_CLASS}\n data-active={active === edge ? 'true' : undefined}\n title={edge === 'br' ? '\u62D6\u52A8\u6539\u9762\u677F\u5927\u5C0F' : undefined}\n style={handleBox(edge)}\n onPointerDown={event => { onPointerDown(edge, event) }}\n >\n {edge === 'br' && (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" aria-hidden>\n <path\n d=\"M11 1 1 11M11 6 6 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n strokeLinecap=\"round\"\n />\n </svg>\n )}\n </div>\n ))}\n </div>,\n panel,\n )\n}\n", "/**\n * \u8BBE\u7F6E\u9875\u300C\u8F93\u5165\u4F53\u9A8C\u300D\u3002\n *\n * \u7248\u5F0F\u5BF9\u9F50\u793E\u533A\u63D2\u4EF6 @linxin666/dsh-web-all \u7684\u300CWeb \u63D2\u4EF6\u300D\u9875\uFF1A\n * \u9876\u90E8\u5E38\u663E\uFF1A\u4E2D\u6587\u540D + \u4E00\u884C\u63CF\u8FF0\uFF08\u5185\u5D4C\u82F1\u6587\u5305\u540D dsh-composer-ux\uFF09+ \u603B\u5F00\u5173\uFF1B\n * \u5176\u4E0B\u4E09\u4E2A\u680F\u76EE\uFF08\u952E\u4F4D / \u53F3\u952E\u83DC\u5355 / \u8BBE\u7F6E\u9762\u677F\uFF09\u4E3A\u6298\u53E0\u5361\uFF0C\u6807\u9898\u884C\u53EA\u653E\u4E00\u53E5\n * \u6982\u89C8\uFF0C\u957F\u8BF4\u660E\u4E0E\u5177\u4F53\u63A7\u4EF6\u90FD\u5728\u5C55\u5F00\u540E\u7684\u5185\u5BB9\u533A\u91CC\uFF1B\u9ED8\u8BA4\u5168\u90E8\u6298\u53E0\u3001\u4E0D\u8BB0\u5FC6\u3002\n */\nimport React, { useEffect, useRef, useState, type CSSProperties } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsSectionOwnerProps } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n DEFAULT_HEADER_NAME, ENABLED_FIELD, HEADER_ENABLED_FIELD, HEADER_NAME_FIELD,\n HEADER_NAME_MAX, HEADER_ROUTES_FIELD, HEADER_VALUE_FIELD, HEADER_VALUE_MAX,\n MENU_ITEMS, MENU_NATIVE_FIELD, NEWLINE_PRESETS, OPTIMIZER_TIERS, OPTIMIZER_TIER_FIELD,\n PANEL_HEIGHT_FIELD,\n PANEL_RESIZE_FIELD, PANEL_SCROLL_FIELD, PANEL_WIDTH_FIELD, QUICK_LABEL_MAX,\n QUICK_PROMPTS_FIELD, QUICK_PROMPT_MAX, QUICK_TEXT_MAX, SEND_PRESETS,\n newQuickPromptId, newSessionId,\n type ComposerUxSettings, type MenuField, type OptimizerTier, type QuickPrompt,\n type SettingsField,\n} from '../settings-contract.ts'\nimport {\n evaluateRecordedKey, displayChord, type ChordEvent,\n} from './chords.ts'\nimport {\n description, hintError, hintInfo, kbd, pill, pillActive, row, rowDesc, rowText, rowTitle,\n textInput,\n} from './styles.ts'\n\n/** \u8BBE\u7F6E\u9875\u6CE8\u5165\u9762\u3002 */\nexport interface SettingsSectionInjected {\n hooks: {\n /** \u5F53\u524D\u89E3\u6790\u540E\u7684\u8BBE\u7F6E\u5FEB\u7167\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n }\n actions: {\n /** \u5199\u4E00\u4E2A\u5B57\u6BB5\uFF08\u952E\u4F4D\u4E3A\u89C4\u8303\u4E32\uFF0C\u5F00\u5173\u4E3A\u5E03\u5C14\uFF0C\u5C3A\u5BF8\u4E3A\u6570\u5B57\uFF0C\u5FEB\u6377\u6307\u4EE4\u4E3A\u6570\u7EC4\uFF09\u3002 */\n setField: (field: SettingsField, value: unknown) => void\n /** \u6E05\u7A7A\u4E00\u4E2A\u5B57\u6BB5\uFF08\u56DE\u843D\u5230 schema \u9ED8\u8BA4\uFF09\u3002 */\n clearField: (field: SettingsField) => void\n /** \u5168\u90E8\u6062\u590D\u9ED8\u8BA4\uFF08\u6E05\u7A7A\u7528\u6237\u8986\u76D6\uFF0C\u56DE\u843D\u5230 schema \u9ED8\u8BA4\uFF09\u3002 */\n resetAll: () => void\n }\n}\n\nexport type SettingsSectionProps =\n PropsRuntime<'settings.section'>\n & SettingsSectionOwnerProps\n & InjectFace<SettingsSectionInjected>\n\n/** \u5C55\u5F00\u533A\u5185\u7684\u5BFC\u8BED\u3002 */\nconst bodyLead: CSSProperties = { ...description, margin: '12px 0' }\n\n/** \u6298\u53E0\u7BAD\u5934\uFF08\u5185\u8054 SVG\uFF0C\u5C55\u5F00\u65F6\u9760\u7236\u7EA7 class \u65CB\u8F6C 180\u00B0\uFF09\u3002 */\nfunction Chevron() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.25 5.5L7 9.25L10.75 5.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\n/**\n * \u53EF\u6298\u53E0\u680F\u76EE\uFF1A\u6574\u884C\u6807\u9898\u5C31\u662F\u6309\u94AE\uFF0C\u9ED8\u8BA4\u6298\u53E0\u4E14\u4E0D\u8BB0\u5FC6\u5C55\u5F00\u72B6\u6001\n * \uFF08\u6BCF\u6B21\u6253\u5F00\u8BBE\u7F6E\u9875\u90FD\u56DE\u5230\u6298\u53E0\uFF09\u3002\n */\nfunction FoldCard(props: { name: string; summary: string; children: React.ReactNode }) {\n const [open, setOpen] = useState(false)\n return (\n <section className={open ? 'dsh-ux-card dsh-ux-cardOpen' : 'dsh-ux-card'}>\n <button\n type=\"button\"\n className=\"dsh-ux-cardHeader\"\n aria-expanded={open}\n onClick={() => { setOpen(current => !current) }}\n >\n <span className=\"dsh-ux-cardHeadText\">\n <span className=\"dsh-ux-cardName\">{props.name}</span>\n <span className=\"dsh-ux-cardDescription\">{props.summary}</span>\n </span>\n <span className={open ? 'dsh-ux-cardChevron dsh-ux-cardChevronOpen' : 'dsh-ux-cardChevron'}>\n <Chevron />\n </span>\n </button>\n {open && <div className=\"dsh-ux-cardBody\">{props.children}</div>}\n </section>\n )\n}\n\n/** \u952E\u4F4D\u884C\uFF1A\u5F53\u524D\u503C + \u9884\u8BBE + \u5F55\u5236 + \u6E05\u9664\u3002 */\nfunction KeyRow(props: {\n title: string\n desc: string\n value: string\n presets: readonly string[]\n conflict: (chord: string) => boolean\n onChange: (chord: string) => void\n /** \u5C55\u5F00\u533A\u91CC\u7684\u7B2C\u4E00\u884C\uFF1A\u4E0D\u753B\u4E0A\u8FB9\u6846\uFF08\u5185\u5BB9\u533A\u81EA\u5DF1\u6709\u4E00\u6761\u5206\u9694\u7EBF\uFF09\u3002 */\n first?: boolean\n}) {\n const { title, desc, value, presets, conflict, onChange, first } = props\n const [recording, setRecording] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (!recording) return\n const onKeyDown = (event: KeyboardEvent): void => {\n // \u5F55\u5236\u671F\u95F4\u541E\u6389\u6240\u6709\u6309\u952E\uFF0C\u907F\u514D\u6C61\u67D3\u8F93\u5165\u6846\u6216\u9875\u9762\u3002\n event.preventDefault()\n event.stopPropagation()\n if (event.isComposing) return\n const result = evaluateRecordedKey(event as unknown as ChordEvent)\n if (result.kind === 'ignore') return\n if (result.kind === 'cancel') {\n setRecording(false)\n setError(null)\n return\n }\n if (result.kind === 'clear') {\n setRecording(false)\n setError(null)\n onChange('')\n return\n }\n if (result.kind === 'reject') {\n setError(result.message)\n return\n }\n if (conflict(result.chord)) {\n setRecording(false)\n setError('\u53D1\u9001\u4E0E\u6362\u884C\u4E0D\u80FD\u8BBE\u4E3A\u76F8\u540C\u6309\u952E\uFF08\u53EF\u5148\u7ED9\u53E6\u4E00\u4FA7\u6362\u952E\uFF0C\u518D\u7ED1\u5B9A\u8BE5\u952E\uFF09\u3002')\n return\n }\n setRecording(false)\n setError(null)\n onChange(result.chord)\n }\n window.addEventListener('keydown', onKeyDown, true)\n return () => { window.removeEventListener('keydown', onKeyDown, true) }\n }, [recording, conflict, onChange])\n\n const base = first === true ? { ...row, borderTop: 'none' } : row\n\n return (\n <div style={{ ...base, flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>{title}</div>\n <div style={rowDesc}>{desc}</div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n <span style={kbd}>{displayChord(value)}</span>\n {!recording && presets.map(preset => (\n <button\n key={preset}\n type=\"button\"\n style={value === preset ? pillActive : pill}\n onClick={() => { setError(null); onChange(preset) }}\n >\n {displayChord(preset)}\n </button>\n ))}\n {!recording && value !== '' && (\n <button type=\"button\" style={pill} onClick={() => { setError(null); onChange('') }}>\n \u6E05\u9664\n </button>\n )}\n <button\n type=\"button\"\n style={recording ? pillActive : pill}\n onClick={() => { setRecording(true); setError(null) }}\n >\n {recording ? '\u8BF7\u6309\u4E0B\u65B0\u7EC4\u5408\u952E\u2026' : '\u81EA\u5B9A\u4E49\u2026'}\n </button>\n {recording && (\n <button type=\"button\" style={pill} onClick={() => { setRecording(false); setError(null) }}>\n Esc \u53D6\u6D88\n </button>\n )}\n {error !== null && (\n <span style={{ color: 'var(--dsw-alias-state-error-primary)', fontSize: 12 }}>{error}</span>\n )}\n </div>\n </div>\n )\n}\n\n/** \u5F00\u5173\u884C\u3002 */\nfunction ToggleRow(props: {\n label: string\n desc?: string\n checked: boolean\n onChange: (next: boolean) => void\n /** \u5C55\u5F00\u533A\u91CC\u7684\u7B2C\u4E00\u884C\uFF1A\u4E0D\u753B\u4E0A\u8FB9\u6846\u3002 */\n first?: boolean\n}) {\n const { label, desc, checked, onChange, first } = props\n return (\n <div style={first === true ? { ...row, borderTop: 'none' } : row}>\n <div style={rowText}>\n <div style={rowTitle}>{label}</div>\n {desc !== undefined && desc !== '' && <div style={rowDesc}>{desc}</div>}\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n onClick={() => { onChange(!checked) }}\n style={{\n width: 36,\n height: 20,\n borderRadius: 999,\n border: '0.5px solid var(--dsw-alias-border-l2)',\n cursor: 'pointer',\n background: checked\n ? 'var(--dsw-alias-button-primary-fill)'\n : 'var(--dsw-alias-interactive-bg-hover)',\n position: 'relative',\n flex: '0 0 auto',\n padding: 0,\n }}\n >\n <span\n style={{\n position: 'absolute',\n top: 2,\n left: checked ? 18 : 2,\n width: 14,\n height: 14,\n borderRadius: '50%',\n background: checked\n ? 'var(--dsw-alias-label-primary-foreground)'\n : 'var(--dsw-alias-label-secondary)',\n transition: 'left 0.12s ease',\n }}\n />\n </button>\n </div>\n )\n}\n\n/** \u6587\u672C\u5B57\u6BB5\u884C\uFF1A\u6807\u9898 + \u8BF4\u660E + \u8F93\u5165\u6846\uFF08\u53EF\u9009\u52A8\u4F5C\u6309\u94AE\uFF09\u3002\n * \u8F93\u5165\u8FC7\u7A0B\u4E2D\u53EA\u6539\u672C\u5730\u8349\u7A3F\uFF0C\u5931\u7126\u6216\u56DE\u8F66\u624D\u843D\u76D8\u2014\u2014\u907F\u514D\u6BCF\u6572\u4E00\u4E2A\u5B57\u5C31\u5199\u4E00\u6B21\u914D\u7F6E\u6587\u4EF6\u3002 */\nfunction TextFieldRow(props: {\n title: string\n desc: string\n value: string\n placeholder?: string\n maxLength: number\n onChange: (next: string) => void\n action?: { label: string; onClick: () => void }\n /** \u5C55\u5F00\u533A\u91CC\u7684\u7B2C\u4E00\u884C\uFF1A\u4E0D\u753B\u4E0A\u8FB9\u6846\u3002 */\n first?: boolean\n}) {\n const { title, desc, value, placeholder, maxLength, onChange, action, first } = props\n const [draft, setDraft] = useState(value)\n const focused = useRef(false)\n\n // \u53EA\u5728\u6CA1\u6709\u7126\u70B9\u65F6\u8DDF\u968F\u5916\u90E8\u503C\uFF1A\u5199\u76D8\u662F\u5F02\u6B65\u5F80\u8FD4\uFF0C\u8F93\u5165\u4E2D\u540C\u6B65\u4F1A\u628A\u7528\u6237\u6B63\u5728\u6253\u7684\u5B57\u56DE\u6EDA\u3002\n useEffect(() => {\n if (!focused.current) setDraft(value)\n }, [value])\n\n const commit = (): void => {\n if (draft === value) return\n onChange(draft.trim())\n }\n\n const base = first === true ? { ...row, borderTop: 'none' } : row\n\n return (\n <div style={{ ...base, flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>{title}</div>\n <div style={rowDesc}>{desc}</div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"text\"\n value={draft}\n placeholder={placeholder ?? ''}\n maxLength={maxLength}\n spellCheck={false}\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n onFocus={() => { focused.current = true }}\n onChange={event => { setDraft(event.target.value) }}\n onBlur={() => { focused.current = false; commit() }}\n onKeyDown={event => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n commit()\n event.currentTarget.blur()\n }}\n style={textInput}\n />\n {action !== undefined && (\n <button type=\"button\" style={pill} onClick={action.onClick}>{action.label}</button>\n )}\n </div>\n </div>\n )\n}\n\n/** \u5FEB\u6377\u6307\u4EE4\u7F16\u8F91\u533A\uFF1A\u672C\u5730\u8349\u7A3F + \u663E\u5F0F\u4FDD\u5B58\uFF08\u907F\u514D\u6BCF\u6572\u4E00\u4E2A\u5B57\u5C31\u5199\u4E00\u6B21\u914D\u7F6E\u6587\u4EF6\uFF09\u3002 */\nfunction QuickPromptsEditor(props: {\n items: readonly QuickPrompt[]\n onSave: (next: readonly QuickPrompt[]) => void\n}) {\n const [rows, setRows] = useState(() => props.items.map(item => ({ ...item })))\n const [dirty, setDirty] = useState(false)\n\n const update = (id: string, patch: Partial<QuickPrompt>): void => {\n setDirty(true)\n setRows(current => current.map(row => (row.id === id ? { ...row, ...patch } : row)))\n }\n const remove = (id: string): void => {\n setDirty(true)\n setRows(current => current.filter(row => row.id !== id))\n }\n const add = (): void => {\n if (rows.length >= QUICK_PROMPT_MAX) return\n setDirty(true)\n setRows(current => current.concat([{\n id: newQuickPromptId(), label: '', prompt: '', always: false,\n }]))\n }\n const move = (index: number, delta: number): void => {\n const target = index + delta\n if (target < 0 || target >= rows.length) return\n setDirty(true)\n setRows((current) => {\n const next = [...current]\n const [row] = next.splice(index, 1)\n next.splice(target, 0, row!)\n return next\n })\n }\n const save = (): void => {\n // \u540D\u79F0\u7559\u7A7A\u65F6\u7528\u6B63\u6587\u5F00\u5934\u515C\u5E95\uFF08\u51C0\u5316\u7AEF\u4E5F\u4F1A\u8FD9\u4E48\u505A\uFF0C\u8FD9\u91CC\u5148\u7ED9\u7528\u6237\u4E00\u4E2A\u53EF\u89C1\u7684\u843D\u70B9\uFF09\u3002\n const cleaned = rows\n .map(row => ({\n ...row,\n prompt: row.prompt.trim(),\n label: row.label.trim() === '' ? row.prompt.trim().slice(0, 12) : row.label.trim(),\n }))\n .filter(row => row.prompt !== '')\n props.onSave(cleaned)\n setRows(cleaned)\n setDirty(false)\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {rows.map((row, index) => (\n <div\n key={row.id}\n style={{\n display: 'flex', flexDirection: 'column', gap: 6,\n padding: 8, borderRadius: 8,\n border: '0.5px solid var(--dsw-alias-border-l2)',\n background: 'var(--dsw-alias-bg-layer-1)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <input\n type=\"text\"\n value={row.label}\n placeholder=\"\u540D\u79F0\uFF0C\u5982\uFF1A\u4EC5\u8BF4\u660E\u539F\u56E0\"\n maxLength={QUICK_LABEL_MAX}\n spellCheck={false}\n onChange={event => { update(row.id, { label: event.target.value }) }}\n style={{ ...textInput, flex: '0 0 150px' }}\n />\n <label style={{ display: 'inline-flex', alignItems: 'center', gap: 4, ...rowDesc, margin: 0, flex: '0 0 auto' }}>\n <input\n type=\"checkbox\"\n checked={row.always}\n style={{ margin: 0, cursor: 'pointer' }}\n onChange={event => { update(row.id, { always: event.target.checked }) }}\n />\n \u9ED8\u8BA4\u63D2\u5165\n </label>\n <span style={{ flex: 1 }} />\n <button type=\"button\" style={pill} title=\"\u4E0A\u79FB\" onClick={() => { move(index, -1) }}>\u2191</button>\n <button type=\"button\" style={pill} title=\"\u4E0B\u79FB\" onClick={() => { move(index, 1) }}>\u2193</button>\n <button type=\"button\" style={pill} title=\"\u5220\u9664\u8FD9\u6761\" onClick={() => { remove(row.id) }}>\u2715</button>\n </div>\n <textarea\n value={row.prompt}\n placeholder=\"\u63D0\u793A\u8BCD\u6B63\u6587\uFF1A\u70B9\u51FB\u8BE5\u6761\u76EE\u65F6\u63D2\u5165\u8F93\u5165\u6846\uFF1B\u52FE\u4E86\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u5219\u5728\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\"\n maxLength={QUICK_TEXT_MAX}\n spellCheck={false}\n rows={Math.min(4, Math.max(2, Math.ceil(row.prompt.length / 46)))}\n onChange={event => { update(row.id, { prompt: event.target.value }) }}\n style={{ ...textInput, resize: 'vertical', fontFamily: 'inherit', lineHeight: 1.5 }}\n />\n </div>\n ))}\n\n {rows.length === 0 && (\n <p style={rowDesc}>\u8FD8\u6CA1\u6709\u6761\u76EE\u3002\u70B9\u4E0B\u9762\u7684\u300C+ \u6DFB\u52A0\u4E00\u6761\u300D\u5F00\u59CB\u5EFA\u81EA\u5DF1\u7684\u5FEB\u6377\u6307\u4EE4\u3002</p>\n )}\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n <button type=\"button\" style={pill} onClick={add}>+ \u6DFB\u52A0\u4E00\u6761</button>\n <button\n type=\"button\"\n style={dirty ? pillActive : pill}\n onClick={save}\n disabled={!dirty}\n >\n {dirty ? '\u4FDD\u5B58\u4FEE\u6539' : '\u5DF2\u4FDD\u5B58'}\n </button>\n <span style={rowDesc}>\n \u5171 {rows.length} / {QUICK_PROMPT_MAX} \u6761 \u00B7 \u52FE\u4E86\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\uFF1A\n {rows.filter(row => row.always).length} \u6761\n </span>\n </div>\n </div>\n )\n}\n\n/** \u8BBE\u7F6E\u9875\u4E3B\u4F53\u3002 */\nexport function SettingsSection({ useLive, actions }: SettingsSectionProps) {\n const settings = useLive(item => item)\n const [conflict, setConflict] = useState<string | null>(null)\n\n const setKey = (side: 'send' | 'newline', chord: string): void => {\n const other = side === 'send' ? settings.newlineKey : settings.sendKey\n if (chord !== '' && chord === other) {\n setConflict(chord)\n return\n }\n setConflict(null)\n actions.setField(side === 'send' ? 'sendKey' : 'newlineKey', chord)\n }\n\n const conflictHint = conflict !== null\n ? `\u300C${displayChord(conflict)}\u300D\u5DF2\u88AB\u53E6\u4E00\u4FA7\u5360\u7528\uFF0C\u8BF7\u5148\u4E3A\u53E6\u4E00\u4FA7\u9009\u62E9\u5176\u5B83\u6309\u952E\u3002`\n : null\n\n const menuEnabled = MENU_ITEMS.filter(item => settings[item.field]).length\n const keySummary = `\u53D1\u9001 ${displayChord(settings.sendKey)} \u00B7 \u6362\u884C ${displayChord(settings.newlineKey)}`\n const menuSummary = settings.menuNative\n ? '\u5F53\u524D\uFF1A\u7CFB\u7EDF\u539F\u751F\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09'\n : `\u5F53\u524D\uFF1A\u81EA\u5B9A\u4E49\u83DC\u5355 \u00B7 ${menuEnabled} / ${MENU_ITEMS.length} \u9879\u5F00\u542F`\n const panelSummary = `\u5BFC\u822A\u6EDA\u52A8 ${settings.panelScroll ? '\u5F00' : '\u5173'}`\n + ` \u00B7 \u8FB9\u7F18\u7F29\u653E ${settings.panelResize ? '\u5F00' : '\u5173'}`\n + ` \u00B7 ${settings.panelWidth}\u00D7${settings.panelHeight}`\n // \u8BF7\u6C42\u5934\u680F\u76EE\u7684\u6982\u89C8\u76F4\u63A5\u590D\u7528\u5BBF\u4E3B\u534A\u5199\u56DE\u6765\u7684\u6267\u884C\u7ED3\u679C\uFF08'\u5DF2\u5199\u5165 opencode-go' \u8FD9\u7C7B\uFF09\u3002\n const headerSummary = settings.headerEnabled\n ? (settings.headerStatus === '' ? '\u5DF2\u542F\u7528' : settings.headerStatus)\n : '\u672A\u542F\u7528'\n const alwaysCount = settings.quickPrompts.filter(item => item.always).length\n const quickSummary = `${settings.quickPrompts.length} \u6761`\n + ` \u00B7 \u9ED8\u8BA4\u63D2\u5165 ${alwaysCount} \u6761`\n + ` \u00B7 \u4F18\u5316\u6863\u4F4D ${OPTIMIZER_TIERS.find(item => item.id === settings.optimizerTier)?.label ?? '\u9AD8\u7EA7'}`\n const headerStatusText = settings.headerEnabled\n ? (settings.headerStatus === '' ? '\u7B49\u5F85\u9996\u6B21\u5199\u5165\u2026' : settings.headerStatus)\n : '\u672A\u542F\u7528\uFF08\u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u5199\u5165\uFF09'\n\n return (\n <div style={{ padding: '4px 2px' }}>\n {/* \u9876\u90E8\u5E38\u663E\u533A\uFF1A\u4E2D\u6587\u540D + \u5185\u5D4C\u82F1\u6587\u5305\u540D\u7684\u4E00\u884C\u63CF\u8FF0 + \u603B\u5F00\u5173\u3002 */}\n <section className=\"dsh-ux-card\">\n <div className=\"dsh-ux-cardHeaderStatic\">\n <span className=\"dsh-ux-cardHeadText\">\n <h2 className=\"dsh-ux-cardName\">\u8F93\u5165\u4F53\u9A8C</h2>\n <p className=\"dsh-ux-cardDescription\">\n dsh-composer-ux \u00B7 \u4E3B\u804A\u5929\u8F93\u5165\u6846\u7684\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\uFF1B\u8BBE\u7F6E\u5373\u65F6\u751F\u6548\u5E76\u6301\u4E45\u4FDD\u5B58\u3002\n </p>\n </span>\n </div>\n <div className=\"dsh-ux-cardBody\">\n <ToggleRow\n first\n label=\"\u542F\u7528\u8F93\u5165\u589E\u5F3A\"\n desc=\"\u5173\u95ED\u540E\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\u6EDA\u52A8/\u7F29\u653E\u5168\u90E8\u505C\u7528\uFF08\u672C\u9875\u4FDD\u7559\u7528\u4E8E\u91CD\u65B0\u5F00\u542F\uFF09\"\n checked={settings.enabled}\n onChange={next => { actions.setField(ENABLED_FIELD, next) }}\n />\n {!settings.enabled && (\n <p style={hintInfo}>\n \u5DF2\u505C\u7528\uFF1A\u53D1\u9001/\u6362\u884C\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u3001\u8BBE\u7F6E\u9762\u677F\u6EDA\u52A8\u4E0E\u8FB9\u7F18\u7F29\u653E\u5747\u4E0D\u518D\u751F\u6548\uFF0C\u8F93\u5165\u6846\u6062\u590D DSH \u539F\u751F\u884C\u4E3A\u3002\n \u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u53EF\u4E00\u952E\u6062\u590D\uFF1B\u6240\u6709\u8BBE\u7F6E\u503C\u4ECD\u4FDD\u7559\u3002\n </p>\n )}\n </div>\n </section>\n\n {settings.enabled && (<>\n <FoldCard name=\"\u952E\u4F4D\" summary={keySummary}>\n <p style={bodyLead}>\n \u652F\u6301\u5E38\u7528\u9884\u8BBE\uFF0C\u4E5F\u53EF\u4EE5\u70B9\u51FB\u300C\u81EA\u5B9A\u4E49\u2026\u300D\u540E\u76F4\u63A5\u6309\u4E0B\u4EFB\u610F\u7EC4\u5408\u952E\u5F55\u5236\uFF08Esc \u53D6\u6D88\uFF0CBackspace \u6E05\u9664\uFF09\u3002\n \u672A\u7ED1\u5B9A\u7684 Enter \u7CFB\u6309\u952E\u4E0D\u4F1A\u89E6\u53D1\u53D1\u9001\u6216\u6362\u884C\uFF1BCtrl+Enter / \u2318+Enter \u672A\u88AB\u7ED1\u5B9A\u65F6\u4FDD\u7559\u539F\u300C\u52A0\u901F\u63D0\u4EA4\u300D\u884C\u4E3A\uFF1B\n \u4E2D\u6587\u8F93\u5165\u6CD5\u7EC4\u5408\u671F\u95F4\u4E0D\u53D7\u5F71\u54CD\u3002\n </p>\n <KeyRow\n first\n title=\"\u53D1\u9001\u952E\"\n desc=\"\u6309\u4E0B\u540E\u53D1\u9001\u5F53\u524D\u8F93\u5165\"\n value={settings.sendKey}\n presets={SEND_PRESETS}\n conflict={chord => chord !== '' && chord === settings.newlineKey}\n onChange={chord => { setKey('send', chord) }}\n />\n <KeyRow\n title=\"\u6362\u884C\u952E\"\n desc=\"\u6309\u4E0B\u540E\u5728\u8F93\u5165\u5185\u6362\u884C\"\n value={settings.newlineKey}\n presets={NEWLINE_PRESETS}\n conflict={chord => chord !== '' && chord === settings.sendKey}\n onChange={chord => { setKey('newline', chord) }}\n />\n {conflictHint !== null && <p style={hintError}>{conflictHint}</p>}\n <div style={{ marginTop: 10 }}>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { setConflict(null); actions.resetAll() }}\n >\n \u6062\u590D\u9ED8\u8BA4\n </button>\n </div>\n </FoldCard>\n\n <FoldCard name=\"\u53F3\u952E\u83DC\u5355\" summary={menuSummary}>\n <p style={bodyLead}>\n \u53F3\u952E\u70B9\u51FB\u8F93\u5165\u6846\u65F6\u7684\u884C\u4E3A\u3002\u7CFB\u7EDF\u539F\u751F\u6A21\u5F0F\u4E0B\u7531\u6D4F\u89C8\u5668\u5F39\u51FA\u81EA\u5DF1\u7684\u83DC\u5355\uFF08\u6837\u5F0F\u968F\u6D4F\u89C8\u5668\u800C\u53D8\u5316\uFF0C\n \u7C98\u8D34\u514D\u6388\u6743\u3001\u96F6\u914D\u7F6E\uFF09\uFF1B\u81EA\u5B9A\u4E49\u6A21\u5F0F\u4F7F\u7528\u56FA\u5B9A\u6837\u5F0F\u83DC\u5355\uFF08\u672A\u9009\u4E2D\u6587\u672C\u65F6\u300C\u526A\u5207 / \u590D\u5236 / \u5220\u9664\u300D\u7F6E\u7070\uFF0C\n \u7C98\u8D34\u9700\u8981\u6D4F\u89C8\u5668\u526A\u8D34\u677F\u6388\u6743\uFF0CFirefox \u8981\u5728 about:config \u4E2D\u8BBE\u7F6E\n permissions.default.clipboard-read = 1 \u624D\u80FD\u514D\u5F39\u7A97\uFF09\u3002\n </p>\n <ToggleRow\n first\n label=\"\u4F7F\u7528\u7CFB\u7EDF\u539F\u751F\u83DC\u5355\"\n desc=\"\u6253\u5F00\u540E\u53F3\u952E\u7C98\u8D34\u514D\u6388\u6743\uFF08\u70B9\u51FB\u6D4F\u89C8\u5668\u83DC\u5355\u7684\u7C98\u8D34\u76F4\u63A5\u6210\u529F\uFF09\uFF1B\u5173\u95ED\u540E\u6062\u590D\u81EA\u5B9A\u4E49\u83DC\u5355\"\n checked={settings.menuNative}\n onChange={next => { actions.setField(MENU_NATIVE_FIELD, next) }}\n />\n {!settings.menuNative && (<>\n {MENU_ITEMS.map(item => (\n <ToggleRow\n key={item.field}\n label={item.label}\n desc={item.shortcut !== '' ? `\u5FEB\u6377\u952E ${item.shortcut}` : ''}\n checked={settings[item.field]}\n onChange={next => { actions.setField(item.field as MenuField, next) }}\n />\n ))}\n <div style={{ marginTop: 10 }}>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { for (const item of MENU_ITEMS) actions.setField(item.field as MenuField, true) }}\n >\n \u5168\u90E8\u5F00\u542F\n </button>\n </div>\n </>)}\n </FoldCard>\n\n <FoldCard name=\"\u5FEB\u6377\u6307\u4EE4\" summary={quickSummary}>\n <p style={bodyLead}>\n \u8F93\u5165\u6846\u5DE5\u5177\u884C\u91CC\u90A3\u4E2A\u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6309\u94AE\u70B9\u5F00\u5C31\u662F\u8FD9\u5F20\u6E05\u5355\uFF1A\u70B9\u6761\u76EE\u628A\u5185\u5BB9\u63D2\u5165\u8F93\u5165\u6846\uFF1B\n \u6761\u76EE\u53F3\u4FA7\u52FE\u4E0A\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF0C\u5219\u5728\u4F60**\u70B9\u53D1\u9001\u65F6**\u628A\u8FD9\u6761\u63D0\u793A\u8BCD\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F**\u672B\u5C3E**\n \u4E00\u8D77\u53D1\u51FA\u53BB\uFF08\u591A\u6761\u6309\u5217\u8868\u987A\u5E8F\u62FC\u63A5\uFF0C\u8F93\u5165\u6846\u91CC\u4E0D\u63D0\u524D\u663E\u793A\uFF09\u3002\n \u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u4F1A\u7528\u53E6\u4E00\u4E2A AI \u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u6574\u7406\u6210\u4E00\u6761\u80FD\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C\n \u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\uFF08Ctrl+Z \u53EF\u8FD8\u539F\uFF09\u2014\u2014\u4E0D\u4F1A\u6C61\u67D3\u5F53\u524D\u5BF9\u8BDD\uFF0C\u4E5F\u4E0D\u5360\u4F60\u7684\u5BF9\u8BDD\u8F6E\u6B21\u3002\n </p>\n <div style={{ ...row, borderTop: 'none', flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>\u4F18\u5316\u5F3A\u5EA6</div>\n <div style={rowDesc}>\n {OPTIMIZER_TIERS.find(item => item.id === settings.optimizerTier)?.hint ?? ''}\n </div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n {OPTIMIZER_TIERS.map(item => (\n <button\n key={item.id}\n type=\"button\"\n title={item.hint}\n style={settings.optimizerTier === item.id ? pillActive : pill}\n onClick={() => { actions.setField(OPTIMIZER_TIER_FIELD, item.id as OptimizerTier) }}\n >\n {item.label}\n </button>\n ))}\n </div>\n </div>\n <div style={{ ...row, borderTop: 'none', flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>\u5FEB\u6377\u6307\u4EE4\u6E05\u5355</div>\n <div style={rowDesc}>\n \u5185\u7F6E 9 \u6761\u53EF\u4EE5\u76F4\u63A5\u7528\uFF1B\u6539\u5B8C\u8BB0\u5F97\u70B9\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\u3002\n </div>\n </div>\n <QuickPromptsEditor\n items={settings.quickPrompts}\n onSave={next => { actions.setField(QUICK_PROMPTS_FIELD, next) }}\n />\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { actions.clearField(QUICK_PROMPTS_FIELD) }}\n >\n \u6062\u590D\u5185\u7F6E 9 \u6761\n </button>\n </div>\n </div>\n </FoldCard>\n\n <FoldCard name=\"\u8BBE\u7F6E\u9762\u677F\" summary={panelSummary}>\n <p style={bodyLead}>\n \u63D2\u4EF6\u88C5\u5F97\u591A\u65F6\u8BBE\u7F6E\u6761\u76EE\u5F88\u957F\uFF1A\u5F00\u542F\u300C\u5BFC\u822A\u53EF\u6EDA\u52A8\u300D\u540E\uFF0C\u5DE6\u4FA7\u5BFC\u822A\u5728\u6EA2\u51FA\u65F6\u4F1A\u51FA\u73B0\u6EDA\u52A8\u6761\u3002\n \u5F00\u542F\u300C\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u300D\u540E\uFF0C\u628A\u9F20\u6807\u79FB\u5230\u8BBE\u7F6E\u9762\u677F\u7684\u8FB9\u6216\u89D2\u4E0A\uFF08\u51FA\u73B0\u9AD8\u4EAE\u6216\u5149\u6807\u53D8\u5316\uFF09\u62D6\u52A8\u5373\u53EF\u6539\u53D8\u9762\u677F\u5927\u5C0F\uFF0C\n \u5C3A\u5BF8\u4F1A\u8BB0\u4F4F\uFF0C\u4E0B\u6B21\u6253\u5F00\u4FDD\u6301\u3002\n </p>\n <ToggleRow\n first\n label=\"\u5BFC\u822A\u53EF\u6EDA\u52A8\"\n desc=\"\u8BBE\u7F6E\u6761\u76EE\u8D85\u51FA\u9762\u677F\u9AD8\u5EA6\u65F6\u663E\u793A\u6EDA\u52A8\u6761\"\n checked={settings.panelScroll}\n onChange={next => { actions.setField(PANEL_SCROLL_FIELD, next) }}\n />\n <ToggleRow\n label=\"\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\"\n desc=\"\u62D6\u52A8\u9762\u677F\u56DB\u8FB9 / \u56DB\u89D2\u6539\u53D8\u9762\u677F\u5C3A\u5BF8\"\n checked={settings.panelResize}\n onChange={next => { actions.setField(PANEL_RESIZE_FIELD, next) }}\n />\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginTop: 10 }}>\n <span style={rowDesc}>\u5C3A\u5BF8\u9884\u8BBE\uFF1A</span>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { actions.clearField(PANEL_WIDTH_FIELD); actions.clearField(PANEL_HEIGHT_FIELD) }}\n >\n \u9ED8\u8BA4\uFF08800\uFF09\n </button>\n <button\n type=\"button\"\n style={settings.panelWidth === 640 && settings.panelHeight === 600 ? pillActive : pill}\n onClick={() => {\n actions.setField(PANEL_WIDTH_FIELD, 640)\n actions.setField(PANEL_HEIGHT_FIELD, 600)\n }}\n >\n \u7D27\u51D1\uFF08640\u00D7600\uFF09\n </button>\n <button\n type=\"button\"\n style={settings.panelWidth === 1040 && settings.panelHeight === 760 ? pillActive : pill}\n onClick={() => {\n actions.setField(PANEL_WIDTH_FIELD, 1040)\n actions.setField(PANEL_HEIGHT_FIELD, 760)\n }}\n >\n \u5BBD\u655E\uFF081040\u00D7760\uFF09\n </button>\n </div>\n </FoldCard>\n\n <FoldCard name=\"OpenCode \u8BF7\u6C42\u5934\" summary={headerSummary}>\n <p style={bodyLead}>\n OpenCode \u7684\u63A5\u53E3\u8981\u6C42\u5BA2\u6237\u7AEF\u6BCF\u6B21\u8BF7\u6C42\u90FD\u5E26\u4E0A\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID \u8BF7\u6C42\u5934\uFF08\u5B98\u65B9 Go \u6587\u6863\n \u300C\u53EF\u4EE5\u5728\u54EA\u91CC\u4F7F\u7528\uFF1F\u300D\u7B2C 3 \u6761\uFF1A\u4E3A\u6BCF\u6BB5\u5BF9\u8BDD\u5728 x-opencode-session \u4E2D\u53D1\u9001\u4F1A\u8BDD ID\uFF0C\n \u4EE5\u4FBF\u5176\u4F18\u5316\u8DEF\u7531\u4E0E\u63D0\u793A\u8BCD\u7F13\u5B58\uFF09\u3002DSH \u7684\u8BBE\u7F6E\u9875\u4E0D\u63D0\u4F9B\u8BF7\u6C42\u5934\u7F16\u8F91\u5668\uFF0C\u6240\u4EE5\u8FD9\u91CC\u76F4\u63A5\u628A\u5B83\u5199\u8FDB\n llm-pi-ai \u7684 provider \u914D\u7F6E\u2014\u2014\u4E0B\u4E00\u6B21\u6A21\u578B\u8BF7\u6C42\u5C31\u751F\u6548\uFF0C\u4E0D\u7528\u91CD\u542F\uFF0C\u4E5F\u4E0D\u7528\u624B\u5DE5\u6539 settings.yaml\u3002\n \u53EA\u5BF9 llm-pi-ai \u91CC\u300C\u5DF2\u5B58\u5728\u300D\u7684 opencode \u7CFB\u8DEF\u7531\u751F\u6548\uFF0C\u4E0D\u4F1A\u51ED\u7A7A\u65B0\u5EFA provider\uFF1B\n \u603B\u5F00\u5173\u5173\u95ED\u6216\u672C\u680F\u76EE\u505C\u7528\u65F6\uFF0C\u5199\u5165\u7684\u5934\u4F1A\u81EA\u52A8\u64A4\u9500\u3002\n </p>\n <ToggleRow\n first\n label=\"\u9644\u52A0\u8BF7\u6C42\u5934\"\n desc=\"\u6253\u5F00\u5373\u5199\u5165\uFF0C\u5E76\u5728\u6BCF\u6B21\u542F\u52A8\u65F6\u8865\u9F50\uFF1B\u5173\u95ED\u5373\u64A4\u9500\"\n checked={settings.headerEnabled}\n onChange={next => { actions.setField(HEADER_ENABLED_FIELD, next) }}\n />\n <TextFieldRow\n title=\"\u5934\u540D\"\n desc={`\u9ED8\u8BA4 ${DEFAULT_HEADER_NAME}\uFF08OpenCode \u5B98\u65B9\u8981\u6C42\u7684\u90A3\u4E00\u4E2A\uFF09`}\n value={settings.headerName}\n placeholder={DEFAULT_HEADER_NAME}\n maxLength={HEADER_NAME_MAX}\n onChange={next => { actions.setField(HEADER_NAME_FIELD, next) }}\n />\n <TextFieldRow\n title=\"\u503C\"\n desc=\"\u6240\u6709\u5BF9\u8BDD\u5171\u7528\u8FD9\u4E00\u4E2A\u503C\uFF1B\u7559\u7A7A\u65F6\u9996\u6B21\u542F\u7528\u4F1A\u81EA\u52A8\u751F\u6210\u4E00\u4E2A UUID \u5E76\u4FDD\u5B58\u6CBF\u7528\"\n value={settings.headerValue}\n placeholder=\"\u7559\u7A7A = \u81EA\u52A8\u751F\u6210\"\n maxLength={HEADER_VALUE_MAX}\n onChange={next => { actions.setField(HEADER_VALUE_FIELD, next) }}\n action={{\n label: '\u91CD\u65B0\u751F\u6210',\n onClick: () => { actions.setField(HEADER_VALUE_FIELD, newSessionId()) },\n }}\n />\n <TextFieldRow\n title=\"\u4F5C\u7528\u8DEF\u7531\"\n desc=\"\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u7559\u7A7A = \u81EA\u52A8\u5339\u914D OpenCode \u8DEF\u7531\uFF08\u540D\u5B57\u4EE5 opencode \u5F00\u5934\uFF0C\u6216 baseURL \u6307\u5411 opencode.ai\uFF09\"\n value={settings.headerRoutes}\n placeholder=\"\u7559\u7A7A = \u81EA\u52A8\uFF08opencode* \u6216 opencode.ai \u7AEF\u70B9\uFF09\"\n maxLength={HEADER_VALUE_MAX}\n onChange={next => { actions.setField(HEADER_ROUTES_FIELD, next) }}\n />\n <p style={hintInfo}>\u72B6\u6001\uFF1A{headerStatusText}</p>\n </FoldCard>\n </>)}\n </div>\n )\n}\n", "/**\n * \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6309\u94AE\uFF1A\u5750\u5728\u5B98\u65B9\u8F93\u5165\u5361\u7247\u5DE5\u5177\u884C\u91CC\u300C\u5C55\u5F00\u300D\u6309\u94AE\u7684\u65C1\u8FB9\n * \uFF08\u69FD\u4F4D `conversation.input.right`\uFF0Corder 89 < \u5C55\u5F00\u7684 90\uFF09\uFF0C\u5F62\u72B6\u4E0E\u5B83\u540C\u6B3E\u80F6\u56CA\u3002\n *\n * \u672C\u7EC4\u4EF6\u53EA\u505A\u4E09\u4EF6\u4E8B\uFF1A\n * 1. \u628A\u5B98\u65B9\u7684 `inputActions` \u4E0E\u5F53\u524D\u8349\u7A3F\u6295\u9012\u7ED9 quick-commands \u6865\u63A5\n * \uFF08\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u53D1\u9001\u62E6\u622A\u5FC5\u987B\u62FF\u5230\u5B83\u4EEC\uFF0C\u62E6\u622A\u5668\u6D3B\u5728 React \u4E4B\u5916\uFF09\uFF1B\n * 2. \u6E32\u67D3\u6309\u94AE\u3001\u70B9\u51FB\u540E\u628A\u81EA\u8EAB\u77E9\u5F62\u4EA4\u7ED9\u9762\u677F\u505A\u951A\u70B9\uFF1B\n * 3. \u628A\u9762\u677F\u7684\u5F00\u5408\u72B6\u6001\u53CD\u5C04\u5230 `aria-expanded`\u3002\n */\nimport React, { useEffect, useRef } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { ComposerUxSettings } from '../settings-contract.ts'\nimport { publishInputBridge, releaseInputBridge, type InputActionsLike } from './quick-commands.ts'\nimport { QUICK_BUTTON_CLASS } from './quick-style.ts'\n\n/** \u9762\u677F\u951A\u70B9\uFF1A\u6309\u94AE\u7684\u89C6\u53E3\u77E9\u5F62\uFF08\u9762\u677F\u636E\u6B64\u8D34\u5728\u4E0A\u65B9\uFF09\u3002 */\nexport interface QuickPanelAnchor {\n readonly left: number\n readonly bottom: number\n readonly width: number\n}\n\n/** \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6CE8\u5165\u9762\u3002 */\nexport interface QuickCommandsInjected {\n hooks: {\n /** \u5F53\u524D\u8BBE\u7F6E\uFF08\u603B\u5F00\u5173\u4E0E\u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF09\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n /** \u9762\u677F\u951A\u70B9\uFF1Bnull = \u9762\u677F\u5173\u95ED\u3002 */\n panel: SnapshotStore<QuickPanelAnchor | null>\n }\n actions: {\n /** \u4EE5\u7ED9\u5B9A\u951A\u70B9\u6253\u5F00\u9762\u677F\uFF1B\u5DF2\u5F00\u5219\u5173\u95ED\uFF08\u70B9\u6309\u94AE\u5373\u5F00\u5408\uFF09\u3002 */\n toggle: (anchor: QuickPanelAnchor) => void\n }\n}\n\nexport type QuickCommandsButtonProps =\n PropsRuntime<'conversation.input.right'>\n & InjectFace<QuickCommandsInjected>\n\n/** \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\u3002 */\nexport function QuickCommandsButton({\n useInput, inputActions, sessionId, useLive, usePanel, actions,\n}: QuickCommandsButtonProps) {\n const settings = useLive(item => item)\n const anchor = usePanel(item => item)\n const draft = useInput(state => state.draft)\n const ref = useRef<HTMLButtonElement | null>(null)\n\n // \u6BCF\u6B21\u6E32\u67D3\u628A\u5B98\u65B9\u8F93\u5165\u52A8\u4F5C\u4E0E\u8349\u7A3F\u6295\u9012\u7ED9\u6865\u63A5\uFF1A\u62E6\u622A\u5668\u8981\u5728 React \u4E4B\u5916\u8BFB\u5B83\u4EEC\u3002\n useEffect(() => {\n const sid = typeof sessionId === 'string' ? sessionId : ''\n publishInputBridge({\n actions: (inputActions ?? null) as InputActionsLike | null,\n draft: typeof draft === 'string' ? draft : '',\n sessionId: sid,\n })\n return () => { releaseInputBridge(sid) }\n }, [inputActions, draft, sessionId])\n\n if (settings.enabled !== true) return null\n\n const open = anchor !== null\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={QUICK_BUTTON_CLASS}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n title=\"\u5FEB\u6377\u6307\u4EE4\uFF1A\u4E00\u952E\u63D2\u5165\u5E38\u7528\u63D0\u793A\u8BCD\uFF0C\u6216\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4F18\u5316\u6210\u4E00\u6761\u6E05\u6670\u7684\u6307\u4EE4\"\n // \u6837\u5F0F\u5168\u90E8\u6765\u81EA\u6CE8\u5165\u7684\u6837\u5F0F\u8868\uFF08\u89C1 quick-style.ts\uFF09\uFF1A\u4E0E\u65C1\u8FB9\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\n // \u9010\u9879\u5BF9\u9F50\uFF0C\u4E14 hover / \u5C55\u5F00\u6001\u53EA\u6709\u6837\u5F0F\u8868\u80FD\u8868\u8FBE\u3002\n // \u4E0D\u8BA9\u6309\u94AE\u62A2\u8D70\u62D6\u52A8\u65F6\u53EF\u80FD\u5B58\u5728\u7684\u8F93\u5165\u6846\u9009\u533A\uFF08\u4E0E\u5B98\u65B9\u5DE5\u5177\u884C\u4E00\u81F4\uFF09\u3002\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => {\n const rect = ref.current?.getBoundingClientRect()\n actions.toggle({\n left: rect?.left ?? 0,\n bottom: rect?.bottom ?? 0,\n width: rect?.width ?? 0,\n })\n }}\n >\n <svg\n viewBox=\"0 0 16 16\"\n width=\"12\"\n height=\"12\"\n aria-hidden\n >\n <path\n d=\"M9.2 1.2 3.4 9.1h3.5l-0.9 5.7 6-8.1H8.4l0.8-5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n <span>\u5FEB\u6377\u6307\u4EE4</span>\n </button>\n )\n}\n", "/**\n * \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5C55\u5F00\u9762\u677F\uFF1A\u6CE8\u518C\u8FDB shell.overlay\uFF08root \u7EA7\u6D6E\u5C42\uFF0C\u4E0D\u53D7\u8F93\u5165\u5361\u7247\u88C1\u526A\uFF09\u3002\n *\n * \u9762\u677F\u5F62\u6001\uFF08\u4E0E\u7528\u6237\u786E\u8BA4\u8FC7\u7684\u8BED\u4E49\u4E00\u81F4\uFF09\uFF1A\n * - \u9876\u90E8\uFF1A\u300C\u2728 \u4F18\u5316\u63D0\u793A\u8BCD\u300D\u4E3B\u6309\u94AE + \u4E09\u6863\u5F3A\u5EA6\u5206\u6BB5\u63A7\u4EF6\uFF1B\n * - \u4E2D\u90E8\uFF1A\u5FEB\u6377\u6307\u4EE4\u6761\u76EE\u5217\u8868 \u2014\u2014 \u70B9\u6761\u76EE\u628A\u5185\u5BB9\u63D2\u5165\u8F93\u5165\u6846\uFF0C\u6761\u76EE\u53F3\u4FA7\u7684\u52FE\u9009\u6846\u5C31\u662F\n * \u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF08\u52FE\u4E0A\u540E\u70B9\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\uFF09\uFF1B\n * - \u5E95\u90E8\uFF1A\u72B6\u6001\u63D0\u793A + \u6307\u8DEF\u8BBE\u7F6E\u9875\u3002\n */\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n OPTIMIZER_TIERS, type ComposerUxSettings, type OptimizerTier,\n} from '../settings-contract.ts'\nimport type { QuickPanelAnchor } from './QuickCommandsButton.tsx'\nimport {\n quickAlwaysBox, quickAlwaysLabel, quickEmpty, quickFootHint, quickItem, quickItemLabel,\n quickItemPreview, quickList, quickNotice, quickPanel, quickPanelFoot, quickPanelHead,\n quickPanelTitle, quickPanelTitleRow, quickPrimaryButton, quickPrimaryButtonDisabled,\n quickTierButton, quickTierButtonActive, quickTierRow,\n} from './styles.ts'\n\n/** \u9762\u677F\u6CE8\u5165\u9762\u3002 */\nexport interface QuickPanelInjected {\n hooks: {\n /** \u5F53\u524D\u8BBE\u7F6E\uFF08\u5FEB\u6377\u6307\u4EE4\u5217\u8868 + \u6863\u4F4D + \u603B\u5F00\u5173\uFF09\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n /** \u9762\u677F\u951A\u70B9\uFF1Bnull = \u9762\u677F\u5173\u95ED\u3002 */\n panel: SnapshotStore<QuickPanelAnchor | null>\n /** \u662F\u5426\u6709\u4E00\u6B21\u4F18\u5316\u5728\u98DE\u3002 */\n busy: SnapshotStore<boolean>\n /** \u9762\u677F\u72B6\u6001\u63D0\u793A\uFF08\u7A7A\u4E32 = \u65E0\uFF09\u3002 */\n notice: SnapshotStore<string>\n }\n actions: {\n /** \u5173\u95ED\u9762\u677F\u3002 */\n close: () => void\n /** \u628A\u4E00\u6BB5\u6587\u672C\u63D2\u8FDB\u8F93\u5165\u6846\u3002 */\n insert: (text: string) => void\n /** \u7528\u5F53\u524D\u8F93\u5165\u6846\u5185\u5BB9\u8DD1\u4E00\u6B21\u4F18\u5316\uFF0C\u7ED3\u679C\u5199\u56DE\u8F93\u5165\u6846\u3002 */\n optimize: () => void\n /** \u5207\u6362\u4F18\u5316\u6863\u4F4D\u3002 */\n setTier: (tier: OptimizerTier) => void\n /** \u5207\u6362\u67D0\u6761\u5FEB\u6377\u6307\u4EE4\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u3002 */\n setAlways: (id: string, value: boolean) => void\n }\n}\n\nexport type QuickCommandsPanelProps =\n PropsRuntime<'shell.overlay'>\n & InjectFace<QuickPanelInjected>\n\n/** \u4E0E\u89C6\u53E3\u8FB9\u754C\u4FDD\u6301\u7684\u95F4\u8DDD\u3002 */\nconst MARGIN = 8\n/** \u9762\u677F\u4E0E\u951A\u70B9\u6309\u94AE\u4E4B\u95F4\u7684\u95F4\u8DDD\u3002 */\nconst GAP = 8\n\n/** \u5C55\u5F00\u9762\u677F\u3002 */\nexport function QuickCommandsPanel({\n useLive, usePanel, useBusy, useNotice, actions,\n}: QuickCommandsPanelProps) {\n const settings = useLive(item => item)\n const anchor = usePanel(item => item)\n const busy = useBusy(item => item)\n const notice = useNotice(item => item)\n const ref = useRef<HTMLDivElement | null>(null)\n const [position, setPosition] = useState<{ left: number; top: number } | null>(null)\n\n // \u8D34\u951A\u70B9\u6309\u94AE\u4E0A\u65B9\uFF1B\u653E\u4E0D\u4E0B\u5C31\u7FFB\u5230\u4E0B\u65B9\uFF1B\u5DE6\u53F3\u94B3\u5236\u5728\u89C6\u53E3\u5185\u3002\n useLayoutEffect(() => {\n if (anchor === null) {\n setPosition(null)\n return\n }\n const el = ref.current\n const height = el === null ? 320 : el.getBoundingClientRect().height\n const width = el === null ? 420 : el.getBoundingClientRect().width\n const left = Math.max(MARGIN, Math.min(anchor.left, window.innerWidth - width - MARGIN))\n const above = anchor.bottom - height - GAP\n const top = above >= MARGIN ? above : Math.min(anchor.bottom + GAP, window.innerHeight - height - MARGIN)\n setPosition({ left, top: Math.max(MARGIN, top) })\n }, [anchor?.left, anchor?.bottom, settings.quickPrompts.length, busy])\n\n // \u5916\u90E8\u70B9\u51FB / Escape / \u6EDA\u52A8 / \u7F29\u653E\u65F6\u5173\u95ED\uFF08\u4E0E\u53F3\u952E\u83DC\u5355\u540C\u4E00\u5957\u89C4\u5219\uFF09\u3002\n useEffect(() => {\n if (anchor === null) return\n const onPointerDown = (event: PointerEvent): void => {\n if (ref.current !== null && event.target instanceof Node && ref.current.contains(event.target)) return\n // \u70B9\u5165\u53E3\u6309\u94AE\u672C\u8EAB\u7531\u5B83\u81EA\u5DF1 toggle\uFF0C\u8FD9\u91CC\u8BA9\u8DEF\uFF0C\u514D\u5F97\u300C\u5173\u4E86\u53C8\u5F00\u300D\u3002\n if (event.target instanceof Element && event.target.closest('.composer-ux-quick-button') !== null) return\n actions.close()\n }\n const onEscape = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n event.preventDefault()\n event.stopPropagation()\n actions.close()\n }\n window.addEventListener('pointerdown', onPointerDown, true)\n window.addEventListener('keydown', onEscape, true)\n window.addEventListener('resize', actions.close)\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, true)\n window.removeEventListener('keydown', onEscape, true)\n window.removeEventListener('resize', actions.close)\n }\n }, [anchor === null, actions])\n\n if (anchor === null) return null\n\n const items = settings.quickPrompts\n const tier = settings.optimizerTier\n\n return (\n <div\n ref={ref}\n role=\"dialog\"\n aria-label=\"\u5FEB\u6377\u6307\u4EE4\"\n style={{ ...quickPanel, left: position?.left ?? anchor.left, top: position?.top ?? anchor.bottom }}\n >\n <div style={quickPanelHead}>\n <div style={quickPanelTitleRow}>\n <span style={quickPanelTitle}>\u5FEB\u6377\u6307\u4EE4</span>\n <div style={quickTierRow} role=\"group\" aria-label=\"\u4F18\u5316\u5F3A\u5EA6\">\n {OPTIMIZER_TIERS.map(item => (\n <button\n key={item.id}\n type=\"button\"\n title={item.hint}\n aria-pressed={tier === item.id}\n style={tier === item.id ? quickTierButtonActive : quickTierButton}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { actions.setTier(item.id) }}\n >\n {item.label}\n </button>\n ))}\n </div>\n </div>\n <button\n type=\"button\"\n disabled={busy}\n title=\"\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4EA4\u7ED9\u53E6\u4E00\u4E2A AI \u6574\u7406\u6210\u4E00\u6761\u53EF\u4EE5\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C\u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\"\n style={busy ? quickPrimaryButtonDisabled : quickPrimaryButton}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { actions.optimize() }}\n >\n <span aria-hidden>\u2728</span>\n <span>{busy ? '\u4F18\u5316\u4E2D\u2026' : '\u4F18\u5316\u63D0\u793A\u8BCD'}</span>\n </button>\n </div>\n\n <div style={quickList}>\n {items.length === 0 && (\n <div style={quickEmpty}>\n \u8FD8\u6CA1\u6709\u5FEB\u6377\u6307\u4EE4\u3002<br />\n \u5728\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C \u2192 \u5FEB\u6377\u6307\u4EE4\u300D\u91CC\u6DFB\u52A0\u3002\n </div>\n )}\n {items.map(item => (\n <div key={item.id} style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <button\n type=\"button\"\n title={item.prompt}\n style={quickItem}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { actions.insert(item.prompt) }}\n >\n <span style={quickItemLabel}>{item.label}</span>\n <span style={quickItemPreview}>{item.prompt.replace(/\\s+/g, ' ')}</span>\n </button>\n <label style={quickAlwaysLabel} title=\"\u52FE\u4E0A\u540E\uFF0C\u70B9\u53D1\u9001\u65F6\u8FD9\u6761\u63D0\u793A\u8BCD\u4F1A\u81EA\u52A8\u9644\u52A0\u5230\u4F60\u7684\u6D88\u606F\u672B\u5C3E\">\n <input\n type=\"checkbox\"\n style={quickAlwaysBox}\n checked={item.always}\n onChange={event => { actions.setAlways(item.id, event.target.checked) }}\n />\n \u9ED8\u8BA4\u63D2\u5165\n </label>\n </div>\n ))}\n </div>\n\n <div style={quickPanelFoot}>\n <span style={quickNotice} role=\"status\">{notice}</span>\n <span style={quickFootHint}>\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C</span>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["row", "text", "React", "import_react", "import_jsx_runtime", "import_react", "import_jsx_runtime", "
|
|
3
|
+
"sources": ["../src/client.tsx", "../src/settings-contract.ts", "../src/client/prompt-book.ts", "../src/client/chords.ts", "../src/client/quick-commands.ts", "../src/client/interceptors.ts", "../src/client/panel.ts", "../src/client/settings-style.ts", "../src/client/quick-style.ts", "../src/client/ContextMenuHost.tsx", "../src/client/styles.ts", "../src/client/PanelResizeHandles.tsx", "../src/client/SettingsSection.tsx", "../src/client/QuickCommandsButton.tsx", "../src/client/QuickCommandsPanel.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * Browser half\uFF1A\u6CE8\u518C\u8BBE\u7F6E\u9875\uFF08settings.section\uFF09\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\u62D6\u62FD\n * \u624B\u67C4\uFF08shell.overlay\uFF09\uFF0C\u5E76\u5B89\u88C5\u8F93\u5165\u6846\u62E6\u622A\u5668\uFF08\u952E\u4F4D + \u53F3\u952E\u83DC\u5355\uFF09\u4E0E\u9762\u677F\n * \u6EDA\u52A8\u6837\u5F0F\u3002\n */\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n DEFAULT_SETTINGS, ENABLED_FIELD, HEADER_ENABLED_FIELD, HEADER_NAME_FIELD,\n HEADER_ROUTES_FIELD, HEADER_VALUE_FIELD, MENU_FIELDS, MENU_NATIVE_FIELD, NAMESPACE,\n NEWLINE_KEY_FIELD, OPTIMIZER_TIER_FIELD, PANEL_SCROLL_FIELD, PANEL_RESIZE_FIELD,\n PANEL_WIDTH_FIELD, PANEL_HEIGHT_FIELD, QUICK_PROMPTS_FIELD, SEND_KEY_FIELD, sanitizeSettings,\n alwaysQuickPrompts, defaultQuickBook,\n type ComposerUxSettings, type MenuState, type OptimizerTier, type QuickPrompt,\n type QuickPromptBook, type SettingsField,\n} from './settings-contract.ts'\nimport {\n loadPromptBook, savePromptBook, withAlwaysToggled, withCategoryAdded, withCategoryMoved,\n withCategoryRemoved, withCategoryRenamed, withPromptAdded, withPromptMoved, withPromptPatched,\n withPromptRemoved,\n} from './client/prompt-book.ts'\nimport { installInterceptors, runMenuAction } from './client/interceptors.ts'\nimport { installPanelStyle } from './client/panel.ts'\nimport { installSettingsCardStyle } from './client/settings-style.ts'\nimport { installQuickButtonStyle } from './client/quick-style.ts'\nimport { ContextMenuHost } from './client/ContextMenuHost.tsx'\nimport { PanelResizeHandles } from './client/PanelResizeHandles.tsx'\nimport { SettingsSection } from './client/SettingsSection.tsx'\nimport { QuickCommandsButton, type QuickPanelAnchor } from './client/QuickCommandsButton.tsx'\nimport { QuickCommandsPanel } from './client/QuickCommandsPanel.tsx'\nimport {\n focusComposer, insertIntoDraft, optimizeDraft, replaceDraft, currentDraft,\n} from './client/quick-commands.ts'\n\nexport const name = 'composer-ux'\nexport const inject = ['slots', 'settingsScope']\n\n/** \u5BA2\u6237\u7AEF\u63D2\u4EF6\u5165\u53E3\u3002 */\nexport function apply(ctx: any): void {\n const slots = ctx.slots\n const scope = ctx.settingsScope.bind<ComposerUxSettings>({ namespace: NAMESPACE })\n\n const live = createSnapshotStore<ComposerUxSettings>({ ...DEFAULT_SETTINGS })\n const menu = createSnapshotStore<MenuState | null>(null)\n const panel = createSnapshotStore<QuickPanelAnchor | null>(null)\n const optimizing = createSnapshotStore<boolean>(false)\n const panelNotice = createSnapshotStore<string>('')\n\n const sync = (): void => {\n const snapshot = scope.getSnapshot()\n live.set(snapshot.status === 'ready' && snapshot.value !== undefined\n ? { ...DEFAULT_SETTINGS, ...sanitizeSettings(snapshot.value) }\n : { ...DEFAULT_SETTINGS })\n }\n sync()\n ctx.effect(() => scope.subscribe(sync), 'composer-ux: settings sync')\n\n const setField = (field: SettingsField, value: unknown): void => {\n void scope.set(field, value as never).catch((error: unknown) => {\n console.error('[composer-ux] settings write failed', error)\n })\n }\n const clearField = (field: SettingsField): void => {\n void scope.unset(field).catch((error: unknown) => {\n console.error('[composer-ux] settings clear failed', error)\n })\n }\n\n // \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\u5B58\u50A8\uFF08\u5206\u7C7B\u7ED3\u6784\uFF1B\u771F\u76F8\u5728 $DSH_HOME/quick-prompts.json\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n //\n // \u8BFB\uFF1Aapply \u65F6\u62C9\u4E00\u6B21\u3002\u5199\uFF1A\u5148\u4E50\u89C2\u66F4\u65B0\u672C\u5730\u5FEB\u7167\u8BA9\u754C\u9762\u7ACB\u523B\u54CD\u5E94\uFF0C\u518D\u628A\u6574\u672C POST \u4E0A\u53BB\uFF1B\n // \u5931\u8D25\u5C31\u4EE5\u78C1\u76D8\u4E3A\u51C6\u56DE\u6EDA\u2014\u2014\u4E0D\u8BA9\u300C\u754C\u9762\u663E\u793A\u7684\u300D\u548C\u300C\u6587\u4EF6\u91CC\u7684\u300D\u957F\u671F\u4E0D\u4E00\u81F4\u3002\n const book = createSnapshotStore<QuickPromptBook>(defaultQuickBook())\n /** '' = \u6B63\u5E38\uFF1B'saving' = \u6B63\u5728\u5199\uFF1B\u5176\u4F59 = \u4E0A\u4E00\u6B21\u7684\u9519\u8BEF\u6587\u6848\u3002 */\n const bookStatus = createSnapshotStore<string>('')\n\n const reloadBook = async (): Promise<void> => {\n const reply = await loadPromptBook()\n if (reply.ok && reply.book !== undefined) {\n book.set(reply.book)\n bookStatus.set('')\n return\n }\n bookStatus.set(reply.error ?? '\u8BFB\u53D6\u5FEB\u6377\u6307\u4EE4\u5931\u8D25')\n }\n\n const commitBook = (next: QuickPromptBook): void => {\n book.set(next)\n bookStatus.set('saving')\n void savePromptBook(next).then(\n (reply) => {\n if (reply.ok && reply.book !== undefined) {\n // \u7528\u5BBF\u4E3B\u56DE\u8BFB\u7684**\u78C1\u76D8\u771F\u5B9E\u5185\u5BB9**\u8986\u76D6\u672C\u5730\uFF1A\u4EFB\u4F55\u88AB\u6536\u7A84/\u4E22\u5F03\u7684\u5B57\u6BB5\u7ACB\u523B\u53EF\u89C1\u3002\n book.set(reply.book)\n bookStatus.set('')\n return\n }\n bookStatus.set(reply.error ?? '\u4FDD\u5B58\u5931\u8D25')\n void reloadBook()\n },\n (error: unknown) => {\n bookStatus.set(error instanceof Error ? error.message : String(error))\n void reloadBook()\n },\n )\n }\n\n void reloadBook()\n\n const bookActions = {\n reload: (): void => { void reloadBook() },\n addCategory: (name: string): void => { commitBook(withCategoryAdded(book.getSnapshot(), name)) },\n renameCategory: (id: string, name: string): void => {\n commitBook(withCategoryRenamed(book.getSnapshot(), id, name))\n },\n removeCategory: (id: string): void => { commitBook(withCategoryRemoved(book.getSnapshot(), id)) },\n moveCategory: (id: string, delta: number): void => {\n commitBook(withCategoryMoved(book.getSnapshot(), id, delta))\n },\n addPrompt: (categoryId: string): void => { commitBook(withPromptAdded(book.getSnapshot(), categoryId)) },\n patchPrompt: (categoryId: string, id: string, patch: { label?: string; prompt?: string }): void => {\n commitBook(withPromptPatched(book.getSnapshot(), categoryId, id, patch))\n },\n removePrompt: (categoryId: string, id: string): void => {\n commitBook(withPromptRemoved(book.getSnapshot(), categoryId, id))\n },\n movePrompt: (categoryId: string, id: string, delta: number): void => {\n commitBook(withPromptMoved(book.getSnapshot(), categoryId, id, delta))\n },\n resetBook: (): void => { commitBook(defaultQuickBook()) },\n /** \u8BBE\u7F6E\u9875\u300C\u4FDD\u5B58\u300D\uFF1A\u628A\u7F16\u8F91\u5668\u91CC\u7684\u6574\u672C\u4E00\u6B21\u5199\u56DE\uFF08\u800C\u4E0D\u662F\u6BCF\u6572\u4E00\u4E2A\u5B57\u5C31\u5199\u76D8\uFF09\u3002 */\n saveBook: (next: QuickPromptBook): void => { commitBook(next) },\n }\n\n const resetAll = (): void => {\n // \u6CE8\u610F\uFF1A\u5BBF\u4E3B\u534A\u7684\u8BB0\u8D26\u5B57\u6BB5\uFF08HOST_OWNED_FIELDS\uFF09\u6545\u610F\u4E0D\u5728\u540D\u5355\u91CC\u2014\u2014\u6E05\u6389\u5B83\u4EEC\u4F1A\u8BA9\n // \u5DF2\u7ECF\u5199\u5165 llm-pi-ai \u7684\u8BF7\u6C42\u5934\u5931\u53BB\u8BB0\u8D26\uFF0C\u4ECE\u800C\u6C38\u8FDC\u64A4\u9500\u4E0D\u6389\u3002\n // \u5FEB\u6377\u6307\u4EE4\u4E5F\u4E0D\u5728\u540D\u5355\u91CC\uFF1A\u5B83\u7684\u771F\u76F8\u5DF2\u7ECF\u642C\u5230 quick-prompts.json\uFF08\u89C1 bookActions.resetBook\uFF09\uFF0C\n // \u800C\u8BBE\u7F6E\u6587\u6863\u91CC\u90A3\u4EFD 0.2.x \u7684\u65E7\u503C\u662F**\u8FC1\u79FB\u7684\u79CD\u5B50**\uFF0C\u6545\u610F\u7559\u7740\u4E0D\u6E05\u2014\u2014\u4E07\u4E00\u56DE\u6EDA\u5230\u65E7\u7248\u8FD8\u80FD\u770B\u5230\u3002\n void scope.mutate(\n [\n ENABLED_FIELD, SEND_KEY_FIELD, NEWLINE_KEY_FIELD, ...MENU_FIELDS,\n MENU_NATIVE_FIELD,\n PANEL_SCROLL_FIELD, PANEL_RESIZE_FIELD, PANEL_WIDTH_FIELD, PANEL_HEIGHT_FIELD,\n HEADER_ENABLED_FIELD, HEADER_NAME_FIELD, HEADER_VALUE_FIELD, HEADER_ROUTES_FIELD,\n OPTIMIZER_TIER_FIELD,\n ].map(field => ({ op: 'unset', path: [field] })),\n ).catch((error: unknown) => {\n console.error('[composer-ux] settings reset failed', error)\n })\n bookActions.resetBook()\n }\n\n // \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\u4E0E\u63D0\u793A\u8BCD\u4F18\u5316 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \u9762\u677F\u5E95\u90E8\u7684\u77ED\u63D0\u793A\uFF1B\u5230\u65F6\u81EA\u52A8\u6D88\u5931\uFF08\u4E0E\u53F3\u952E\u83DC\u5355\u7684 note \u540C\u4E00\u5957\u8DEF\uFF09\u3002 */\n let noticeTimer: ReturnType<typeof setTimeout> | undefined\n const note = (message: string, ms = 4500): void => {\n panelNotice.set(message)\n if (noticeTimer !== undefined) clearTimeout(noticeTimer)\n if (message === '') return\n noticeTimer = setTimeout(() => { panelNotice.set('') }, ms)\n }\n ctx.effect(() => () => {\n if (noticeTimer !== undefined) clearTimeout(noticeTimer)\n }, 'composer-ux: quick notice timer')\n\n const quickActions = {\n toggle: (anchor: { left: number; bottom: number; width: number }): void => {\n if (panel.getSnapshot() !== null) {\n panel.set(null)\n panelNotice.set('')\n return\n }\n panelNotice.set('')\n panel.set(anchor)\n },\n close: (): void => {\n panel.set(null)\n panelNotice.set('')\n },\n insert: (text: string): void => {\n if (insertIntoDraft(text)) focusComposer()\n },\n optimize: (): void => {\n if (optimizing.getSnapshot()) return\n const draft = currentDraft()\n if (draft.trim() === '') {\n note('\u8F93\u5165\u6846\u662F\u7A7A\u7684\uFF1A\u5148\u5199\u70B9\u4EC0\u4E48\uFF0C\u518D\u70B9\u4F18\u5316')\n return\n }\n optimizing.set(true)\n note('\u6B63\u5728\u4F18\u5316\u2026')\n void optimizeDraft(draft, live.getSnapshot().optimizerTier).then(\n (result) => {\n optimizing.set(false)\n if (!result.ok) {\n note(`\u4F18\u5316\u5931\u8D25\uFF1A${result.error ?? '\u672A\u77E5\u539F\u56E0'}`)\n return\n }\n replaceDraft(result.text ?? '')\n focusComposer()\n note(`\u5DF2\u5199\u56DE\u8F93\u5165\u6846\uFF08${result.route}\uFF09\u00B7 Ctrl+Z \u53EF\u8FD8\u539F`)\n },\n (error: unknown) => {\n optimizing.set(false)\n note(`\u4F18\u5316\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`)\n },\n )\n },\n setTier: (tier: OptimizerTier): void => { setField(OPTIMIZER_TIER_FIELD, tier) },\n /**\n * \u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u52FE\u9009\uFF1A\u6309 id \u8DE8\u5206\u7C7B\u627E\u90A3\u4E00\u6761\uFF0C\u76F4\u63A5\u5199\u76D8\u3002\n * \u8FD9\u4E2A\u6807\u8BB0\u5C31\u662F\u300C\u70B9\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\u300D\u7684\u4F9D\u636E\uFF08\u89C1 interceptors.ts\uFF09\u3002\n */\n setAlways: (id: string, value: boolean): void => {\n commitBook(withAlwaysToggled(book.getSnapshot(), id, value))\n },\n }\n\n // \u8BBE\u7F6E\u9875\u6761\u76EE\u3002\n slots.inject('settings.section', () => slots.register({\n name: 'settings.section',\n id: 'composer-ux',\n order: 40,\n label: '\u8F93\u5165\u4F53\u9A8C',\n inject: () => ({\n hooks: { live, book, bookStatus },\n actions: {\n setField, clearField, resetAll,\n saveBook: bookActions.saveBook,\n reloadBook: bookActions.reload,\n resetBook: bookActions.resetBook,\n },\n }),\n }, SettingsSection))\n\n // \u53F3\u952E\u83DC\u5355\u6D6E\u5C42\uFF08shell.overlay \u662F root \u7EA7 list \u69FD\uFF1B\u5149\u6807\u5C42\u672C\u8EAB\u70B9\u51FB\u7A7F\u900F\uFF0C\u83DC\u5355\u81EA\u8425 pointer-events\uFF09\u3002\n slots.inject('shell.overlay', () => slots.register({\n name: 'shell.overlay',\n id: 'composer-ux-menu',\n inject: () => ({\n hooks: { menu, live },\n actions: {\n run: runMenuAction,\n close: () => { menu.set(null) },\n note: (message: string | undefined) => {\n const current = menu.getSnapshot()\n if (current === null) return\n menu.set({ ...current, note: message })\n },\n },\n }),\n }, ContextMenuHost))\n\n // \u8BBE\u7F6E\u9762\u677F\u8FB9\u7F18\u62D6\u62FD\u624B\u67C4\u3002\n slots.inject('shell.overlay', () => slots.register({\n name: 'shell.overlay',\n id: 'composer-ux-panel-resize',\n inject: () => ({ hooks: { live }, actions: { setField } }),\n }, PanelResizeHandles))\n\n // \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\uFF1A\u4E0E\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\u540C\u6392\uFF08order 89 < \u5C55\u5F00\u7684 90\uFF09\u3002\n slots.inject('conversation.input.right', () => slots.register({\n name: 'conversation.input.right',\n id: 'composer-ux-quick',\n order: 89,\n label: '\u5FEB\u6377\u6307\u4EE4',\n inject: () => ({\n hooks: { live, panel },\n actions: { toggle: quickActions.toggle },\n }),\n }, QuickCommandsButton))\n\n // \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5C55\u5F00\u9762\u677F\uFF1A\u8D70 root \u7EA7\u6D6E\u5C42\uFF0C\u4E0D\u53D7\u8F93\u5165\u5361\u7247\u88C1\u526A\u3002\n slots.inject('shell.overlay', () => slots.register({\n name: 'shell.overlay',\n id: 'composer-ux-quick-panel',\n inject: () => ({\n hooks: { live, panel, busy: optimizing, notice: panelNotice, book, bookStatus },\n actions: {\n toggle: quickActions.toggle,\n close: quickActions.close,\n insert: quickActions.insert,\n optimize: quickActions.optimize,\n setTier: quickActions.setTier,\n setAlways: quickActions.setAlways,\n toggleAlways: quickActions.setAlways,\n addCategory: bookActions.addCategory,\n renameCategory: bookActions.renameCategory,\n removeCategory: bookActions.removeCategory,\n moveCategory: bookActions.moveCategory,\n reloadBook: bookActions.reload,\n },\n }),\n }, QuickCommandsPanel))\n\n // \u8BBE\u7F6E\u9875\u6298\u53E0\u5361\u7247\u6837\u5F0F\uFF08\u5E38\u9A7B\uFF1B\u53EA\u7BA1\u8BBE\u7F6E\u9875\u5916\u89C2\uFF0C\u4E0E\u603B\u5F00\u5173\u65E0\u5173\uFF09\u3002\n ctx.effect(() => installSettingsCardStyle(), 'composer-ux: settings card style')\n\n // \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\u6837\u5F0F\u8868\uFF08\u4E0E\u65C1\u8FB9\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\u9010\u9879\u5BF9\u9F50\uFF09\u3002\n ctx.effect(() => installQuickButtonStyle(), 'composer-ux: quick button style')\n\n // \u8BBE\u7F6E\u9762\u677F\u5BFC\u822A\u6EDA\u52A8\u6837\u5F0F\uFF08\u968F panelScroll \u5F00\u5173\u5207\u6362\uFF1B\u603B\u5F00\u5173\u5173\u95ED\u65F6\u4E00\u5E76\u505C\u7528\uFF09\u3002\n ctx.effect(\n () => installPanelStyle(\n () => {\n const settings = live.getSnapshot()\n return settings.enabled && settings.panelScroll\n },\n listener => live.subscribe(listener),\n ),\n 'composer-ux: panel style',\n )\n\n // \u952E\u4F4D\u62E6\u622A + \u53F3\u952E\u83DC\u5355\u6253\u5F00\uFF08\u53D7\u603B\u5F00\u5173\u63A7\u5236\uFF1A\u5173\u95ED\u65F6\u5378\u8F7D\u76D1\u542C\u5E76\u5173\u95ED\u5DF2\u5F00\u83DC\u5355\uFF09\u3002\n ctx.effect(() => {\n let dispose: (() => void) | null = null\n const syncInterceptors = (): void => {\n const enabled = live.getSnapshot().enabled\n if (enabled && dispose === null) {\n dispose = installInterceptors({\n settings: () => live.getSnapshot(),\n alwaysPrompts: () => alwaysQuickPrompts(book.getSnapshot()),\n setMenu: state => { menu.set(state) },\n menuOpen: () => menu.getSnapshot() !== null,\n })\n } else if (!enabled) {\n dispose?.()\n dispose = null\n menu.set(null)\n panel.set(null)\n }\n // \u539F\u751F\u83DC\u5355\u6A21\u5F0F\u542F\u7528\u77AC\u95F4\uFF1A\u6E05\u6389\u53EF\u80FD\u8FD8\u5F00\u7740\u7684\u81EA\u5B9A\u4E49\u83DC\u5355\u3002\n if (live.getSnapshot().menuNative) menu.set(null)\n // \u603B\u5F00\u5173\u5173\u6389\u65F6\u6309\u94AE\u672C\u8EAB\u4E5F\u4F1A\u6D88\u5931\uFF08\u7EC4\u4EF6\u91CC\u6309 enabled \u8FD4\u56DE null\uFF09\uFF0C\n // \u6D6E\u5C42\u5FC5\u987B\u8DDF\u7740\u4E00\u8D77\u6536\uFF0C\u5426\u5219\u4F1A\u7559\u4E0B\u4E00\u4E2A\u6CA1\u6709\u951A\u70B9\u7684\u9762\u677F\u3002\n if (!live.getSnapshot().enabled) panel.set(null)\n }\n syncInterceptors()\n const unsubscribe = live.subscribe(syncInterceptors)\n return () => {\n unsubscribe()\n dispose?.()\n dispose = null\n }\n }, 'composer-ux: input interceptors')\n}\n", "/**\n * dsh-composer-ux \u516C\u5171\u5951\u7EA6\uFF1A\u8BBE\u7F6E\u5B57\u6BB5\u3001\u9ED8\u8BA4\u503C\u3001\u5C55\u793A\u5143\u6570\u636E\u3002\n * \u672C\u6A21\u5757\u5FC5\u987B\u96F6 import\uFF08host \u4E0E client \u4E24\u534A\u5171\u7528\uFF0C\u8DE8\u7AEF\u4E0D\u5171\u4EAB\u4EFB\u4F55\u8FD0\u884C\u65F6\u8EAB\u4EFD\uFF09\u3002\n */\n\n/** Host settings namespace\uFF08\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF09\u3002 */\nexport const NAMESPACE = 'composer-ux'\n\n/** \u5168\u5C40\u603B\u5F00\u5173\u5B57\u6BB5\u540D\u3002 */\nexport const ENABLED_FIELD = 'enabled'\n\n/** \u952E\u4F4D\u5B57\u6BB5\u540D\u3002 */\nexport const SEND_KEY_FIELD = 'sendKey'\nexport const NEWLINE_KEY_FIELD = 'newlineKey'\n\n/** \u8BBE\u7F6E\u9762\u677F\u5B57\u6BB5\u540D\u3002 */\nexport const PANEL_SCROLL_FIELD = 'panelScroll'\nexport const PANEL_RESIZE_FIELD = 'panelResize'\nexport const PANEL_WIDTH_FIELD = 'panelWidth'\nexport const PANEL_HEIGHT_FIELD = 'panelHeight'\n\n/** \u53F3\u952E\u83DC\u5355\u5F00\u5173\u5B57\u6BB5\u540D\u3002 */\nexport const MENU_FIELDS = [\n 'menuUndo',\n 'menuRedo',\n 'menuCut',\n 'menuCopy',\n 'menuPaste',\n 'menuDelete',\n 'menuSelectAll',\n] as const\n\nexport type MenuField = (typeof MENU_FIELDS)[number]\n\n/** \u53F3\u952E\u83DC\u5355\u6A21\u5F0F\u5B57\u6BB5\u540D\uFF1Atrue = \u6D4F\u89C8\u5668\u539F\u751F\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09\uFF0Cfalse = \u81EA\u5B9A\u4E49\u83DC\u5355\u3002 */\nexport const MENU_NATIVE_FIELD = 'menuNative'\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\u4E0E\u63D0\u793A\u8BCD\u4F18\u5316 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** \u5FEB\u6377\u6307\u4EE4\u5217\u8868\u5B57\u6BB5\u540D\u3002 */\nexport const QUICK_PROMPTS_FIELD = 'quickPrompts'\n\n/** \u4F18\u5316\u5F3A\u5EA6\u6863\u4F4D\u5B57\u6BB5\u540D\u3002 */\nexport const OPTIMIZER_TIER_FIELD = 'optimizerTier'\n\n/** \u5355\u4E2A\u5206\u7C7B\u5185\u7684\u6761\u6570\u4E0A\u9650\u3002 */\nexport const QUICK_PROMPT_MAX = 60\n\n/** \u5206\u7C7B\u6570\u4E0A\u9650\u3002 */\nexport const QUICK_CATEGORY_MAX = 20\n\n/** \u5206\u7C7B\u540D\u7684\u5B57\u7B26\u4E0A\u9650\u3002 */\nexport const QUICK_CATEGORY_NAME_MAX = 40\n\n/** \u5355\u6761\u300C\u540D\u79F0\u300D\u7684\u5B57\u7B26\u4E0A\u9650\u3002 */\nexport const QUICK_LABEL_MAX = 40\n\n/**\n * \u5355\u6761\u300C\u63D0\u793A\u8BCD\u300D\u7684\u5B57\u7B26\u4E0A\u9650\u3002\n *\n * 0.3.0 \u8D77\u5FEB\u6377\u6307\u4EE4\u6539\u5B58 `$DSH_HOME/quick-prompts.json`\uFF0C\u4E0D\u518D\u53D7\u8BBE\u7F6E\u6587\u6863\u7684\u4F53\u79EF\u7EA6\u675F\uFF0C\n * \u6240\u4EE5\u8FD9\u91CC\u4ECE 4000 \u63D0\u5230 20 \u4E07\u2014\u2014\u53EA\u505A\u300C\u522B\u628A\u51E0\u767E MB \u585E\u8FDB\u6765\u300D\u7684\u9632\u5446\uFF0C\u6B63\u5E38\u63D0\u793A\u8BCD\u4E0D\u518D\u88AB\u622A\u65AD\u3002\n */\nexport const QUICK_TEXT_MAX = 200_000\n\n/**\n * \u9001\u53BB\u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u7684\u539F\u6587\u4E0A\u9650\u3002\n *\n * \u4E0E\u539F `QUICK_TEXT_MAX * 2`\uFF08= 8000\uFF09\u7B49\u503C\uFF1A\u62AC\u9AD8\u7B49\u5FEB\u6377\u6307\u4EE4\u7684\u5B58\u50A8\u4E0A\u9650\u65F6**\u4E0D\u80FD**\n * \u987A\u5E26\u628A\u4F18\u5316\u8BF7\u6C42\u7684\u8F93\u5165\u4E0A\u9650\u4E5F\u62AC\u4E0A\u53BB\uFF0C\u5426\u5219\u8D85\u957F\u6587\u672C\u4F1A\u88AB\u4E22\u7ED9\u6A21\u578B\u3002\n */\nexport const OPTIMIZE_TEXT_MAX = 8_000\n\n/**\n * \u5FEB\u6377\u6307\u4EE4\u5B58\u50A8\u7684 HTTP \u8DEF\u5F84\uFF08\u5BBF\u4E3B\u534A\u6CE8\u518C\uFF0C\u5BA2\u6237\u7AEF\u534A\u8BFB\u5199\uFF09\u3002\n *\n * \u4E3A\u4EC0\u4E48\u5B58\u50A8\u4E5F\u5FC5\u987B\u8D70 HTTP\uFF1A\u6D4F\u89C8\u5668\u4FA7\u6CA1\u6709\u6587\u4EF6\u7CFB\u7EDF\uFF0C\u800C\u300C\u7528\u6237\u5185\u5BB9\u300D\u9700\u8981\u4E00\u4EFD\n * \u5168\u5C40\u3001\u4E0E\u4F1A\u8BDD/\u9879\u76EE\u65E0\u5173\u7684\u843D\u70B9\uFF0C\u53EA\u6709\u5BBF\u4E3B\u534A\u80FD\u63D0\u4F9B\u3002\n */\nexport const QUICK_PROMPTS_API_PATH = '/composer-ux/prompts'\n\n/** \u6587\u4EF6\u683C\u5F0F\u7248\u672C\uFF1B\u4E0E lnyuqian/dsh-quick-prompts \u7684 v2 \u5BF9\u9F50\uFF08\u89C1 bookToFile \u6CE8\u91CA\uFF09\u3002 */\nexport const QUICK_BOOK_VERSION = 2\n\n/** \u8FC1\u79FB/\u515C\u5E95\u5206\u7C7B\u540D\u3002 */\nexport const DEFAULT_CATEGORY_NAME = '\u9ED8\u8BA4'\n\n/** \u4F18\u5316\u7ED3\u679C\u957F\u5EA6\u4E0A\u9650\uFF08\u8D85\u8FC7\u89C6\u4E3A\u5F02\u5E38\u4EA7\u51FA\uFF0C\u622A\u65AD\u5E76\u63D0\u793A\uFF09\u3002 */\nexport const OPTIMIZE_OUTPUT_MAX = 12000\n\n/**\n * \u5BBF\u4E3B\u534A\u4E3A\u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u6CE8\u518C\u7684 HTTP \u63A5\u53E3\u8DEF\u5F84\u3002\n *\n * \u4E3A\u4EC0\u4E48\u5FC5\u987B\u8D70 HTTP\uFF1A\u51FA\u7F51\u8BF7\u6C42\u7531\u5BBF\u4E3B\u7684\u6A21\u578B\u9002\u914D\u5668\u53D1\u51FA\uFF08\u6D4F\u89C8\u5668\u4FA7\u78B0\u4E0D\u5230\u6A21\u578B\u8DEF\u7531\uFF09\uFF0C\n * \u800C\u5BBF\u4E3B\u534A <-> \u5BA2\u6237\u7AEF\u534A\u4E4B\u95F4\u6CA1\u6709\u522B\u7684\u53D7\u652F\u6301\u901A\u9053 \u2014\u2014 \u4E0E\n * WestFox-AwA/dsh-prompt-optimizer \u7684\u505A\u6CD5\u4E00\u81F4\u3002\n */\nexport const OPTIMIZER_API_PATH = '/composer-ux/optimize'\n\n/**\n * \u4E00\u6761\u5FEB\u6377\u6307\u4EE4\u3002\n *\n * `always` \u5C31\u662F\u754C\u9762\u4E0A\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF1A\u52FE\u4E0A\u4E4B\u540E\uFF0C\u70B9\u53D1\u9001\u65F6\u8FD9\u6761\u63D0\u793A\u8BCD\u4F1A\u88AB\n * \u81EA\u52A8\u62FC\u5230\u6D88\u606F**\u672B\u5C3E**\u4E00\u8D77\u53D1\u51FA\u53BB\uFF08\u8F93\u5165\u6846\u91CC\u4E0D\u63D0\u524D\u663E\u793A\uFF09\uFF0C\u89C1\n * `client/quick-commands.ts` \u7684 `appendAlwaysPrompts()`\u3002\n */\nexport interface QuickPrompt {\n /** \u7A33\u5B9A id\uFF1A\u7F16\u8F91\u540D\u79F0/\u5185\u5BB9\u65F6\u4E0D\u53D8\uFF0C\u7528\u4E8E\u52FE\u9009\u72B6\u6001\u4E0E\u5217\u8868 diff\u3002 */\n readonly id: string\n /** \u6309\u94AE\u4E0A\u663E\u793A\u7684\u540D\u79F0\u3002 */\n readonly label: string\n /** \u70B9\u51FB\u540E\u63D2\u5165\u8F93\u5165\u6846\u7684\u63D0\u793A\u8BCD\u6B63\u6587\u3002 */\n readonly prompt: string\n /** \u9ED8\u8BA4\u63D2\u5165\uFF1A\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\u3002 */\n readonly always: boolean\n}\n\n/**\n * \u4F18\u5316\u5F3A\u5EA6\u6863\u4F4D\u3002\n *\n * \u4E09\u6863\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\u63D0\u53D6\u81EA WestFox-AwA/dsh-prompt-optimizer\uFF08BSD-3-Clause\uFF0C\n * \u4F5C\u8005\u300C\u5543\u8F6E\u80CE\u7684\u897F\u72D0\u300D\uFF09\u7684 `lib/index.js`\uFF0C\u89C1 `optimizer-prompt.ts`\u3002\n */\nexport type OptimizerTier = 'basic' | 'advanced' | 'extreme'\n\n/** \u6863\u4F4D\u5143\u6570\u636E\uFF08\u987A\u5E8F\u5373\u754C\u9762\u987A\u5E8F\uFF09\u3002 */\nexport const OPTIMIZER_TIERS: readonly {\n readonly id: OptimizerTier\n readonly label: string\n readonly hint: string\n}[] = [\n { id: 'basic', label: '\u666E\u901A', hint: '\u53EA\u505A\u8BED\u8A00\u5C42\u4FEE\u590D\uFF1A\u75C5\u53E5\u3001\u9519\u522B\u5B57\u3001\u6307\u4EE3\u4E0E\u542B\u7CCA\u8BCD\uFF0C\u4E0D\u65B0\u589E\u4EFB\u4F55\u9700\u6C42\uFF0C\u7BC7\u5E45\u4E0E\u539F\u6587\u76F8\u5F53\u3002' },\n { id: 'advanced', label: '\u9AD8\u7EA7', hint: '\u5728\u4E0D\u52A8\u76EE\u6807\u7684\u524D\u63D0\u4E0B\uFF0C\u628A\u300C\u4F60\u663E\u7136\u60F3\u8981\u3001\u4F46\u6CA1\u8BF4\u51FA\u53E3\u300D\u7684\u5FC5\u8981\u8981\u6C42\u8865\u6210\u5BF9 AI \u7684\u8981\u6C42\uFF0C\u8BA9\u5B83\u4E00\u6B21\u505A\u5BF9\u3002' },\n { id: 'extreme', label: '\u6781\u7AEF', hint: '\u6309\u590D\u6742\u4EFB\u52A1\u5904\u7406\uFF1A\u56FA\u5316\u547D\u4EE4\u7ED3\u6784 + \u5206\u9636\u6BB5\u6267\u884C\u8BA1\u5212 + 2~4 \u79CD\u60C5\u51B5\u7684\u9884\u6848\u3002' },\n]\n\n/** \u9ED8\u8BA4\u6863\u4F4D\u3002 */\nexport const DEFAULT_OPTIMIZER_TIER: OptimizerTier = 'advanced'\n\n/**\n * \u5185\u7F6E\u7684 9 \u6761\u5FEB\u6377\u6307\u4EE4 = \u7528\u6237\u53E3\u8FF0\u7684 4 \u6761 + \u63D0\u53D6\u81EA congyaqwq/dsh-quick-prompts \u7684 5 \u6761\u3002\n *\n * \u8BF4\u660E\uFF08\u5982\u5B9E\u8BB0\u5F55\u8C03\u7814\u7ED3\u679C\uFF09\uFF1A\u53E6\u5916\u4E24\u4E2A\u540C\u540D\u63D2\u4EF6 lcsdg / lnyuqian \u7684\n * dsh-quick-prompts **\u4E0D\u5E26\u5185\u7F6E\u6307\u4EE4**\uFF08\u5217\u8868\u9ED8\u8BA4\u662F\u7A7A\u7684\uFF0C\u9760\u7528\u6237\u81EA\u5EFA\uFF09\uFF0C\n * \u6240\u4EE5\u4ECE\u5B83\u4EEC\u90A3\u91CC\u6CA1\u6709\u53EF\u63D0\u53D6\u7684\u6761\u76EE\u3002\n */\nexport const DEFAULT_QUICK_PROMPTS: readonly QuickPrompt[] = [\n { id: 'builtin-1', label: '\u4E00\u95EE\u4E00\u7B54', prompt: '\u4F60\u4E0D\u61C2\u7684\u5C31\u95EE\u6211\uFF0C\u4E00\u95EE\u4E00\u7B54\uFF1B\u540C\u65F6\u8BF4\u6E05\u695A\u4F60\u4E3A\u4EC0\u4E48\u8981\u95EE\u8BE5\u95EE\u9898\uFF1B\u76F4\u5230\u4F60\u5BF9\u6211\u7684\u76EE\u6807\u6709\u660E\u786E\u8BA4\u77E5\u540E\u518D\u5F00\u59CB\u5E72\u6D3B\u3002', always: false },\n { id: 'builtin-2', label: '\u4EA4\u63A5\u6587\u6863', prompt: '\u628A\u8FD9\u6B21\u4EFB\u52A1\u3001\u5DF2\u5B8C\u6210\u5185\u5BB9\u3001\u5F53\u524D\u5361\u70B9\u3001\u4E0B\u4E00\u6B65\u8BA1\u5212\u3001\u8E29\u8FC7\u7684\u5751\uFF0C\u6574\u7406\u6210\u4E00\u4EFD\u4EA4\u63A5\u6587\u6863\uFF0C\u5199\u7ED9\u65B0\u4F1A\u8BDD\u770B\u3002', always: false },\n { id: 'builtin-3', label: '\u4EC5\u8BF4\u660E\u539F\u56E0', prompt: '\u4EC5\u8BF4\u660E\u539F\u56E0\uFF0C\u4E0D\u8981\u505A\u5176\u4ED6\u52A8\u4F5C\u3002', always: false },\n { id: 'builtin-4', label: '\u5206\u6790\u540E\u76F4\u63A5\u5E72', prompt: '\u5206\u6790\u539F\u56E0\uFF0C\u7136\u540E\u76F4\u63A5\u5F00\u59CB\u5E72\u6D3B\uFF0C\u4E0D\u9700\u8981\u8FC7\u95EE\u6211\u3002', always: false },\n { id: 'builtin-5', label: '\u63D0\u4EA4\u4EE3\u7801', prompt: '\u8BF7\u5E2E\u6211\u63D0\u4EA4\u4EE3\u7801\uFF1A\u68C0\u67E5\u5F53\u524D git \u53D8\u66F4\uFF0C\u751F\u6210\u89C4\u8303\u7684 commit message \u5E76\u6267\u884C\u63D0\u4EA4\u3002', always: false },\n { id: 'builtin-6', label: '\u7ED9\u65B9\u6848', prompt: '\u8BF7\u9488\u5BF9\u4E0A\u9762\u7684\u95EE\u9898\u7ED9\u51FA\u4E00\u4E2A\u5B8C\u6574\u65B9\u6848\uFF0C\u5305\u62EC\u601D\u8DEF\u3001\u6B65\u9AA4\u3001\u6CE8\u610F\u4E8B\u9879\u548C\u98CE\u9669\u3002', always: false },\n { id: 'builtin-7', label: '\u89E3\u91CA\u4EE3\u7801', prompt: '\u8BF7\u89E3\u91CA\u8FD9\u6BB5\u4EE3\u7801\u7684\u4F5C\u7528\u548C\u5B9E\u73B0\u601D\u8DEF\u3002', always: false },\n { id: 'builtin-8', label: '\u5199\u6D4B\u8BD5', prompt: '\u8BF7\u4E3A\u4E0B\u9762\u7684\u4EE3\u7801\u7F16\u5199\u5355\u5143\u6D4B\u8BD5\u3002', always: false },\n { id: 'builtin-9', label: '\u4EE3\u7801\u5BA1\u67E5', prompt: '\u8BF7\u5BF9\u4E0B\u9762\u7684\u4EE3\u7801\u8FDB\u884C\u4EE3\u7801\u5BA1\u67E5\uFF0C\u6307\u51FA\u95EE\u9898\u5E76\u7ED9\u51FA\u6539\u8FDB\u5EFA\u8BAE\u3002', always: false },\n]\n\n/** \u751F\u6210\u4E00\u6761\u65B0\u5FEB\u6377\u6307\u4EE4\u7684 id\uFF08\u65F6\u95F4\u6233 + \u968F\u673A\u540E\u7F00\uFF0C\u907F\u514D\u4E0E\u65E2\u6709 id \u78B0\u649E\uFF09\u3002 */\nexport function newQuickPromptId(): string {\n return `qp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`\n}\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\uFF1A\u5206\u7C7B\u7ED3\u6784\u4E0E\u6587\u4EF6\u6620\u5C04 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// 0.3.0 \u8D77\u5FEB\u6377\u6307\u4EE4\u4E0D\u518D\u5B58\u5728\u8BBE\u7F6E\u6587\u6863\u91CC\uFF0C\u800C\u662F\u5B58\u5728 `$DSH_HOME/quick-prompts.json`\u3002\n// \u539F\u56E0\u662F\u8BBE\u7F6E\u6587\u6863\u5BF9**\u6570\u7EC4**\u662F\u300C\u6574\u4EFD\u66FF\u6362\u300D\u3001\u4E14\u53D7 schema \u957F\u5EA6\u4E0A\u9650\u7EA6\u675F\uFF08\u65E7 4000 \u5B57\u4F1A\u9759\u9ED8\n// \u622A\u65AD\uFF09\uFF0C\u800C\u5FEB\u6377\u6307\u4EE4\u662F\u7528\u6237\u5185\u5BB9\u3001\u4F1A\u5199\u5F88\u957F\u7684\u63D0\u793A\u8BCD\u3002\u4E13\u7528\u6587\u4EF6\u8FD8\u4FBF\u4E8E\u5355\u72EC\u5907\u4EFD\u4E0E\u8FC1\u79FB\u3002\n//\n// \u6587\u4EF6\u5B57\u6BB5\u540D\u4E0E lnyuqian/dsh-quick-prompts \u5BF9\u9F50\uFF08categories / name / title / text /\n// autoSend / order\uFF09\uFF0C\u8FD9\u6837\u540C\u4E00\u4E2A\u6587\u4EF6\u4E24\u8FB9\u90FD\u8BFB\u5F97\u61C2\uFF1A\u5185\u90E8\u7528 label/prompt/always\uFF0C\n// \u53EA\u5728\u6587\u4EF6\u8FB9\u754C\u6620\u5C04\uFF08\u89C1 bookToFile / asPromptRow\uFF09\u3002\n// \u26A0\uFE0F \u4F46**\u4E0D\u8981\u540C\u65F6\u88C5\u4E24\u4E2A\u63D2\u4EF6**\u2014\u2014\u540C\u4E00\u4E2A\u6587\u4EF6\u4E24\u4E2A\u5199\u8005\u4F1A\u4E92\u76F8\u8986\u76D6\uFF0C\u800C\u5B83\u90A3\u8FB9\u662F\u975E\u539F\u5B50\u5199\u3002\n\n/** \u751F\u6210\u4E00\u4E2A\u65B0\u5206\u7C7B id\u3002 */\nexport function newQuickCategoryId(): string {\n return `qc-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`\n}\n\n/** \u4E00\u4E2A\u5206\u7C7B\uFF1A\u540D\u5B57 + \u5B83\u81EA\u5DF1\u7684\u6761\u76EE\u5217\u8868\uFF08\u987A\u5E8F\u5373\u663E\u793A\u987A\u5E8F\uFF09\u3002 */\nexport interface QuickPromptCategory {\n readonly id: string\n readonly name: string\n readonly prompts: readonly QuickPrompt[]\n}\n\n/** \u5168\u5C40\u5FEB\u6377\u6307\u4EE4\u672C\uFF1A\u5206\u7C7B\u4E24\u7EA7\u7ED3\u6784\uFF0C\u843D\u76D8\u6210\u4E00\u4EFD JSON \u6587\u4EF6\u3002 */\nexport interface QuickPromptBook {\n readonly version: number\n readonly categories: readonly QuickPromptCategory[]\n}\n\n/** \u5185\u7F6E\u9ED8\u8BA4\u672C\uFF1A\u4E00\u4E2A\u300C\u9ED8\u8BA4\u300D\u5206\u7C7B\u88C5\u90A3 9 \u6761\u3002 */\nexport function defaultQuickBook(): QuickPromptBook {\n return {\n version: QUICK_BOOK_VERSION,\n categories: [{ id: 'cat-default', name: DEFAULT_CATEGORY_NAME, prompts: DEFAULT_QUICK_PROMPTS }],\n }\n}\n\n/** \u6587\u4EF6\u91CC\u7684\u5206\u7C7B\u5F62\u72B6\uFF08\u5199\u76D8\u7528\uFF1B\u4E0E\u53C2\u8003\u5B9E\u73B0\u540C\u540D\u5B57\u6BB5\uFF09\u3002 */\nexport interface QuickCategoryFileRow {\n readonly id: string\n readonly name: string\n readonly prompts: readonly {\n readonly id: string\n readonly title: string\n readonly text: string\n readonly autoSend: boolean\n readonly order: number\n }[]\n}\n\n/** \u6536\u7A84\u4E00\u6761\uFF1A\u5185\u90E8\u5B57\u6BB5\u540D\uFF08label/prompt/always\uFF09\u4E0E\u6587\u4EF6\u5B57\u6BB5\u540D\uFF08title/text/autoSend\uFF09\u90FD\u8BA4\u3002 */\nfunction asPromptRow(value: unknown): { readonly prompt: QuickPrompt; readonly order?: number } | undefined {\n if (typeof value !== 'object' || value === null) return undefined\n const row = value as Record<string, unknown>\n const either = (first: unknown, second: unknown): string => {\n const picked = typeof first === 'string' && first !== '' ? first : second\n return typeof picked === 'string' ? picked : ''\n }\n const prompt = either(row.prompt, row.text).slice(0, QUICK_TEXT_MAX).trim()\n if (prompt === '') return undefined\n const label = either(row.label, row.title).slice(0, QUICK_LABEL_MAX).trim()\n const id = typeof row.id === 'string' && row.id !== '' ? row.id.slice(0, 64) : newQuickPromptId()\n const order = typeof row.order === 'number' && Number.isFinite(row.order)\n ? Math.max(1, Math.round(row.order))\n : undefined\n return {\n prompt: { id, label: label === '' ? prompt.slice(0, 12) : label, prompt, always: row.always === true || row.autoSend === true },\n order,\n }\n}\n\n/** \u6536\u7A84\u4E00\u4E2A\u5217\u8868\uFF1A\u6309 id \u53BB\u91CD\u4FDD\u5E8F\u3001\u6309 order \u5347\u5E8F\uFF08\u6CA1\u6709 order \u7684\u4FDD\u6301\u539F\u76F8\u5BF9\u4F4D\u7F6E\uFF09\u3001\u9650\u91CF\u3002 */\nfunction toPromptList(values: readonly unknown[]): readonly QuickPrompt[] {\n const rows: { prompt: QuickPrompt; order?: number; index: number }[] = []\n for (const value of values) {\n const row = asPromptRow(value)\n if (row !== undefined) rows.push({ ...row, index: rows.length })\n }\n rows.sort((a, b) => {\n const left = a.order ?? Number.MAX_SAFE_INTEGER\n const right = b.order ?? Number.MAX_SAFE_INTEGER\n return left === right ? a.index - b.index : left - right\n })\n const seen = new Set<string>()\n const out: QuickPrompt[] = []\n for (const row of rows) {\n if (out.length >= QUICK_PROMPT_MAX) break\n if (seen.has(row.prompt.id)) continue\n seen.add(row.prompt.id)\n out.push(row.prompt)\n }\n return out\n}\n\n/**\n * \u628A\u4EFB\u610F\u6765\u6E90\u6536\u7A84\u6210\u4E00\u672C\uFF08\u6587\u4EF6\u5185\u5BB9\u3001HTTP \u8BF7\u6C42\u4F53\u90FD\u8D70\u8FD9\u91CC\uFF09\u3002\n * @param value \u4EFB\u610F\u503C\u3002\n * @returns \u6536\u7A84\u540E\u7684\u672C\uFF1B**\u8BA4\u4E0D\u51FA\u7684\u5F62\u72B6\u8FD4\u56DE undefined** \u2014\u2014 \u8C03\u7528\u65B9\u5FC5\u987B\u628A\u5B83\u5F53\u6210\u635F\u574F\uFF0C\n * \u7EDD\u4E0D\u80FD\u56DE\u9000\u6210\u7A7A\u672C\u518D\u5199\u56DE\u53BB\uFF08\u90A3\u4F1A\u628A\u7528\u6237\u6570\u636E\u62B9\u6389\uFF09\u3002\n */\nexport function sanitizeBook(value: unknown): QuickPromptBook | undefined {\n if (typeof value !== 'object' || value === null) return undefined\n const source = value as Record<string, unknown>\n\n // v1 \u5E73\u94FA\uFF08\u88F8\u6570\u7EC4\uFF0C\u6216 { prompts: [...] }\uFF09\uFF1A\u5347\u7EA7\u6210\u4E00\u4E2A\u300C\u9ED8\u8BA4\u300D\u5206\u7C7B\u3002\n const flat = Array.isArray(value) ? value : (Array.isArray(source.prompts) ? source.prompts : undefined)\n if (flat !== undefined) {\n const prompts = toPromptList(flat)\n return {\n version: QUICK_BOOK_VERSION,\n categories: prompts.length === 0\n ? []\n : [{ id: 'cat-default', name: DEFAULT_CATEGORY_NAME, prompts }],\n }\n }\n\n if (!Array.isArray(source.categories)) return undefined\n const seen = new Set<string>()\n const categories: QuickPromptCategory[] = []\n for (const raw of source.categories) {\n if (categories.length >= QUICK_CATEGORY_MAX) break\n if (typeof raw !== 'object' || raw === null) continue\n const row = raw as Record<string, unknown>\n const prompts = toPromptList(Array.isArray(row.prompts) ? row.prompts : [])\n // \u7A7A\u5206\u7C7B**\u4FDD\u7559**\uFF08\u8FD9\u70B9\u4E0E\u53C2\u8003\u5B9E\u73B0\u4E0D\u540C\uFF09\uFF1A\u9762\u677F\u7684\u300C\uFF0B\u300D\u53EA\u662F\u65B0\u5EFA\u4E00\u4E2A\u5206\u7C7B\uFF0C\u7528\u6237\u63A5\u4E0B\u6765\n // \u624D\u4F1A\u5F80\u91CC\u653E\u6761\u76EE\uFF1B\u82E5\u5728\u8FD9\u91CC\u4E22\u6389\uFF0C\u70B9\u300C\uFF0B\u300D\u5C31\u4F1A\u770B\u8D77\u6765\u6BEB\u65E0\u53CD\u5E94\uFF080.3.0 \u771F\u673A\u4E0A\u8E29\u5230\uFF09\u3002\n // \u7A7A\u5206\u7C7B\u5728\u6587\u4EF6\u91CC\u4E5F\u662F\u5408\u6CD5\u72B6\u6001\uFF0C\u6570\u91CF\u4E0A\u9650\u7531 QUICK_CATEGORY_MAX \u515C\u4F4F\u3002\n const wanted = typeof row.id === 'string' && row.id !== '' ? row.id.slice(0, 64) : newQuickCategoryId()\n const id = seen.has(wanted) ? newQuickCategoryId() : wanted\n seen.add(id)\n const name = (typeof row.name === 'string' ? row.name : '').slice(0, QUICK_CATEGORY_NAME_MAX).trim()\n categories.push({ id, name: name === '' ? DEFAULT_CATEGORY_NAME : name, prompts })\n }\n return { version: QUICK_BOOK_VERSION, categories }\n}\n\n/** \u5185\u90E8\u7ED3\u6784 \u2192 \u6587\u4EF6\u7ED3\u6784\uFF08\u5199\u76D8\u65F6\u7528\uFF1B\u987A\u5E8F\u5373 order\uFF09\u3002 */\nexport function bookToFile(book: QuickPromptBook): { version: number; categories: readonly QuickCategoryFileRow[] } {\n return {\n version: QUICK_BOOK_VERSION,\n categories: book.categories.map(category => ({\n id: category.id,\n name: category.name,\n prompts: category.prompts.map((prompt, index) => ({\n id: prompt.id,\n title: prompt.label,\n text: prompt.prompt,\n autoSend: prompt.always,\n order: index + 1,\n })),\n })),\n }\n}\n\n/** \u8DE8\u5206\u7C7B\u62CD\u5E73\uFF08\u9762\u677F\u5217\u8868\u3001\u603B\u6761\u6570\u7EDF\u8BA1\u7528\uFF09\u3002 */\nexport function flattenQuickPrompts(book: QuickPromptBook): readonly QuickPrompt[] {\n return book.categories.flatMap(category => category.prompts)\n}\n\n/** \u53EA\u53D6\u52FE\u4E86\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u90A3\u4E9B\uFF08\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\uFF1B\u8DE8\u6240\u6709\u5206\u7C7B\uFF09\u3002 */\nexport function alwaysQuickPrompts(book: QuickPromptBook): readonly QuickPrompt[] {\n return flattenQuickPrompts(book).filter(prompt => prompt.always)\n}\n\n// \u2500\u2500 OpenCode \u8BF7\u6C42\u5934 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// OpenCode \u7684\u63A5\u53E3\u8981\u6C42\u5BA2\u6237\u7AEF\u6BCF\u6B21\u8BF7\u6C42\u90FD\u5E26\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID \u8BF7\u6C42\u5934\n// \uFF08\u5B98\u65B9 Go \u6587\u6863\u300C\u53EF\u4EE5\u5728\u54EA\u91CC\u4F7F\u7528\uFF1F\u300D\u7B2C 3 \u6761\uFF09\u3002DSH \u7684 Models \u8BBE\u7F6E\u9875\u660E\u786E\u4E0D\u63D0\u4F9B\n// \u8BF7\u6C42\u5934\u7F16\u8F91\u5668\uFF0C\u6240\u4EE5\u672C\u63D2\u4EF6\u628A\u8FD9\u4E00\u9879\u5199\u8FDB llm-pi-ai \u7684 provider profile.headers \u2014\u2014\n// \u90A3\u662F DSH \u91CC\u552F\u4E00\u53D7\u652F\u6301\u7684\u51FA\u7F51\u8BF7\u6C42\u5934\u5165\u53E3\uFF08\u4F1A\u5728 pi-ai \u4FA7\u6700\u540E\u5408\u5E76\uFF0C\u4E0B\u4E00\u6B21\u8BF7\u6C42\u751F\u6548\uFF09\u3002\n\n/** \u8BF7\u6C42\u5934\u680F\u76EE\u5B57\u6BB5\u540D\u3002 */\nexport const HEADER_ENABLED_FIELD = 'headerEnabled'\nexport const HEADER_NAME_FIELD = 'headerName'\nexport const HEADER_VALUE_FIELD = 'headerValue'\n/** \u4F5C\u7528\u8DEF\u7531\u540D\u5355\uFF08\u9017\u53F7/\u7A7A\u683C\u5206\u9694\uFF09\uFF1B\u7559\u7A7A = \u81EA\u52A8\u5339\u914D OpenCode \u8DEF\u7531\uFF08\u89C1 OPENCODE_ROUTE_PREFIX / OPENCODE_HOSTS\uFF09\u3002 */\nexport const HEADER_ROUTES_FIELD = 'headerRoutes'\n\n/** \u5BBF\u4E3B\u534A\u8BB0\u8D26\uFF1A\u4E0A\u6B21\u5B9E\u9645\u5199\u5165\u7684\u5934\u540D\u4E0E\u503C\uFF08\u51B3\u5B9A\u505C\u7528/\u6539\u540D\u65F6\u64A4\u9500\u54EA\u4E9B\u952E\uFF09\u3002 */\nexport const HEADER_APPLIED_NAME_FIELD = 'headerAppliedName'\nexport const HEADER_APPLIED_VALUE_FIELD = 'headerAppliedValue'\n\n/** \u5BBF\u4E3B\u534A\u5199\u5165\u7684\u6267\u884C\u7ED3\u679C\uFF1B\u8BBE\u7F6E\u9875\u53EA\u8BFB\u5C55\u793A\u3002 */\nexport const HEADER_STATUS_FIELD = 'headerStatus'\n\n/**\n * \u53EA\u5728\u5BBF\u4E3B\u534A\u7EF4\u62A4\u7684\u5B57\u6BB5\uFF1A\u8BBE\u7F6E\u9875\u300C\u6062\u590D\u9ED8\u8BA4\u300D\u4E0D\u5F97\u6E05\u7A7A\u5B83\u4EEC\uFF0C\n * \u5426\u5219\u5DF2\u5199\u5165\u7684\u5934\u4F1A\u5931\u53BB\u8BB0\u8D26\u3001\u6C38\u8FDC\u64A4\u9500\u4E0D\u6389\u3002\n */\nexport const HOST_OWNED_FIELDS = [\n HEADER_APPLIED_NAME_FIELD,\n HEADER_APPLIED_VALUE_FIELD,\n HEADER_STATUS_FIELD,\n] as const\n\n/** \u8BF7\u6C42\u5934\u6700\u7EC8\u843D\u5730\u7684\u8BBE\u7F6E\u547D\u540D\u7A7A\u95F4\uFF08\u7531 llm-pi-ai \u6CE8\u518C\uFF09\u3002 */\nexport const LLM_NAMESPACE = 'llm-pi-ai'\n\n/**\n * \u81EA\u52A8\u5339\u914D\u7684\u4E24\u6761\u5224\u636E\uFF08\u6EE1\u8DB3\u5176\u4E00\u5373\u7B97 OpenCode \u8DEF\u7531\uFF09\uFF1A\n * 1. \u8DEF\u7531\u540D\u4EE5 `opencode` \u5F00\u5934\u2014\u2014DSH \u5185\u7F6E\u7684 `opencode-go` \u5C31\u5C5E\u4E8E\u8FD9\u79CD\uFF0C\n * \u5B83\u7684 baseURL \u7531 pi-ai \u76EE\u5F55\u5185\u7F6E\uFF0C\u914D\u7F6E\u91CC\u8BFB\u4E0D\u5230\uFF0C\u53EA\u80FD\u9760\u540D\u5B57\u3002\n * 2. \u8BE5\u8DEF\u7531\u7684 `baseURL` \u4E3B\u673A\u662F opencode.ai\uFF08\u542B\u5B50\u57DF\uFF09\u2014\u2014\u7528\u6237\u81EA\u5EFA\u8DEF\u7531\u5E38\u8D77\u4EFB\u610F\u540D\u5B57\n * \uFF08\u4F8B\u5982 `go`\uFF09\uFF0C\u4F46\u7AEF\u70B9\u7167\u6837\u662F OpenCode\uFF0C\u6309 URL \u8BA4\u6BD4\u6309\u540D\u5B57\u8BA4\u53EF\u9760\u3002\n */\nexport const OPENCODE_ROUTE_PREFIX = 'opencode'\n\n/** \u5224\u636E 2 \u7528\u7684\u4E3B\u673A\u540D\uFF08\u542B\u5B50\u57DF\uFF09\u3002 */\nexport const OPENCODE_HOSTS = ['opencode.ai'] as const\n\n/** \u5934\u540D\u9ED8\u8BA4\u503C = OpenCode \u5B98\u65B9\u8981\u6C42\u7684\u90A3\u4E00\u4E2A\u3002 */\nexport const DEFAULT_HEADER_NAME = 'x-opencode-session'\n\n/** \u5934\u503C\u957F\u5EA6\u4E0A\u9650\uFF08HTTP \u5934\u4E0E\u8BBE\u7F6E\u6587\u6863\u90FD\u4E0D\u5B9C\u8FC7\u957F\uFF09\u3002 */\nexport const HEADER_VALUE_MAX = 200\n\n/** \u5934\u540D\u957F\u5EA6\u4E0A\u9650\u3002 */\nexport const HEADER_NAME_MAX = 64\n\n/** \u5168\u90E8\u53EF\u6301\u4E45\u5316\u5B57\u6BB5\u3002 */\nexport type SettingsField =\n | typeof ENABLED_FIELD\n | typeof SEND_KEY_FIELD\n | typeof NEWLINE_KEY_FIELD\n | typeof PANEL_SCROLL_FIELD\n | typeof PANEL_RESIZE_FIELD\n | typeof PANEL_WIDTH_FIELD\n | typeof PANEL_HEIGHT_FIELD\n | typeof MENU_NATIVE_FIELD\n | typeof HEADER_ENABLED_FIELD\n | typeof HEADER_NAME_FIELD\n | typeof HEADER_VALUE_FIELD\n | typeof HEADER_ROUTES_FIELD\n | typeof QUICK_PROMPTS_FIELD\n | typeof OPTIMIZER_TIER_FIELD\n | MenuField\n\n/** \u9F20\u6807\u53F3\u952E\u83DC\u5355\u6253\u5F00\u65F6\u7684\u4E00\u6B21\u5FEB\u7167\uFF08\u542B\u4F4D\u7F6E\u4E0E\u9009\u62E9\u72B6\u6001\uFF09\u3002 */\nexport interface MenuState {\n /** \u89C6\u53E3\u5750\u6807\u3002 */\n readonly x: number\n readonly y: number\n /** \u53F3\u952E\u65F6\u8F93\u5165\u6846\u5185\u662F\u5426\u6709\u975E\u6298\u53E0\u9009\u533A\uFF08\u51B3\u5B9A\u526A\u5207/\u590D\u5236/\u5220\u9664\u662F\u5426\u53EF\u7528\uFF09\u3002 */\n readonly hasSelection: boolean\n /** \u7C98\u8D34\u5931\u8D25\u65F6\u7684\u77ED\u6682\u63D0\u793A\u3002 */\n readonly note?: string\n}\n\n/** \u89E3\u6790\u540E\u7684\u8BBE\u7F6E\u3002 */\nexport interface ComposerUxSettings {\n /** \u5168\u5C40\u603B\u5F00\u5173\uFF1Afalse \u65F6\u672C\u63D2\u4EF6\u6240\u6709\u529F\u80FD\u505C\u7528\u3002 */\n enabled: boolean\n /** \u53D1\u9001\u952E\u4F4D\u89C4\u8303\u4E32\uFF08\u5982 'Enter'\u3001'Ctrl+Enter'\u3001''=\u65E0\uFF09\u3002 */\n sendKey: string\n /** \u6362\u884C\u952E\u4F4D\u89C4\u8303\u4E32\u3002 */\n newlineKey: string\n menuUndo: boolean\n menuRedo: boolean\n menuCut: boolean\n menuCopy: boolean\n menuPaste: boolean\n menuDelete: boolean\n menuSelectAll: boolean\n /** true = \u6D4F\u89C8\u5668\u539F\u751F\u53F3\u952E\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09\uFF1Bfalse = \u81EA\u5B9A\u4E49\u83DC\u5355\u3002 */\n menuNative: boolean\n /** \u8BBE\u7F6E\u9762\u677F\uFF1A\u6761\u76EE\u8FC7\u591A\u65F6\u5BFC\u822A\u5217\u53EF\u6EDA\u52A8\u3002 */\n panelScroll: boolean\n /** \u8BBE\u7F6E\u9762\u677F\uFF1A\u5141\u8BB8\u62D6\u62FD\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u3002 */\n panelResize: boolean\n /** \u8BBE\u7F6E\u9762\u677F\u5BBD\uFF08px\uFF09\uFF1B\u7F3A\u7701\u4F7F\u7528\u5B98\u65B9\u9ED8\u8BA4 800\u3002 */\n panelWidth?: number\n /** \u8BBE\u7F6E\u9762\u677F\u9AD8\uFF08px\uFF09\uFF1B\u7F3A\u7701\u4F7F\u7528\u5B98\u65B9\u9ED8\u8BA4 min(800, \u89C6\u53E3-48)\u3002 */\n panelHeight?: number\n /** OpenCode \u8BF7\u6C42\u5934\uFF1A\u542F\u7528\u540E\u5199\u8FDB llm-pi-ai \u7684 opencode \u7CFB\u8DEF\u7531\u3002 */\n headerEnabled: boolean\n /** \u5934\u540D\uFF08\u9ED8\u8BA4 x-opencode-session\uFF09\u3002 */\n headerName: string\n /** \u5934\u503C\uFF1B\u7559\u7A7A\u65F6\u9996\u6B21\u542F\u7528\u7531\u5BBF\u4E3B\u534A\u751F\u6210\u4E00\u4E2A\u7A33\u5B9A ID \u5E76\u843D\u76D8\u6CBF\u7528\u3002 */\n headerValue: string\n /** \u4F5C\u7528\u8DEF\u7531\u540D\u5355\uFF1B\u7559\u7A7A = \u81EA\u52A8\u5339\u914D opencode \u7CFB\u8DEF\u7531\uFF08\u53EA\u52A8\u5DF2\u5B58\u5728\u7684\u8DEF\u7531\uFF09\u3002 */\n headerRoutes: string\n /** \u5BBF\u4E3B\u534A\u8BB0\u8D26\u5B57\u6BB5\uFF08\u8BBE\u7F6E\u9875\u53EA\u8BFB\uFF09\u3002 */\n headerAppliedName: string\n headerAppliedValue: string\n /** \u5BBF\u4E3B\u534A\u5199\u5165\u7ED3\u679C\uFF08\u8BBE\u7F6E\u9875\u53EA\u8BFB\uFF09\u3002 */\n headerStatus: string\n /** \u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF08\u987A\u5E8F\u5373\u9762\u677F\u4E0E\u8BBE\u7F6E\u9875\u91CC\u7684\u663E\u793A\u987A\u5E8F\uFF09\u3002 */\n quickPrompts: readonly QuickPrompt[]\n /** \u63D0\u793A\u8BCD\u4F18\u5316\u5F3A\u5EA6\u6863\u4F4D\u3002 */\n optimizerTier: OptimizerTier\n}\n\n/** \u9ED8\u8BA4\u503C = DSH Web \u73B0\u72B6\uFF08Enter \u53D1\u9001\u3001Shift+Enter \u6362\u884C\u3001\u53F3\u952E\u83DC\u5355\u5168\u5F00\uFF09\u3002 */\nexport const DEFAULT_SETTINGS: ComposerUxSettings = {\n enabled: true,\n sendKey: 'Enter',\n newlineKey: 'Shift+Enter',\n menuUndo: true,\n menuRedo: true,\n menuCut: true,\n menuCopy: true,\n menuPaste: true,\n menuDelete: true,\n menuSelectAll: true,\n menuNative: false,\n panelScroll: true,\n panelResize: true,\n headerEnabled: false,\n headerName: DEFAULT_HEADER_NAME,\n headerValue: '',\n headerRoutes: '',\n headerAppliedName: '',\n headerAppliedValue: '',\n headerStatus: '',\n quickPrompts: DEFAULT_QUICK_PROMPTS,\n optimizerTier: DEFAULT_OPTIMIZER_TIER,\n}\n\n/** \u8BBE\u7F6E\u9875\u300C\u952E\u4F4D\u300D\u4E00\u8282\u7684\u9884\u8BBE\u3002 */\nexport const SEND_PRESETS: readonly string[] = ['Enter', 'Ctrl+Enter', 'Alt+Enter', 'Shift+Enter']\nexport const NEWLINE_PRESETS: readonly string[] = ['Shift+Enter', 'Enter', 'Ctrl+Enter', 'Alt+Enter']\n\n/** \u53F3\u952E\u83DC\u5355\u6761\u76EE\uFF08\u987A\u5E8F\u5373\u663E\u793A\u987A\u5E8F\uFF1Bshortcut \u4E0E\u56FE\u7247\u4E00\u81F4\uFF09\u3002 */\nexport const MENU_ITEMS: readonly {\n readonly field: MenuField\n readonly label: string\n readonly shortcut: string\n}[] = [\n { field: 'menuUndo', label: '\u64A4\u9500', shortcut: 'Ctrl+Z' },\n { field: 'menuRedo', label: '\u91CD\u505A', shortcut: 'Ctrl+Y' },\n { field: 'menuCut', label: '\u526A\u5207', shortcut: 'Ctrl+X' },\n { field: 'menuCopy', label: '\u590D\u5236', shortcut: 'Ctrl+C' },\n { field: 'menuPaste', label: '\u7C98\u8D34', shortcut: 'Ctrl+V' },\n { field: 'menuDelete', label: '\u5220\u9664', shortcut: '' },\n { field: 'menuSelectAll', label: '\u5168\u9009', shortcut: 'Ctrl+A' },\n]\n\n/**\n * \u751F\u6210\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID\uFF08UUID v4\uFF1B\u65E0 crypto \u65F6\u9000\u56DE\u7B49\u4EF7\u7684\u968F\u673A\u5341\u516D\u8FDB\u5236\uFF09\u3002\n * \u503C\u672C\u8EAB\u4E0D\u53C2\u4E0E\u9274\u6743\uFF0C\u53EA\u7528\u4E8E\u8BA9\u7F51\u5173\u628A\u540C\u4E00\u6BB5\u5BF9\u8BDD\u56FA\u5B9A\u5230\u540C\u4E00\u4E2A\u4E0A\u6E38\uFF0C\u6545 Math.random \u515C\u5E95\u53EF\u63A5\u53D7\u3002\n * @returns 36 \u5B57\u7B26\u7684 UUID \u5B57\u7B26\u4E32\u3002\n */\nexport function newSessionId(): string {\n const bag = globalThis as unknown as { crypto?: { randomUUID?: () => string } }\n if (typeof bag.crypto?.randomUUID === 'function') return bag.crypto.randomUUID()\n const hex = (count: number): string => Array.from(\n { length: count },\n () => Math.floor(Math.random() * 16).toString(16),\n ).join('')\n return `${hex(8)}-${hex(4)}-4${hex(3)}-a${hex(3)}-${hex(12)}`\n}\n\n/** \u89E3\u6790\u300C\u4F5C\u7528\u8DEF\u7531\u300D\u6587\u672C\uFF1A\u9017\u53F7 / \u7A7A\u683C / \u6362\u884C\u5206\u9694\uFF0C\u53BB\u91CD\u4FDD\u5E8F\u3002 */\nexport function parseRouteList(text: string): readonly string[] {\n const parts = text.split(/[\\s,\uFF0C\u3001]+/).map(item => item.trim()).filter(item => item !== '')\n return [...new Set(parts)]\n}\n\n/** \u8BBE\u7F6E\u6570\u636E\u51C0\u5316\uFF1A\u628A\u7EBF\u4E0A\u503C\u6536\u7A84\u4E3A\u5B89\u5168\u5F62\u72B6\uFF08\u9632\u810F\u6570\u636E\uFF09\u3002 */\nexport function sanitizeSettings(value: unknown): ComposerUxSettings {\n const source = (typeof value === 'object' && value !== null ? value : {}) as Record<string, unknown>\n const asString = (field: string): string => {\n const v = source[field]\n return typeof v === 'string' && v.length > 0 && v.length <= 64 ? v : ''\n }\n const asText = (field: string, max: number): string => {\n const v = source[field]\n return typeof v === 'string' && v.length <= max ? v : ''\n }\n const asBool = (field: string): boolean => {\n const v = source[field]\n return typeof v === 'boolean' ? v : (DEFAULT_SETTINGS as unknown as Record<string, unknown>)[field] as boolean\n }\n const asSize = (field: string): number | undefined => {\n const v = source[field]\n return typeof v === 'number' && Number.isFinite(v) && v >= 320 && v <= 4000 ? Math.round(v) : undefined\n }\n /**\n * \u51C0\u5316\u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF1A\u9010\u6761\u6536\u7A84\u5F62\u72B6\uFF0C\u4E22\u6389\u6B8B\u7F3A\u9879\uFF0C\u5E76\u6309 id \u53BB\u91CD\u4FDD\u5E8F\u3002\n * \u5B57\u6BB5\u7F3A\u5931 / \u4E0D\u662F\u6570\u7EC4\uFF08\u9996\u6B21\u542F\u7528\uFF09\u2192 \u56DE\u843D\u5230\u5185\u7F6E 9 \u6761\uFF1B\u5B57\u6BB5\u662F\u6570\u7EC4\u5C31\u7167\u5B83\u6765\uFF0C\n * \u7A7A\u6570\u7EC4\u4E5F\u662F\u5408\u6CD5\u72B6\u6001\uFF08\u7528\u6237\u628A\u6761\u76EE\u5168\u5220\u5149\uFF0C\u5C31\u5E94\u5F53\u4FDD\u6301\u5168\u7A7A\uFF0C\u4E0D\u518D\u81EA\u52A8\u5192\u51FA\u6765\uFF09\u3002\n */\n const asQuickPrompts = (): readonly QuickPrompt[] => {\n const raw = source[QUICK_PROMPTS_FIELD]\n if (!Array.isArray(raw)) return DEFAULT_QUICK_PROMPTS\n const seen = new Set<string>()\n const out: QuickPrompt[] = []\n for (const item of raw) {\n if (out.length >= QUICK_PROMPT_MAX) break\n if (typeof item !== 'object' || item === null) continue\n const row = item as Record<string, unknown>\n const prompt = typeof row.prompt === 'string' ? row.prompt.slice(0, QUICK_TEXT_MAX).trim() : ''\n if (prompt === '') continue\n const label = typeof row.label === 'string' ? row.label.slice(0, QUICK_LABEL_MAX).trim() : ''\n const id = typeof row.id === 'string' && row.id !== '' ? row.id.slice(0, 64) : newQuickPromptId()\n if (seen.has(id)) continue\n seen.add(id)\n out.push({ id, label: label === '' ? prompt.slice(0, 12) : label, prompt, always: row.always === true })\n }\n return out\n }\n const asTier = (): OptimizerTier => {\n const v = source[OPTIMIZER_TIER_FIELD]\n return v === 'basic' || v === 'advanced' || v === 'extreme' ? v : DEFAULT_OPTIMIZER_TIER\n }\n return {\n enabled: asBool(ENABLED_FIELD),\n sendKey: asString(SEND_KEY_FIELD),\n newlineKey: asString(NEWLINE_KEY_FIELD),\n menuUndo: asBool('menuUndo'),\n menuRedo: asBool('menuRedo'),\n menuCut: asBool('menuCut'),\n menuCopy: asBool('menuCopy'),\n menuPaste: asBool('menuPaste'),\n menuDelete: asBool('menuDelete'),\n menuSelectAll: asBool('menuSelectAll'),\n menuNative: asBool(MENU_NATIVE_FIELD),\n panelScroll: asBool(PANEL_SCROLL_FIELD),\n panelResize: asBool(PANEL_RESIZE_FIELD),\n panelWidth: asSize(PANEL_WIDTH_FIELD),\n panelHeight: asSize(PANEL_HEIGHT_FIELD),\n headerEnabled: asBool(HEADER_ENABLED_FIELD),\n // \u5934\u540D\u7559\u7A7A\u662F\u4E0D\u5408\u6CD5\u72B6\u6001\uFF08\u5BBF\u4E3B\u534A\u4F1A\u62D2\u7EDD\u5199\u5165\u5E76\u628A\u539F\u56E0\u5199\u8FDB headerStatus\uFF09\uFF0C\n // \u6545\u51C0\u5316\u53EA\u505A\u957F\u5EA6\u6536\u7A84\u3001\u4FDD\u7559\u539F\u6837\uFF0C\u8BA9\u7528\u6237\u770B\u5F97\u89C1\u81EA\u5DF1\u8F93\u9519\u4E86\u4EC0\u4E48\u3002\n headerName: asText(HEADER_NAME_FIELD, HEADER_NAME_MAX),\n headerValue: asText(HEADER_VALUE_FIELD, HEADER_VALUE_MAX),\n headerRoutes: asText(HEADER_ROUTES_FIELD, HEADER_VALUE_MAX),\n headerAppliedName: asText(HEADER_APPLIED_NAME_FIELD, HEADER_NAME_MAX),\n headerAppliedValue: asText(HEADER_APPLIED_VALUE_FIELD, HEADER_VALUE_MAX),\n headerStatus: asText(HEADER_STATUS_FIELD, HEADER_VALUE_MAX),\n quickPrompts: asQuickPrompts(),\n optimizerTier: asTier(),\n }\n}\n", "/**\n * \u5FEB\u6377\u6307\u4EE4\u7684**\u5BA2\u6237\u7AEF**\u8BFB\u5199\u5C42\u3002\n *\n * \u4E24\u4EF6\u4E8B\uFF1A\n * 1. \u7ECF\u5BBF\u4E3B\u8DEF\u7531 `/composer-ux/prompts` \u8BFB\u3001\u5199\u6574\u672C\uFF08\u6D4F\u89C8\u5668\u6CA1\u6709\u6587\u4EF6\u7CFB\u7EDF\uFF0C\u53EA\u80FD\u8D70 HTTP\uFF09\uFF1B\n * 2. \u4E00\u7EC4**\u7EAF**\u7F16\u8F91\u51FD\u6570\uFF08\u589E\u5220\u6539\u79FB\uFF09\uFF0C\u5168\u90E8\u4E0D\u53EF\u53D8\u2014\u2014\u5217\u8868\u64CD\u4F5C\u6700\u5BB9\u6613\u51FA\u300C\u539F\u5730\u6539\u574F\u300D\u7684\n * bug\uFF0C\u7EAF\u51FD\u6570\u8BA9\u5B83\u80FD\u5728 node \u91CC\u76F4\u63A5\u6D4B\uFF08\u89C1 test/quick-store.mjs \u7B2C 10 \u8282\uFF09\u3002\n *\n * \u4FDD\u5B58\u7B56\u7565\uFF1A\u5148\u4E50\u89C2\u66F4\u65B0\u672C\u5730\u5FEB\u7167\u8BA9 UI \u7ACB\u523B\u54CD\u5E94\uFF0C\u518D\u628A\u6574\u672C POST \u4E0A\u53BB\uFF1B**\u5931\u8D25\u5C31\u4EE5\u78C1\u76D8\n * \u4E3A\u51C6\u56DE\u6EDA**\u2014\u2014\u7EDD\u4E0D\u8BA9\u300C\u754C\u9762\u663E\u793A\u7684\u300D\u548C\u300C\u6587\u4EF6\u91CC\u7684\u300D\u957F\u671F\u4E0D\u4E00\u81F4\u3002\n */\nimport {\n DEFAULT_CATEGORY_NAME, QUICK_CATEGORY_MAX, QUICK_CATEGORY_NAME_MAX, QUICK_LABEL_MAX,\n QUICK_PROMPTS_API_PATH, QUICK_PROMPT_MAX, QUICK_TEXT_MAX,\n newQuickCategoryId, newQuickPromptId, sanitizeBook,\n type QuickPrompt, type QuickPromptBook, type QuickPromptCategory,\n} from '../settings-contract.ts'\n\n/** \u8DEF\u7531\u5E94\u7B54\uFF08\u6210\u529F\u4E0E\u5931\u8D25\u90FD\u8D70\u540C\u4E00\u5F62\u72B6\uFF0C\u4FBF\u4E8E\u7EDF\u4E00\u5904\u7406\uFF09\u3002 */\nexport interface PromptBookReply {\n readonly ok: boolean\n readonly book?: QuickPromptBook\n readonly error?: string\n /** \u78C1\u76D8\u4E0A\u7684\u771F\u5B9E\u8DEF\u5F84\uFF08\u5C55\u793A\u7ED9\u7528\u6237\uFF0C\u4FBF\u4E8E\u624B\u5DE5\u7F16\u8F91/\u5907\u4EFD\uFF09\u3002 */\n readonly file?: string\n /** \u574F\u6587\u4EF6\u88AB\u9694\u79BB\u540E\u7684\u8DEF\u5F84\uFF08\u975E\u7A7A\u8BF4\u660E\u51FA\u4E86\u95EE\u9898\u3001\u4E14\u539F\u6587\u4EF6\u5DF2\u4FDD\u4F4F\uFF09\u3002 */\n readonly quarantined?: string\n}\n\nasync function requestBook(method: 'GET' | 'POST', body?: unknown): Promise<PromptBookReply> {\n try {\n const response = await fetch(QUICK_PROMPTS_API_PATH, {\n method,\n headers: body === undefined ? undefined : { 'content-type': 'application/json' },\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n const text = await response.text()\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n return { ok: false, error: `\u670D\u52A1\u7AEF\u8FD4\u56DE\u7684\u4E0D\u662F JSON\uFF08HTTP ${String(response.status)}\uFF09` }\n }\n const row = (typeof parsed === 'object' && parsed !== null ? parsed : {}) as Record<string, unknown>\n const book = sanitizeBook(row.book)\n const textOf = (value: unknown): string | undefined => (typeof value === 'string' && value !== '' ? value : undefined)\n return {\n ok: row.ok === true,\n ...(book === undefined ? {} : { book }),\n ...(textOf(row.error) === undefined ? {} : { error: textOf(row.error) }),\n ...(textOf(row.file) === undefined ? {} : { file: textOf(row.file) }),\n ...(textOf(row.quarantined) === undefined ? {} : { quarantined: textOf(row.quarantined) }),\n }\n } catch (error: unknown) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) }\n }\n}\n\n/** \u8BFB\u6574\u672C\uFF08\u9996\u6B21\u8BFB\u53D6\u4F1A\u89E6\u53D1\u5BBF\u4E3B\u534A\u7684\u4E00\u6B21\u6027\u8FC1\u79FB\uFF09\u3002 */\nexport function loadPromptBook(): Promise<PromptBookReply> {\n return requestBook('GET')\n}\n\n/** \u5199\u6574\u672C\uFF08\u5BBF\u4E3B\u534A\u4F1A\u505A\u539F\u5B50\u5199\uFF1B\u574F\u6587\u4EF6\u65F6\u5B83\u4F1A\u62D2\u7EDD\u5199\u5165\u5E76\u62A5\u9519\uFF09\u3002 */\nexport function savePromptBook(book: QuickPromptBook): Promise<PromptBookReply> {\n return requestBook('POST', { book })\n}\n\n// \u2500\u2500 \u7EAF\u7F16\u8F91\u51FD\u6570\uFF08\u5168\u90E8\u4E0D\u53EF\u53D8\uFF0C\u8FD4\u56DE\u65B0\u672C\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** \u6309 id \u627E\u5206\u7C7B\u3002 */\nexport function categoryOf(book: QuickPromptBook, categoryId: string): QuickPromptCategory | undefined {\n return book.categories.find(category => category.id === categoryId)\n}\n\n/** \u6309 id \u627E\u6761\u76EE\uFF08\u8DE8\u5206\u7C7B\uFF1A\u9762\u677F\u91CC\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u52FE\u9009\u4E0D\u5E26\u5206\u7C7B\u4E0A\u4E0B\u6587\uFF09\u3002 */\nexport function findPrompt(\n book: QuickPromptBook,\n promptId: string,\n): { readonly category: QuickPromptCategory; readonly prompt: QuickPrompt } | undefined {\n for (const category of book.categories) {\n const prompt = category.prompts.find(item => item.id === promptId)\n if (prompt !== undefined) return { category, prompt }\n }\n return undefined\n}\n\n/** \u7EDF\u8BA1\uFF08\u9762\u677F\u5934\u90E8\u4E0E\u8BBE\u7F6E\u9875\u7528\uFF09\u3002 */\nexport function bookCounts(book: QuickPromptBook): { readonly categories: number; readonly prompts: number; readonly always: number } {\n const prompts = book.categories.flatMap(category => category.prompts)\n return {\n categories: book.categories.length,\n prompts: prompts.length,\n always: prompts.filter(prompt => prompt.always).length,\n }\n}\n\nfunction mapCategory(\n book: QuickPromptBook,\n categoryId: string,\n edit: (category: QuickPromptCategory) => QuickPromptCategory,\n): QuickPromptBook {\n return {\n version: book.version,\n categories: book.categories.map(category => (category.id === categoryId ? edit(category) : category)),\n }\n}\n\n/** \u65B0\u589E\u5206\u7C7B\uFF08\u540D\u5B57\u53BB\u7A7A\u767D\uFF1B\u8D85\u8FC7\u4E0A\u9650\u5219\u4E0D\u52A8\u4F5C\u5E76\u8FD4\u56DE\u539F\u672C\uFF09\u3002 */\nexport function withCategoryAdded(book: QuickPromptBook, name: string): QuickPromptBook {\n if (book.categories.length >= QUICK_CATEGORY_MAX) return book\n const clean = name.trim().slice(0, QUICK_CATEGORY_NAME_MAX)\n return {\n version: book.version,\n categories: [...book.categories, { id: newQuickCategoryId(), name: clean === '' ? DEFAULT_CATEGORY_NAME : clean, prompts: [] }],\n }\n}\n\n/** \u6539\u5206\u7C7B\u540D\uFF08\u7A7A\u540D\u56DE\u843D\u5230\u9ED8\u8BA4\u540D\uFF0C\u907F\u514D\u51FA\u73B0\u70B9\u4E0D\u4E2D\u7684\u7A7A\u6807\u7B7E\uFF09\u3002 */\nexport function withCategoryRenamed(book: QuickPromptBook, categoryId: string, name: string): QuickPromptBook {\n const clean = name.trim().slice(0, QUICK_CATEGORY_NAME_MAX)\n return mapCategory(book, categoryId, category => ({ ...category, name: clean === '' ? DEFAULT_CATEGORY_NAME : clean }))\n}\n\n/** \u5220\u5206\u7C7B\uFF08\u8FDE\u5E26\u5B83\u91CC\u9762\u7684\u6761\u76EE\u4E00\u8D77\u5220\uFF09\u3002 */\nexport function withCategoryRemoved(book: QuickPromptBook, categoryId: string): QuickPromptBook {\n return { version: book.version, categories: book.categories.filter(category => category.id !== categoryId) }\n}\n\n/** \u5206\u7C7B\u6362\u4F4D\uFF08delta = -1 \u4E0A\u79FB / +1 \u4E0B\u79FB\uFF09\uFF1B\u8D8A\u754C\u65F6\u539F\u6837\u8FD4\u56DE\u3002 */\nexport function withCategoryMoved(book: QuickPromptBook, categoryId: string, delta: number): QuickPromptBook {\n const index = book.categories.findIndex(category => category.id === categoryId)\n const next = index + delta\n if (index < 0 || next < 0 || next >= book.categories.length) return book\n const categories = [...book.categories]\n const [moved] = categories.splice(index, 1)\n categories.splice(next, 0, moved)\n return { version: book.version, categories }\n}\n\n/** \u5728\u6307\u5B9A\u5206\u7C7B\u91CC\u52A0\u4E00\u6761\u7A7A\u6761\u76EE\uFF08\u540D\u5B57\u4E0E\u6B63\u6587\u7559\u7A7A\uFF0C\u7531\u7528\u6237\u5728\u8BBE\u7F6E\u9875\u586B\uFF09\u3002 */\nexport function withPromptAdded(book: QuickPromptBook, categoryId: string): QuickPromptBook {\n return mapCategory(book, categoryId, (category) => {\n if (category.prompts.length >= QUICK_PROMPT_MAX) return category\n return { ...category, prompts: [...category.prompts, { id: newQuickPromptId(), label: '\u65B0\u6307\u4EE4', prompt: '', always: false }] }\n })\n}\n\n/**\n * \u6539\u6761\u76EE\u5B57\u6BB5\u3002\n *\n * `prompt` \u7A7A\u4E32\u662F**\u5408\u6CD5\u4E2D\u95F4\u6001**\uFF08\u7528\u6237\u6B63\u5728\u7F16\u8F91\uFF09\uFF0C\u6545\u8FD9\u91CC\u4E0D\u505A\u300C\u7A7A\u5C31\u4E22\u6389\u300D\u7684\u6536\u7A84\u2014\u2014\n * \u6536\u7A84\u53D1\u751F\u5728\u5199\u76D8\u4E0E\u51C0\u5316\u65F6\uFF08`sanitizeBook` \u4F1A\u4E22\u6389\u7A7A\u6B63\u6587\u7684\u6761\u76EE\uFF09\uFF0C\u754C\u9762\u4E0A\u4F1A\u8868\u73B0\u4E3A\n * \u300C\u4FDD\u5B58\u540E\u7A7A\u6761\u76EE\u6D88\u5931\u300D\uFF0C\u8FD9\u662F\u671F\u671B\u884C\u4E3A\u3002\n */\nexport function withPromptPatched(\n book: QuickPromptBook,\n categoryId: string,\n promptId: string,\n patch: Partial<Pick<QuickPrompt, 'label' | 'prompt' | 'always'>>,\n): QuickPromptBook {\n return mapCategory(book, categoryId, (category) => ({\n ...category,\n prompts: category.prompts.map((prompt) => {\n if (prompt.id !== promptId) return prompt\n const label = patch.label === undefined ? prompt.label : patch.label.slice(0, QUICK_LABEL_MAX)\n const text = patch.prompt === undefined ? prompt.prompt : patch.prompt.slice(0, QUICK_TEXT_MAX)\n const always = patch.always === undefined ? prompt.always : patch.always\n return { id: prompt.id, label, prompt: text, always }\n }),\n }))\n}\n\n/** \u5220\u6761\u76EE\u3002 */\nexport function withPromptRemoved(book: QuickPromptBook, categoryId: string, promptId: string): QuickPromptBook {\n return mapCategory(book, categoryId, category => ({\n ...category,\n prompts: category.prompts.filter(prompt => prompt.id !== promptId),\n }))\n}\n\n/** \u6761\u76EE\u6362\u4F4D\uFF1B\u8D8A\u754C\u65F6**\u8FD4\u56DE\u4F20\u5165\u7684\u90A3\u4E2A\u5BF9\u8C61**\uFF08\u8C03\u7528\u65B9\u636E\u6B64\u907F\u514D\u65E0\u610F\u4E49\u7684\u5199\u76D8\uFF09\u3002 */\nexport function withPromptMoved(book: QuickPromptBook, categoryId: string, promptId: string, delta: number): QuickPromptBook {\n const category = categoryOf(book, categoryId)\n if (category === undefined) return book\n const index = category.prompts.findIndex(prompt => prompt.id === promptId)\n const next = index + delta\n if (index < 0 || next < 0 || next >= category.prompts.length) return book\n const prompts = [...category.prompts]\n const [moved] = prompts.splice(index, 1)\n prompts.splice(next, 0, moved)\n return mapCategory(book, categoryId, target => ({ ...target, prompts }))\n}\n\n/** \u52FE\u9009/\u53D6\u6D88\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF08\u6309 id \u8DE8\u5206\u7C7B\u627E\uFF09\u3002 */\nexport function withAlwaysToggled(book: QuickPromptBook, promptId: string, value: boolean): QuickPromptBook {\n const hit = findPrompt(book, promptId)\n if (hit === undefined) return book\n return withPromptPatched(book, hit.category.id, promptId, { always: value })\n}\n", "/**\n * \u952E\u4F4D\u89C4\u8303\u4E32\uFF1A\u4FEE\u9970\u952E\u6309 Ctrl+Alt+Shift+Meta \u987A\u5E8F + \u4E3B\u952E\uFF0C\u7528 '+' \u8FDE\u63A5\u3002\n * \u4E3B\u952E\u53D6\u503C\u4F18\u5148\u7269\u7406\u7801\uFF08KeyJ\u2192J\u3001Digit3\u21923\uFF09\uFF0C\u5176\u4F59\u7528\u6807\u51C6\u6309\u952E\u540D\uFF08Enter\u3001Space\u3001F2...\uFF09\u3002\n */\n\n/** \u4E00\u6B21\u6309\u952E\u4E8B\u4EF6\u7684\u53EA\u8BFB\u6295\u5F71\uFF08KeyboardEvent \u7684\u6700\u5C0F\u5F62\u72B6\uFF09\u3002 */\nexport interface ChordEvent {\n readonly ctrlKey: boolean\n readonly altKey: boolean\n readonly shiftKey: boolean\n readonly metaKey: boolean\n readonly code: string\n readonly key: string\n}\n\n/** \u4FEE\u9970\u952E\u672C\u8EAB\uFF08\u4E0D\u5E94\u4F5C\u4E3A\u4E3B\u952E\u53C2\u4E0E\u7ED1\u5B9A\uFF09\u3002 */\nconst MODIFIER_KEYS = new Set(['Control', 'Alt', 'Shift', 'Meta', 'AltGraph'])\n\n/** \u5E38\u89C1\u6807\u70B9\u4E3B\u952E\u7684\u53CB\u597D\u540D\u3002 */\nconst CODE_LABELS: Readonly<Record<string, string>> = {\n Slash: '/',\n Backslash: '\\\\',\n BracketLeft: '[',\n BracketRight: ']',\n Semicolon: ';',\n Quote: \"'\",\n Comma: ',',\n Period: '.',\n Backquote: '`',\n Minus: '-',\n Equal: '=',\n Space: 'Space',\n}\n\n/** \u628A\u4E00\u6B21\u6309\u952E\u4E8B\u4EF6\u7F16\u7801\u4E3A\u89C4\u8303\u4E32\uFF1B\u7EAF\u4FEE\u9970\u952E\u8FD4\u56DE ''\u3002 */\nexport function encodeChord(event: ChordEvent): string {\n const parts: string[] = []\n if (event.ctrlKey) parts.push('Ctrl')\n if (event.altKey) parts.push('Alt')\n if (event.shiftKey) parts.push('Shift')\n if (event.metaKey) parts.push('Meta')\n const mainKey = normalizeMainKey(event)\n if (mainKey === '') return ''\n parts.push(mainKey)\n return parts.join('+')\n}\n\n/** \u4E3B\u952E\u540D\uFF1A\u5B57\u6BCD/\u6570\u5B57\u7528\u7269\u7406\u7801\u5F52\u4E00\uFF0C\u5176\u4F59\u7528\u6807\u51C6\u540D\u3002 */\nfunction normalizeMainKey(event: ChordEvent): string {\n const code = event.code\n if (code.startsWith('Key')) return code.slice(3)\n if (code.startsWith('Digit')) return code.slice(5)\n if (CODE_LABELS[code] !== undefined) return CODE_LABELS[code] as string\n // F1..F24 \u53CA Enter/Tab/Arrow* /Backspace/Delete \u7B49 code \u672C\u8EAB\u5373\u6807\u51C6\u540D\u3002\n return code !== '' ? code : event.key\n}\n\n/** \u662F\u5426\u7EAF\u4FEE\u9970\u952E\u6309\u4E0B\uFF08\u7528\u4E8E\u5FFD\u7565 Ctrl/Alt/Shift \u5355\u72EC\u6309\u4E0B\uFF09\u3002 */\nexport function isModifierOnly(event: ChordEvent): boolean {\n return MODIFIER_KEYS.has(event.key)\n}\n\n/** \u4E3B\u952E\u662F\u5426\u5C5E\u4E8E\u300C\u6253\u5B57\u7C7B\u300D\u6309\u952E\uFF08\u672A\u88AB\u8BB0\u5F55\u89C4\u5219\u5141\u8BB8\u7684\u88F8\u952E\uFF09\u3002 */\nconst BARE_ALLOWED = new Set([\n 'Enter', 'Space', 'Tab', 'Backspace', 'Delete', 'Insert', 'Home', 'End',\n 'PageUp', 'PageDown', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight',\n])\n\n/** \u88F8\u952E\uFF08\u65E0\u4EFB\u4F55\u4FEE\u9970\u952E\uFF09\u662F\u5426\u5141\u8BB8\u7ED1\u5B9A\u3002 */\nexport function isBareKeyAllowed(chord: string): boolean {\n if (chord.includes('+')) return true\n if (BARE_ALLOWED.has(chord)) return true\n return /^F\\d{1,2}$/.test(chord)\n}\n\n/** \u89E3\u6790\u89C4\u8303\u4E32 \u2192 \u53CD\u5411\u4E8B\u4EF6\u521D\u59CB\u5316\u53C2\u6570\uFF08\u7528\u4E8E\u5408\u6210\u56DE\u653E\uFF09\u3002 */\nexport function chordToInit(chord: string): KeyboardEventInit {\n const parts = chord.split('+').filter(Boolean)\n const init: KeyboardEventInit = {\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n bubbles: true,\n cancelable: true,\n }\n const key = parts.pop() ?? ''\n init.key = key\n // \u4E3B\u952E\u7684 code \u53CD\u63A8\uFF08\u5C3D\u529B\u8FD8\u539F\uFF1B\u4EC5\u5F71\u54CD IME/\u7269\u7406\u7801\u8BFB\u53D6\uFF0C\u4E0D\u5C5E\u5173\u952E\u8DEF\u5F84\uFF09\u3002\n init.code = key.length === 1 ? (/^[A-Z]$/.test(key) ? `Key${key}` : key) : key\n for (const part of parts) {\n if (part === 'Ctrl') init.ctrlKey = true\n else if (part === 'Alt') init.altKey = true\n else if (part === 'Shift') init.shiftKey = true\n else if (part === 'Meta') init.metaKey = true\n }\n return init\n}\n\n/** \u952E\u4F4D\u662F\u5426\u5C5E\u4E8E Enter \u5BB6\u65CF\uFF08\u62E6\u622A\u5668\u53EA\u63A5\u7BA1\u8FD9\u4E9B\u7EC4\u5408\uFF09\u3002 */\nexport function isEnterFamily(chord: string): boolean {\n return chord === 'Enter' || chord.endsWith('+Enter')\n}\n\n/** \u8BB0\u5F55\u65F6\u5408\u6CD5\u6027\u68C0\u67E5\u7ED3\u679C\u3002 */\nexport type RecordResult =\n | { kind: 'ok'; chord: string }\n | { kind: 'cancel' }\n | { kind: 'clear' }\n | { kind: 'ignore' }\n | { kind: 'reject'; message: string }\n\n/** \u68C0\u67E5\u5F55\u5236\u6309\u952E\uFF1A\u7ED3\u679C\u4E3A ok \u65F6\u8FD4\u56DE\u53EF\u5199\u5165\u7684\u89C4\u8303\u4E32\u3002 */\nexport function evaluateRecordedKey(event: ChordEvent): RecordResult {\n if (isModifierOnly(event)) return { kind: 'ignore' }\n if (event.code === 'Escape' || event.key === 'Escape') return { kind: 'cancel' }\n // Backspace/Delete = \u6E05\u9664\u7ED1\u5B9A\uFF08\u4E0E\u300C\u65E0\u300D\u7B49\u4EF7\uFF0C\u4F46\u8BED\u4E49\u66F4\u660E\u663E\uFF09\u3002\n if (event.code === 'Backspace' || event.code === 'Delete') return { kind: 'clear' }\n const chord = encodeChord(event)\n if (chord === '') return { kind: 'ignore' }\n if (!isBareKeyAllowed(chord)) {\n return {\n kind: 'reject',\n message: '\u5355\u4E2A\u5B57\u6BCD/\u6570\u5B57\u952E\u4F1A\u4E0E\u6253\u5B57\u51B2\u7A81\uFF0C\u8BF7\u914D\u5408 Ctrl / Alt / Shift \u4F7F\u7528\uFF0C\u6216\u9009\u62E9 Enter\u3002',\n }\n }\n return { kind: 'ok', chord }\n}\n\n/** \u952E\u4F4D\u663E\u793A\u6587\u672C\uFF1A'' \u2192 \u65E0\u3002 */\nexport function displayChord(chord: string): string {\n return chord === '' ? '\u65E0' : chord\n}\n", "/**\n * \u5FEB\u6377\u6307\u4EE4\u4E0E\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u8FD0\u884C\u65F6\u6865\u63A5\u3002\n *\n * \u4E3A\u4EC0\u4E48\u9700\u8981\u8FD9\u4E2A\u6A21\u5757\uFF1A\u8F93\u5165\u6846\u62E6\u622A\u5668\uFF08interceptors.ts\uFF09\u6D3B\u5728\u7EAF DOM / \u6355\u83B7\u9636\u6BB5\u91CC\uFF0C\n * \u62FF\u4E0D\u5230 React \u69FD\u4F4D\u624D\u6709\u7684 `inputActions` \u4E0E InputState \u8349\u7A3F\uFF1B\u800C\u300C\u70B9\u53D1\u9001\u65F6\u81EA\u52A8\u628A\n * \u63D0\u793A\u8BCD\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\u300D\u4E24\u6837\u90FD\u8981\u7528 \u2014\u2014 \u5F97\u77E5\u9053\u5F53\u524D\u8349\u7A3F\u662F\u4EC0\u4E48\uFF0C\u518D\u628A\u9644\u52A0\u540E\u7684\u6574\u6BB5\u5199\n * \u56DE\u7F16\u8F91\u5668\u3002\u4E8E\u662F\u7531 `conversation.input.right` \u7684\u6309\u94AE\u7EC4\u4EF6\u5728\u6BCF\u6B21\u6E32\u67D3\u65F6\u628A\u8FD9\u4E24\u6837\u4E1C\u897F\n * \u6295\u9012\u5230\u8FD9\u91CC\uFF0C\u62E6\u622A\u5668\u540C\u6B65\u8BFB\u53D6\u3002\n *\n * \u672C\u6A21\u5757\u96F6 React \u4F9D\u8D56\uFF0C\u53EF\u88AB\u62E6\u622A\u5668\u4E0E\u7EC4\u4EF6\u5171\u7528\u3002\n */\nimport type { QuickPrompt } from '../settings-contract.ts'\nimport { OPTIMIZER_API_PATH } from '../settings-contract.ts'\n\n/** \u5B98\u65B9\u516C\u5F00\u8F93\u5165\u52A8\u4F5C\u91CC\u672C\u6A21\u5757\u7528\u5230\u7684\u4E24\u4E2A\uFF08\u89C1 DSH \u7684 InputActions \u5951\u7EA6\uFF09\u3002 */\nexport interface InputActionsLike {\n /** \u6574\u4F53\u66FF\u6362\u8349\u7A3F\uFF08\u5B98\u65B9\u652F\u6301\u7684\u7A0B\u5E8F\u5316\u5199\u5165\u8DEF\u5F84\uFF09\u3002 */\n setDraft: (text: string) => void\n}\n\n/** \u8349\u7A3F\u6765\u6E90\uFF1A\u69FD\u4F4D\u5FEB\u7167\uFF08\u6743\u5A01\uFF09> DOM \u515C\u5E95\u3002 */\ninterface BridgeState {\n actions: InputActionsLike | null\n draft: string\n sessionId: string\n}\n\n/** \u8F93\u5165\u6846\u6839\u5143\u7D20\u7684\u9009\u62E9\u5668\uFF08\u4E0E interceptors.ts \u4FDD\u6301\u4E00\u81F4\uFF09\u3002 */\nconst COMPOSER_SELECTOR = '[data-composer-input]'\n\n/** \u8F93\u5165\u5361\u7247\u9009\u62E9\u5668\uFF08\u5B98\u65B9\u5728 InputBar \u4E0A\u5199\u7684\u6807\u8BB0\uFF09\u3002 */\nconst CARD_SELECTOR = '[data-composer-card]'\n\nconst state: BridgeState = { actions: null, draft: '', sessionId: '' }\n\n/**\n * \u69FD\u4F4D\u7EC4\u4EF6\u6BCF\u6B21\u6E32\u67D3\u6295\u9012\u4E00\u6B21\u6865\u63A5\u6570\u636E\u3002\n * @param next - \u672C\u4F1A\u8BDD\u7684\u8F93\u5165\u52A8\u4F5C\u3001\u5F53\u524D\u8349\u7A3F\u4E0E\u670D\u52A1\u7AEF\u4F1A\u8BDD id\u3002\n */\nexport function publishInputBridge(next: {\n readonly actions: InputActionsLike | null\n readonly draft: string\n readonly sessionId: string\n}): void {\n state.actions = next.actions\n state.draft = next.draft\n state.sessionId = next.sessionId\n}\n\n/**\n * \u5378\u8F7D\u65F6\u64A4\u4E0B\u6865\u63A5\uFF0C\u907F\u514D\u300C\u5207\u8D70\u7684\u4F1A\u8BDD\u300D\u7559\u4E0B\u7684\u65E7 actions \u88AB\u540E\u7EED\u624B\u52BF\u8BEF\u7528\u3002\n * \u53EA\u6E05\u81EA\u5DF1\u90A3\u4EFD\uFF1A\u540C\u4E00\u4E2A\u4F1A\u8BDD\u53EF\u80FD\u5148\u540E\u6302\u8F7D\u591A\u4E2A\u69FD\u4F4D\u6761\u76EE\u3002\n * @param sessionId - \u5378\u8F7D\u65B9\u6240\u5C5E\u4F1A\u8BDD id\u3002\n */\nexport function releaseInputBridge(sessionId: string): void {\n if (state.sessionId !== sessionId) return\n state.actions = null\n state.draft = ''\n state.sessionId = ''\n}\n\n/** DOM \u515C\u5E95\u8BFB\u8349\u7A3F\uFF08\u69FD\u4F4D\u672A\u6302\u8F7D\u65F6\u7684\u6700\u540E\u624B\u6BB5\uFF09\u3002 */\nfunction draftFromDom(): string {\n const el = document.querySelector(COMPOSER_SELECTOR)\n if (!(el instanceof HTMLElement)) return ''\n return el.innerText.replace(/\\n+$/, '')\n}\n\n/** \u5F53\u524D\u8349\u7A3F\uFF1A\u6709\u69FD\u4F4D\u5C31\u4FE1\u69FD\u4F4D\u5FEB\u7167\uFF0C\u5426\u5219\u8BFB DOM\u3002 */\nexport function currentDraft(): string {\n return state.actions === null ? draftFromDom() : state.draft\n}\n\n/** \u5F53\u524D\u4F1A\u8BDD id\uFF08'' = \u65E0\u4F1A\u8BDD\uFF09\u3002 */\nexport function currentSessionId(): string {\n return state.sessionId\n}\n\n/** \u53D6\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u6761\u76EE\uFF08\u4FDD\u6301\u5217\u8868\u987A\u5E8F\uFF0C\u4E22\u6389\u7A7A\u5185\u5BB9\uFF09\u3002 */\nexport function alwaysPrompts(prompts: readonly QuickPrompt[]): readonly QuickPrompt[] {\n return prompts.filter(item => item.always === true && item.prompt.trim() !== '')\n}\n\n/**\n * \u628A\u52FE\u4E86\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u6761\u76EE\u62FC\u5230\u539F\u6587**\u672B\u5C3E**\u3002\n *\n * \u89C4\u5219\uFF08\u4E0E\u7528\u6237\u786E\u8BA4\u8FC7\u7684\u8BED\u4E49\u4E00\u81F4\uFF09\uFF1A\n * - \u591A\u6761\u6309\u5217\u8868\u987A\u5E8F\u62FC\u63A5\uFF0C\u6761\u76EE\u4E4B\u95F4\u7A7A\u4E00\u884C\uFF1B\n * - \u539F\u6587\u4E3A\u7A7A\u65F6**\u4E0D\u9644\u52A0** \u2014\u2014 \u6CA1\u6709\u300C\u4F60\u7684\u6D88\u606F\u300D\u53EF\u9644\u52A0\uFF0C\u6B64\u65F6\u5E94\u5F53\u4EA4\u8FD8\u5B98\u65B9\u539F\u8BED\u4E49\n * \uFF08\u7A7A\u8F93\u5165\u7684 Enter \u5728\u5B98\u65B9\u90A3\u91CC\u662F\u522B\u7684\u52A8\u4F5C\uFF0C\u62A2\u8FC7\u6765\u4F1A\u8BA9\u4EBA\u610F\u5916\uFF09\uFF1B\n * - \u4E00\u6761\u90FD\u6CA1\u52FE\u65F6\u8FD4\u56DE null\uFF1B\n * - **\u5DF2\u7ECF\u4EE5\u540C\u4E00\u6BB5\u540E\u7F00\u7ED3\u5C3E\u65F6\u8FD4\u56DE null\uFF08\u5E42\u7B49\uFF09** \u2014\u2014 \u4E07\u4E00\u53D1\u9001\u90A3\u4E00\u6B65\u6CA1\u6210\uFF0C\u7B2C\u4E8C\u6B21\n * \u70B9\u51FB\u4E0D\u4F1A\u628A\u540C\u4E00\u6BB5\u63D0\u793A\u8BCD\u518D\u53E0\u4E00\u904D\uFF0C\u800C\u662F\u76F4\u63A5\u653E\u884C\u5B98\u65B9\u53D1\u9001\uFF080.2.0 \u7684\u5931\u63A7\u75C7\u72B6\u5C31\u662F\n * \u300C\u4E00\u76F4\u70B9\u4E00\u76F4\u63D2\u5165\u300D\uFF0C\u8FD9\u6761\u62A4\u680F\u8BA9\u5B83\u53D8\u6210\u300C\u518D\u70B9\u4E00\u6B21\u5C31\u53D1\u51FA\u53BB\u300D\uFF09\u3002\n * @param draft - \u5F53\u524D\u8349\u7A3F\u539F\u6587\u3002\n * @param prompts - \u5B8C\u6574\u5FEB\u6377\u6307\u4EE4\u5217\u8868\u3002\n * @returns \u62FC\u63A5\u540E\u7684\u5B8C\u6574\u8349\u7A3F\uFF1B\u65E0\u9700\u9644\u52A0\u65F6\u4E3A null\u3002\n */\nexport function withAlwaysPrompts(draft: string, prompts: readonly QuickPrompt[]): string | null {\n const picked = alwaysPrompts(prompts)\n if (picked.length === 0) return null\n const base = draft.replace(/\\s+$/, '')\n if (base === '') return null\n const suffix = picked.map(item => item.prompt.trim()).join('\\n\\n')\n if (base.endsWith(suffix)) return null\n return `${base}\\n\\n${suffix}`\n}\n\n/**\n * \u628A\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u5199\u56DE\u7F16\u8F91\u5668\u3002\n *\n * \u53EA\u8D1F\u8D23\u5199\u5165\uFF0C\u4E0D\u8D1F\u8D23\u53D1\u9001\uFF1A\u53D1\u9001\u52A8\u4F5C\u4EA4\u8FD8\u5B98\u65B9\u624B\u52BF\uFF08\u89C1 interceptors.ts \u7684\u4E24\u6761\u8DEF\u5F84\uFF09\uFF0C\n * \u8FD9\u6837\u300C\u53D1\u9001 / \u6392\u961F / \u6253\u65AD\u300D\u7684\u8BED\u4E49\u5B8C\u5168\u7531\u5B98\u65B9\u51B3\u5B9A\uFF0C\u672C\u63D2\u4EF6\u4E0D\u505A\u7B2C\u4E8C\u5957\u5224\u65AD\u3002\n * @param prompts - \u5B8C\u6574\u5FEB\u6377\u6307\u4EE4\u5217\u8868\u3002\n * @returns true = \u5DF2\u5199\u5165\uFF08\u8C03\u7528\u65B9\u5E94\u7EE7\u7EED\u8D70\u5B98\u65B9\u53D1\u9001\u624B\u52BF\uFF09\uFF1Bfalse = \u65E0\u9700\u9644\u52A0\u3002\n */\nexport function applyAlwaysPrompts(prompts: readonly QuickPrompt[]): boolean {\n const actions = state.actions\n if (actions === null) return false\n const next = withAlwaysPrompts(currentDraft(), prompts)\n if (next === null) return false\n actions.setDraft(next)\n return true\n}\n\n/** \u628A\u4E00\u6BB5\u6587\u672C\u63D2\u8FDB\u8F93\u5165\u6846\uFF08\u6761\u76EE\u70B9\u51FB\u63D2\u5165\u7528\uFF1B\u539F\u6709\u5185\u5BB9\u4FDD\u7559\uFF0C\u65B0\u5185\u5BB9\u53E6\u8D77\u4E00\u884C\uFF09\u3002 */\nexport function insertIntoDraft(text: string): boolean {\n const actions = state.actions\n const body = text.trim()\n if (actions === null || body === '') return false\n const draft = currentDraft()\n const next = draft.trim() === '' ? body : `${draft.replace(/\\s+$/, '')}\\n${body}`\n actions.setDraft(next)\n return true\n}\n\n/** \u6574\u4F53\u66FF\u6362\u8349\u7A3F\uFF08\u4F18\u5316\u7ED3\u679C\u5199\u56DE\u7528\uFF09\u3002 */\nexport function replaceDraft(text: string): boolean {\n const actions = state.actions\n if (actions === null) return false\n actions.setDraft(text)\n return true\n}\n\n/** \u628A\u7126\u70B9\u4EA4\u8FD8\u8F93\u5165\u6846\uFF08\u63D2\u5165/\u5199\u56DE\u4E4B\u540E\u8C03\u7528\uFF0C\u65B9\u4FBF\u63A5\u7740\u6253\u5B57\uFF09\u3002 */\nexport function focusComposer(): void {\n const el = document.querySelector(COMPOSER_SELECTOR)\n if (el instanceof HTMLElement) el.focus({ preventScroll: true })\n}\n\n/**\n * \u627E\u51FA\u8FD9\u6B21\u70B9\u51FB\u843D\u5728\u7684**\u5B98\u65B9\u53D1\u9001\u4E3B\u6309\u94AE**\uFF1B\u4E0D\u662F\u53D1\u9001\u952E\u65F6\u8FD4\u56DE null\u3002\n *\n * \u4E3A\u4EC0\u4E48\u8FD4\u56DE\u5143\u7D20\u800C\u4E0D\u662F\u5E03\u5C14\uFF1A\u8C03\u7528\u65B9\u8981\u62FF\u5B83**\u91CD\u653E\u4E00\u6B21\u70B9\u51FB**\uFF08\u89C1 interceptors.ts\uFF09\u3002\n * \u8FD9\u91CC\u5FC5\u987B\u8FD4\u56DE\u771F\u6B63\u7684 `<button>`\uFF0C\u800C\u4E0D\u662F `event.target` \u2014\u2014 \u53D1\u9001\u952E\u662F\u4E2A\u5706\u5F62\u6309\u94AE\uFF0C\n * \u89C6\u89C9\u4E2D\u5FC3\u5C31\u662F\u91CC\u9762\u7684 `<svg>` / `<path>`\uFF0C\u800C **SVG \u5143\u7D20\u6CA1\u6709 `.click()`**\u3002\n * 0.2.0 \u5C31\u662F\u56E0\u4E3A\u628A `event.target` \u5F53\u6309\u94AE\u7528\u3001`click()` \u629B TypeError \u800C\u6CA1\u53D1\u9001\uFF0C\n * \u75C7\u72B6\u662F\u300C\u70B9\u4E86\u53EA\u63D2\u5165\u3001\u4E0D\u53D1\u9001\uFF0C\u4E00\u76F4\u70B9\u4E00\u76F4\u63D2\u5165\u300D\u3002\n *\n * \u4E3A\u4EC0\u4E48\u6562\u6309\u7ED3\u6784\u5224\u522B\uFF1A\u53D1\u9001\u952E\u4E0E\u505C\u6B62\u952E\u5171\u7528\u540C\u4E00\u4E2A\u4F4D\u7F6E\uFF08\u5361\u7247\u91CC\u6700\u540E\u4E00\u4E2A button\uFF09\uFF0C\n * \u53EA\u80FD\u9760\u56FE\u5F62\u533A\u5206 \u2014\u2014 \u505C\u6B62\u6E32\u67D3 `<rect>`\uFF08\u65B9\u5757\uFF09\uFF0C\u53D1\u9001\u6E32\u67D3 `<path>`\uFF08\u7BAD\u5934\uFF09\u3002\n * \u6309\u56FE\u5F62\u5224\u522B\u4E0E\u754C\u9762\u6587\u6848\u3001\u8BED\u8A00\u90FD\u65E0\u5173\uFF0C\u4E2D\u82F1\u6587\u73AF\u5883\u4E00\u81F4\u3002\n * @param target - \u4E8B\u4EF6\u76EE\u6807\uFF08\u53EF\u80FD\u662F\u6309\u94AE\u672C\u8EAB\uFF0C\u4E5F\u53EF\u80FD\u662F\u5B83\u5185\u90E8\u7684\u56FE\u6807\uFF09\u3002\n * @returns \u5B98\u65B9\u53D1\u9001\u4E3B\u6309\u94AE\uFF1B\u65E0\u6CD5\u786E\u5B9A\u65F6 null\uFF08\u6B64\u65F6\u8C03\u7528\u65B9\u5FC5\u987B**\u4E0D\u62E6\u622A**\uFF09\u3002\n */\nexport function sendButtonOf(target: EventTarget | null): HTMLButtonElement | null {\n if (!(target instanceof Element)) return null\n const card = target.closest(CARD_SELECTOR)\n if (card === null) return null\n const buttons = card.querySelectorAll('button')\n if (buttons.length === 0) return null\n const last = buttons[buttons.length - 1]!\n // \u5FC5\u987B\u662F\u771F\u6B63\u7684 <button>\uFF1A\u62FF\u5230\u7684\u82E5\u662F svg\uFF0C\u91CD\u653E\u70B9\u51FB\u4F1A\u5931\u8D25\u3002\n if (!(last instanceof HTMLButtonElement)) return null\n if (last !== target && !last.contains(target)) return null\n if (last.disabled) return null\n // \u505C\u6B62\u952E\uFF1A\u65B9\u5757\u56FE\u6807\u3002\u53D1\u9001\u952E\uFF1A\u7BAD\u5934 path\u3002\n if (last.querySelector('svg rect') !== null) return null\n if (last.querySelector('svg path') === null) return null\n return last\n}\n\n/** \u4E00\u6B21\u4F18\u5316\u7684\u7ED3\u679C\u3002 */\nexport interface OptimizeOutcome {\n readonly ok: boolean\n /** \u6210\u529F\u65F6\uFF1A\u4F18\u5316\u540E\u7684\u6B63\u6587\u3002 */\n readonly text?: string\n /** \u5931\u8D25\u65F6\uFF1A\u7ED9\u7528\u6237\u770B\u7684\u4E00\u53E5\u8BDD\u539F\u56E0\u3002 */\n readonly error?: string\n /** \u6210\u529F\u65F6\uFF1A\u5B9E\u9645\u4F7F\u7528\u7684\u8DEF\u7531\uFF08\u7528\u4E8E\u300C\u4F18\u5316\u6CA1\u751F\u6548\u300D\u65F6\u7684\u6392\u67E5\uFF09\u3002 */\n readonly route?: string\n}\n\n/**\n * \u8BF7\u5BBF\u4E3B\u534A\u8DD1\u4E00\u6B21\u72EC\u7ACB\u4F18\u5316\u3002\n *\n * \u4E3A\u4EC0\u4E48\u662F\u4E00\u6B21 HTTP \u5F80\u8FD4\uFF1A\u51FA\u7F51\u8BF7\u6C42\u7531\u5BBF\u4E3B\u7684\u6A21\u578B\u9002\u914D\u5668\u53D1\u51FA\uFF0C\u6D4F\u89C8\u5668\u4FA7\u78B0\u4E0D\u5230\u6A21\u578B\u8DEF\u7531\uFF1B\n * \u5BBF\u4E3B <-> \u5BA2\u6237\u7AEF\u4E4B\u95F4\u6CA1\u6709\u522B\u7684\u53D7\u652F\u6301\u901A\u9053\uFF08\u4E0E WestFox \u7684\u63D2\u4EF6\u540C\u6784\uFF09\u3002\n * @param text - \u8F93\u5165\u6846\u91CC\u7684\u539F\u6587\u3002\n * @param tier - \u5F3A\u5EA6\u6863\u4F4D\u3002\n * @returns \u4F18\u5316\u7ED3\u679C\uFF1B\u7F51\u7EDC\u5C42\u5931\u8D25\u4E5F\u5F52\u4E00\u6210 `ok: false` \u800C\u4E0D\u629B\u3002\n */\nexport async function optimizeDraft(text: string, tier: string): Promise<OptimizeOutcome> {\n const body = text.trim()\n if (body === '') return { ok: false, error: '\u8F93\u5165\u6846\u662F\u7A7A\u7684\uFF0C\u5148\u5199\u70B9\u4EC0\u4E48\u518D\u4F18\u5316' }\n let response: Response\n try {\n response = await fetch(OPTIMIZER_API_PATH, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ text: body, tier }),\n })\n } catch (error) {\n return { ok: false, error: `\u8FDE\u4E0D\u4E0A\u5BBF\u4E3B\u534A\u7684\u4F18\u5316\u63A5\u53E3\uFF1A${error instanceof Error ? error.message : String(error)}` }\n }\n if (!response.ok) {\n return { ok: false, error: `\u5BBF\u4E3B\u534A\u8FD4\u56DE HTTP ${response.status}\uFF08\u63D2\u4EF6\u53EF\u80FD\u8FD8\u6CA1\u91CD\u542F\u751F\u6548\uFF09` }\n }\n let payload: unknown\n try {\n payload = await response.json()\n } catch {\n return { ok: false, error: '\u5BBF\u4E3B\u534A\u8FD4\u56DE\u7684\u4E0D\u662F JSON' }\n }\n const record = (typeof payload === 'object' && payload !== null ? payload : {}) as Record<string, unknown>\n if (record.ok !== true) {\n const message = typeof record.error === 'string' && record.error !== '' ? record.error : '\u4F18\u5316\u5931\u8D25'\n return { ok: false, error: message }\n }\n const optimized = typeof record.text === 'string' ? record.text.trim() : ''\n if (optimized === '') return { ok: false, error: '\u6A21\u578B\u6CA1\u6709\u4EA7\u51FA\u4EFB\u4F55\u5185\u5BB9' }\n const route = `${String(record.provider ?? '')}/${String(record.model ?? '')}`\n return { ok: true, text: optimized, route }\n}\n", "/** \u8F93\u5165\u6846\u62E6\u622A\u5668\uFF1A\u63A5\u7BA1 Enter \u5BB6\u65CF\u952E\u4F4D\uFF08\u53D1\u9001/\u6362\u884C\uFF09\u4E0E\u53F3\u952E\u83DC\u5355\u3002\n * \u4E0E React \u65E0\u5173\uFF1A\u57FA\u4E8E\u300C\u6355\u83B7\u9636\u6BB5 + \u76EE\u6807\u9650\u5B9A + \u5408\u6210\u56DE\u653E\u300D\u7684\u62E6\u622A\u6A21\u578B\u3002\n *\n * \u952E\u4F4D\u89C4\u5219\uFF08\u603B\u62EC\uFF09\uFF1A\n * - \u8BB0\u5F55\u76EE\u6807\u53EA\u5728\u4E3B\u804A\u5929\u8F93\u5165\u6846 [data-composer-input] \u5185\uFF1B\n * - IME \u7EC4\u5408\u671F\u95F4\uFF08isComposing / keyCode 229\uFF09\u4E00\u5F8B\u653E\u884C\uFF0C\u7EDD\u4E0D\u5F71\u54CD\u4E2D\u6587\u8F93\u5165\uFF1B\n * - '/' '@' \u89E6\u53D1\u5668\u83DC\u5355\u6216\u4EFB\u4F55\u8F93\u5165\u6846 overlay \u6253\u5F00\u65F6\u653E\u884C Enter\uFF0C\u8BA9\u83DC\u5355\u4EF2\u88C1\u4F18\u5148\uFF1B\n * - \u547D\u4E2D\u300C\u53D1\u9001\u952E\u4F4D\u300D\u2192 \u56DE\u653E\u5E26 Ctrl \u52A0\u901F\u8BED\u4E49\u4E4B\u5916\u7684\u666E\u901A Enter\uFF08\u8D70\u5B98\u65B9\u63D0\u4EA4\u7BA1\u7EBF\uFF09\uFF1B\n * - \u547D\u4E2D\u300C\u6362\u884C\u952E\u4F4D\u300D\u2192 \u56DE\u653E Shift+Enter\uFF08\u5B98\u65B9\u6362\u884C\u7BA1\u7EBF\uFF09\uFF1B\n * - Ctrl+Enter / Meta+Enter \u82E5\u672A\u88AB\u7ED1\u5B9A\uFF0C\u5219\u56DE\u653E\u539F\u7EC4\u5408\uFF0C\u4FDD\u7559\u5B98\u65B9\u300C\u52A0\u901F\u63D0\u4EA4\u300D\u884C\u4E3A\uFF1B\n * - \u5176\u4F59 Enter \u5BB6\u65CF\u7EC4\u5408\uFF1A\u6D88\u8017\u4F46\u4E0D\u52A8\u4F5C\uFF08\u7528\u6237\u663E\u5F0F\u53D6\u6D88\u7684\u539F\u751F\u8BED\u4E49\uFF09\u3002\n *\n * \u5173\u952E\u5B88\u536B\uFF1A\u5408\u6210\u56DE\u653E\u4E8B\u4EF6\u4E5F\u5FC5\u987B\u7ECF\u8FC7 window \u6355\u83B7\u76D1\u542C\u5668\uFF0C\u56E0\u6B64\u56DE\u653E\u671F\u95F4\u7528\n * \u540C\u6B65\u6807\u5FD7\u8DF3\u8FC7\u81EA\u8EAB\u62E6\u622A\uFF0C\u5426\u5219\u53D1\u9001/\u6362\u884C\u56DE\u653E\u4F1A\u65E0\u9650\u81EA\u89E6\u53D1\u3002\n */\nimport {\n chordToInit, encodeChord, isEnterFamily, type ChordEvent,\n} from './chords.ts'\nimport { applyAlwaysPrompts, sendButtonOf } from './quick-commands.ts'\nimport type { ComposerUxSettings, MenuState, QuickPrompt } from '../settings-contract.ts'\n\nexport interface InterceptorDeps {\n /** \u540C\u6B65\u8BFB\u53D6\u5F53\u524D\u89E3\u6790\u540E\u7684\u8BBE\u7F6E\uFF08\u62E6\u622A\u5668\u975E React \u73AF\u5883\uFF09\u3002 */\n readonly settings: () => ComposerUxSettings\n /**\n * \u540C\u6B65\u8BFB\u53D6\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u6761\u76EE\uFF08\u8DE8\u5206\u7C7B\uFF09\u3002\n *\n * 0.3.0 \u8D77\u5FEB\u6377\u6307\u4EE4\u5B58\u5728 quick-prompts.json \u91CC\uFF0C\u4E0D\u518D\u5C5E\u4E8E\u8BBE\u7F6E\u6587\u6863\uFF0C\u6240\u4EE5\u8FD9\u91CC\u5355\u72EC\u8981\u4E00\u4E2A\n * \u53D6\u503C\u51FD\u6570\uFF0C\u800C\u4E0D\u662F\u4ECE `settings.quickPrompts` \u62FF\u3002\n */\n readonly alwaysPrompts: () => readonly QuickPrompt[]\n /** \u6253\u5F00 / \u5173\u95ED\u53F3\u952E\u83DC\u5355\u3002 */\n readonly setMenu: (state: MenuState | null) => void\n /** \u81EA\u5B9A\u4E49\u83DC\u5355\u5F53\u524D\u662F\u5426\u6253\u5F00\uFF08\u539F\u751F\u83DC\u5355\u6A21\u5F0F\u4E0B\u9700\u8981\u6E05\u6389\uFF09\u3002 */\n readonly menuOpen: () => boolean\n}\n\nconst INPUT_SELECTOR = '[data-composer-input]'\nconst OVERLAY_SELECTOR = '[data-trigger-menu], [data-conversation-composer-overlay]'\n\n/** \u76EE\u6807\u662F\u5426\u843D\u5728\u4E3B\u804A\u5929\u8F93\u5165\u6846\u53CA\u5176\u5185\u90E8\u3002 */\nfunction findComposerRoot(target: EventTarget | null): HTMLElement | null {\n if (!(target instanceof Element)) return null\n return target.closest<HTMLElement>(INPUT_SELECTOR)\n}\n\n/** \u89E6\u53D1\u5668\u83DC\u5355\uFF08'/' '@'\uFF09\u6216\u8F93\u5165\u6846 overlay \u662F\u5426\u6253\u5F00\u3002 */\nfunction overlayOpen(): boolean {\n return document.querySelector(OVERLAY_SELECTOR) !== null\n}\n\n/** \u56DE\u653E\u8FDB\u884C\u4E2D\u6807\u5FD7\uFF1A\u5408\u6210\u4E8B\u4EF6\u56DE\u5230\u6355\u83B7\u76D1\u542C\u5668\u65F6\u8DF3\u8FC7\u81EA\u8EAB\u62E6\u622A\u3002 */\nlet replaying = false\n\n/** \u5B98\u65B9\u53D1\u9001\u6309\u94AE\u7684\u300C\u5148\u5199\u56DE\u3001\u518D\u91CD\u653E\u300D\u6807\u5FD7\uFF08\u907F\u514D\u5408\u6210\u70B9\u51FB\u88AB\u81EA\u5DF1\u518D\u62E6\u4E00\u6B21\uFF09\u3002 */\nlet replayingSendClick = false\n\n/** \u53F3\u952E\u65F6\u9884\u8BFB\u6210\u529F\u7684\u526A\u8D34\u677F\u6587\u672C\u7F13\u5B58\uFF08null = \u672A\u9884\u8BFB/\u9884\u8BFB\u5931\u8D25\uFF09\u3002 */\nlet pasteCache: string | null = null\n\n/** \u5728\u53F3\u952E\u624B\u52BF\u91CC\u53D1\u8D77\u4E00\u6B21\u9759\u9ED8\u9884\u8BFB\uFF1A\u6388\u6743\u6D6E\u7A97\u6B64\u523B\u51FA\u73B0\uFF0C\u7528\u6237\u987A\u624B\u70B9\u4E00\u6B21\u5373\u53EF\u3002 */\nfunction prefetchClipboard(): void {\n pasteCache = null\n const readText = (navigator as Navigator & { clipboard?: { readText?: () => Promise<string> } }).clipboard?.readText\n if (typeof readText !== 'function') return\n readText.call(navigator.clipboard).then(\n (text: string) => { pasteCache = text },\n () => { pasteCache = null },\n )\n}\n\n/** \u5411\u8F93\u5165\u6846\u6839\u5143\u7D20\u6D3E\u53D1\u5408\u6210\u6309\u952E\uFF08\u89E6\u53D1 Lexical \u81EA\u8EAB\u952E\u76D8\u7BA1\u7EBF\uFF09\u3002 */\nfunction dispatchKey(root: HTMLElement, init: KeyboardEventInit): void {\n replaying = true\n try {\n root.dispatchEvent(new KeyboardEvent('keydown', init))\n } finally {\n replaying = false\n }\n}\n\n/** \u662F\u5426\u8FDB\u5165 IME \u7EC4\u5408\uFF08\u5408\u6210\u4E8B\u4EF6\u9700\u4E0E\u771F\u5B9E\u6309\u952E\u8D70\u540C\u4E00\u5B88\u536B\uFF09\u3002 */\nfunction composing(event: KeyboardEvent): boolean {\n // oxlint-disable-next-line typescript/no-deprecated\n return event.isComposing || event.keyCode === 229\n}\n\n/** \u5B89\u88C5\u4E24\u4E2A\u6355\u83B7\u9636\u6BB5\u62E6\u622A\u5668\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\u3002 */\nexport function installInterceptors(deps: InterceptorDeps): () => void {\n const onKeyDown = (event: KeyboardEvent): void => {\n if (replaying) return\n const root = findComposerRoot(event.target)\n if (root === null) return\n if (composing(event)) return\n const chord = encodeChord(event as unknown as ChordEvent)\n if (!isEnterFamily(chord)) return\n // \u83DC\u5355/overlay \u6253\u5F00\u65F6\uFF0CEnter \u8981\u7ED9\u83DC\u5355\u4EF2\u88C1\uFF08\u8865\u5168\u9009\u62E9\u3001\u5F39\u5C42\u5173\u95ED\uFF09\u8BA9\u8DEF\u3002\n if (overlayOpen()) return\n\n const settings = deps.settings()\n const gesture = chord === settings.sendKey\n ? 'send'\n : chord === settings.newlineKey\n ? 'newline'\n : (chord === 'Ctrl+Enter' || chord === 'Meta+Enter') ? 'accelerated'\n : 'none'\n\n event.preventDefault()\n event.stopPropagation()\n // \u957F\u6309\u8FDE\u53D1\uFF1A\u6D88\u8017\u4E00\u6B21\u5373\u53EF\uFF08\u53D1\u9001\u9632\u673A\u67AA\u95E8\u4E0E\u5B98\u65B9\u4E00\u81F4\uFF0C\u6362\u884C\u8FDE\u53D1\u65E0\u610F\u4E49\uFF09\u3002\n if (event.repeat) return\n\n if (gesture === 'send') {\n // \u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF1A\u5148\u628A\u52FE\u9009\u7684\u63D0\u793A\u8BCD\u5199\u56DE\u7F16\u8F91\u5668\u672B\u5C3E\uFF0C\u518D\u56DE\u653E\u53D1\u9001\u624B\u52BF \u2014\u2014\n // \u5B98\u65B9\u624B\u52BF\u7167\u65E7\uFF08\u542B\u8FD0\u884C\u4E2D\u300C\u6392\u961F / \u6253\u65AD\u300D\u7684\u5224\u5B9A\uFF09\uFF0C\u672C\u63D2\u4EF6\u4E0D\u505A\u7B2C\u4E8C\u5957\u5224\u65AD\u3002\n // \u539F\u6587\u4E3A\u7A7A\u65F6 applyAlwaysPrompts \u8FD4\u56DE false\uFF0C\u4E00\u5207\u7167\u65E7\u3002\n applyAlwaysPrompts(deps.alwaysPrompts())\n dispatchKey(root, chordToInit('Enter'))\n } else if (gesture === 'newline') {\n dispatchKey(root, chordToInit('Shift+Enter'))\n } else if (gesture === 'accelerated') {\n dispatchKey(root, chordToInit('Ctrl+Enter'))\n }\n // gesture === 'none'\uFF1A\u6D88\u8017\u4F46\u65E0\u52A8\u4F5C\u3002\n }\n\n const onContextMenu = (event: MouseEvent): void => {\n const root = findComposerRoot(event.target)\n if (root === null) return\n // \u539F\u751F\u83DC\u5355\u6A21\u5F0F\uFF1A\u4E0D\u8BA9\u7B2C\u4E09\u65B9\u63D2\u4EF6\uFF08\u5982 dsh-paste-input-plus \u7684\u300C\u53EA\u6709\u590D\u5236\u300D\u83DC\u5355\uFF09\n // \u5403\u6389 contextmenu\u2014\u2014\u6211\u4EEC\u6392\u5728 capture \u9636\u6BB5\u5148\u6267\u884C\uFF0CstopImmediatePropagation \u540E\n // \u4E8B\u4EF6\u5230\u4E0D\u4E86 bubble \u9636\u6BB5\u7684\u63D2\u4EF6\u76D1\u542C\u5668\uFF1B\u4F46\u4E0D preventDefault\uFF0C\u6D4F\u89C8\u5668\u539F\u751F\u83DC\u5355\u7167\u5E38\u51FA\u73B0\u3002\n if (deps.settings().menuNative) {\n if (deps.menuOpen()) deps.setMenu(null)\n event.stopImmediatePropagation()\n event.stopPropagation()\n return\n }\n event.preventDefault()\n event.stopPropagation()\n const selection = window.getSelection()\n const hasSelection = selection !== null\n && !selection.isCollapsed\n && selection.anchorNode !== null\n && root.contains(selection.anchorNode)\n deps.setMenu({ x: event.clientX, y: event.clientY, hasSelection })\n // \u8D81\u7740\u53F3\u952E\u7684\u7528\u6237\u624B\u52BF\u8FD8\u5728\uFF0C\u9759\u9ED8\u9884\u8BFB\u526A\u8D34\u677F\uFF08\u6388\u6743\u6D6E\u7A97\u6B64\u523B\u5F39\u51FA\uFF0C\u70B9\u4E00\u6B21\u5373\u56FA\u5316\uFF09\u3002\n prefetchClipboard()\n }\n\n /**\n * \u5B98\u65B9\u300C\u53D1\u9001\u300D\u6309\u94AE\u4E0A\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u3002\n *\n * \u5B98\u65B9\u4E3B\u6309\u94AE\u8D70\u7684\u662F\u5305\u5185\u90E8\u7684 keyboard.submit\uFF08\u6CA1\u6709\u5BF9\u5916\u7684\u62E6\u622A\u94A9\u5B50\uFF09\uFF0C\u6240\u4EE5\u53EA\u80FD\u5728\n * \u6355\u83B7\u9636\u6BB5\u8BA4\u4E0B\u8FD9\u6B21\u70B9\u51FB\u3002\u8BA4\u4E0B\u4E4B\u540E\u4E0D\u53BB\u81EA\u5DF1\u8C03 submit \u2014\u2014 \u800C\u662F\u5148\u628A\u9644\u52A0\u5185\u5BB9\u5199\u56DE\u7F16\u8F91\u5668\u3001\n * \u518D\u7528\u540C\u4E00\u4E2A\u6309\u94AE\u91CD\u653E\u4E00\u6B21\u70B9\u51FB\uFF0C\u8BA9\u5B98\u65B9\u7684 primarySubmitMode\uFF08\u53D1\u9001 / \u6392\u961F / \u6253\u65AD\uFF09\n * \u539F\u6837\u751F\u6548\u3002\n *\n * \u4E24\u6761\u5FC5\u987B\u5B88\u4F4F\u7684\u7EAA\u5F8B\uFF080.2.0 \u5728\u8FD9\u4E24\u5904\u90FD\u51FA\u8FC7\u4E8B\uFF09\uFF1A\n * 1. \u91CD\u653E\u7684\u5FC5\u987B\u662F `sendButtonOf()` \u8FD4\u56DE\u7684**\u771F <button>**\uFF0C\u4E0D\u80FD\u662F event.target\n * \u2014\u2014 \u70B9\u5728\u5706\u5F62\u6309\u94AE\u7684\u89C6\u89C9\u4E2D\u5FC3\u65F6 target \u662F\u5185\u90E8\u7684 svg\uFF0Csvg \u6CA1\u6709 `.click()`\uFF0C\n * \u4F1A\u629B TypeError\uFF0C\u7ED3\u679C\u5C31\u662F\u300C\u5DF2\u63D2\u5165\u4F46\u6CA1\u53D1\u9001\u300D\u3002\n * 2. \u53EA\u6709\u5728\u786E\u8BA4\u80FD\u91CD\u653E\u4E4B\u540E\u624D preventDefault/stopPropagation\uFF1B\u62FF\u4E0D\u5230\u6309\u94AE\u5C31\u76F4\u63A5\n * \u653E\u884C\uFF0C\u7EDD\u4E0D\u628A\u7528\u6237\u8FD9\u6B21\u70B9\u51FB\u541E\u6389\u3002\n */\n const onClickSend = (event: MouseEvent): void => {\n if (replayingSendClick) return\n const button = sendButtonOf(event.target)\n if (button === null) return\n if (!applyAlwaysPrompts(deps.alwaysPrompts())) return\n event.preventDefault()\n event.stopPropagation()\n replayingSendClick = true\n try {\n button.click()\n } finally {\n replayingSendClick = false\n }\n }\n\n window.addEventListener('keydown', onKeyDown, true)\n window.addEventListener('contextmenu', onContextMenu, true)\n window.addEventListener('click', onClickSend, true)\n return () => {\n window.removeEventListener('keydown', onKeyDown, true)\n window.removeEventListener('contextmenu', onContextMenu, true)\n window.removeEventListener('click', onClickSend, true)\n }\n}\n\n/** \u53F3\u952E\u83DC\u5355\u52A8\u4F5C id\uFF08\u4E0E MENU_ITEMS \u5BF9\u5E94\uFF09\u3002 */\nexport type MenuActionId = 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'delete' | 'selectAll'\n\nexport interface MenuActionResult {\n readonly ok: boolean\n readonly message?: string\n}\n\n/** \u5728\u5F53\u524D\u8F93\u5165\u6846\u4E0A\u6267\u884C\u4E00\u4E2A\u53F3\u952E\u83DC\u5355\u52A8\u4F5C\u3002 */\nexport async function runMenuAction(id: MenuActionId): Promise<MenuActionResult> {\n const root = document.querySelector<HTMLElement>(INPUT_SELECTOR)\n if (root === null) return { ok: false, message: '\u627E\u4E0D\u5230\u8F93\u5165\u6846' }\n if (!document.activeElement || !root.contains(document.activeElement)) {\n if (root.isConnected) {\n root.focus({ preventScroll: true })\n }\n }\n switch (id) {\n case 'undo':\n dispatchKey(root, chordToInit('Ctrl+Z'))\n return { ok: true }\n case 'redo':\n dispatchKey(root, chordToInit('Ctrl+Y'))\n return { ok: true }\n case 'copy':\n return { ok: document.execCommand('copy') }\n case 'cut':\n return { ok: document.execCommand('cut') }\n case 'delete':\n return { ok: document.execCommand('delete') }\n case 'selectAll':\n return { ok: document.execCommand('selectAll') }\n case 'paste':\n return pasteText(root)\n }\n}\n\n/** \u5E26\u8D85\u65F6\u7684 Promise\uFF08\u7528\u4E8E\u7B49\u5F85\u526A\u8D34\u677F\u6388\u6743\u5F39\u7A97\uFF09\u3002 */\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => { reject(new Error('clipboard-read timeout')) }, ms)\n promise.then(\n (value) => { clearTimeout(timer); resolve(value) },\n (error: unknown) => { clearTimeout(timer); reject(error) },\n )\n })\n}\n\nfunction isClipboardTimeout(error: unknown): boolean {\n return error instanceof Error && error.message === 'clipboard-read timeout'\n}\n\n/** Firefox\uFF1A\u526A\u8D34\u677F\u6388\u6743\u4E0D\u8FDB\u7AD9\u70B9\u6743\u9650\u9762\u677F\uFF0C\u53EA\u80FD\u9760 about:config \u5168\u5C40\u5141\u8BB8\u4E00\u6B21\u3002 */\nfunction isFirefox(): boolean {\n return typeof navigator !== 'undefined' && /Firefox\\//.test(navigator.userAgent)\n}\n\n/** Firefox \u4E00\u6B21\u6027\u914D\u7F6E\u6307\u5F15\uFF08\u5168\u5C40\u5141\u8BB8\u8BFB\u526A\u8D34\u677F\uFF0Cafter:config \u65B0\u5EFA\u6574\u6570\uFF0C\u6539\u5B8C\u7ACB\u5373\u751F\u6548\uFF09\u3002 */\nconst FIREFOX_TIP = 'Firefox \u6BCF\u6B21\u8BFB\u526A\u8D34\u677F\u90FD\u8981\u70B9\u300C\u7C98\u8D34(P)\u300D\u786E\u8BA4\uFF1A\u5730\u5740\u680F\u8F93\u5165 about:config \u2192 \u63A5\u53D7\u98CE\u9669\u7EE7\u7EED \u2192 \u53F3\u952E\u65B0\u5EFA\u300C\u6574\u6570\u300D\u2192 \u540D\u79F0\u586B permissions.default.clipboard-read \u2192 \u503C\u586B 1 \u2192 \u91CD\u8FDB DSH\uFF1B\u4E4B\u540E\u70B9\u4E00\u6B21\u7C98\u8D34\u5373\u6210\u529F\uFF08\u6216\u76F4\u63A5 Ctrl+V\uFF09'\n\n/** \u7C98\u8D34\uFF1A\u8BFB\u526A\u8D34\u677F\u540E\u5728\u5149\u6807\u5904\u63D2\u5165\u7EAF\u6587\u672C\u3002\n * \u6D4F\u89C8\u5668\u5B89\u5168\u6A21\u578B\uFF1A\u5199\u526A\u8D34\u677F\uFF08\u590D\u5236/\u526A\u5207\uFF09\u514D\u6388\u6743\uFF0C\u8BFB\u526A\u8D34\u677F\uFF08\u7C98\u8D34\uFF09\u5FC5\u987B\u6388\u6743\uFF0C\n * \u4EFB\u4F55\u7F51\u9875\u90FD\u65E0\u6CD5\u7ED5\u8FC7\u2014\u2014\u4F46\u9996\u6B21\u6388\u6743\u540E\u6D4F\u89C8\u5668\u4F1A\u8BB0\u4F4F\u8BE5\u7AD9\u70B9\uFF0C\u4E4B\u540E\u9759\u9ED8\u53EF\u7528\u3002\n * \u4F18\u5148\u4F7F\u7528\u53F3\u952E\u65F6\u9884\u8BFB\u7684\u7F13\u5B58\uFF08\u6388\u6743\u5DF2\u88AB\u70B9\u51FB\u8FC7\u4E00\u6B21\uFF0C\u65E0\u611F\uFF09\uFF0C\u5931\u8D25\u518D\u5B9E\u65F6\u8BFB\u53D6\u3002\n */\nasync function pasteText(root: HTMLElement): Promise<MenuActionResult> {\n const insertText = (text: string): MenuActionResult => {\n if (!document.activeElement || !root.contains(document.activeElement)) {\n root.focus({ preventScroll: true })\n }\n if (text === '') return { ok: true }\n return { ok: document.execCommand('insertText', false, text) }\n }\n // \u7F13\u5B58\u547D\u4E2D\uFF1A\u53F3\u952E\u65F6\u6388\u6743\u5DF2\u5B8C\u6210\uFF0C\u76F4\u63A5\u63D2\u5165\uFF08\u53EF\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32\uFF0C\u6B64\u65F6\u8D70\u5B9E\u65F6\u8BFB\u53D6\uFF09\u3002\n if (pasteCache !== null && pasteCache !== '') {\n const text = pasteCache\n pasteCache = null\n return insertText(text)\n }\n if (typeof navigator === 'undefined' || navigator.clipboard === undefined\n || typeof navigator.clipboard.readText !== 'function') {\n return { ok: false, message: '\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u8BFB\u53D6\u526A\u8D34\u677F\uFF0C\u8BF7\u7528 Ctrl+V \u7C98\u8D34' }\n }\n // \u6743\u9650\u9884\u68C0\uFF1A\u5DF2\u88AB\u660E\u786E\u62D2\u7EDD\u65F6\u76F4\u63A5\u7ED9\u6062\u590D\u6307\u5F15\uFF08\u907F\u514D\u5047\u6B7B\u6216\u8BEF\u5BFC\uFF09\u3002\n const permissions = (navigator as {\n permissions?: { query?: (descriptor: { name: string }) => Promise<{ state: string }> }\n }).permissions\n if (permissions?.query) {\n try {\n const result = await permissions.query({ name: 'clipboard-read' })\n if (result.state === 'denied') {\n if (isFirefox()) return { ok: false, message: FIREFOX_TIP }\n return {\n ok: false,\n message: '\u6D4F\u89C8\u5668\u5DF2\u62D2\u7EDD\u526A\u8D34\u677F\u8BFB\u53D6\uFF1A\u70B9\u51FB\u5730\u5740\u680F\u5DE6\u4FA7\u56FE\u6807 \u2192 \u7AD9\u70B9\u8BBE\u7F6E \u2192 \u526A\u8D34\u677F \u2192 \u5141\u8BB8\uFF1B\u6216\u76F4\u63A5\u6309 Ctrl+V',\n }\n }\n } catch {\n // \u4E0D\u652F\u6301\u8BE5\u6743\u9650\u67E5\u8BE2\uFF1A\u7EE7\u7EED\u5C1D\u8BD5\u8BFB\u53D6\u3002\n }\n }\n let text: string\n try {\n // \u7B49\u5F85\u6388\u6743\u5F39\u7A97\u53EF\u80FD\u8F83\u4E45\uFF08\u8981\u7528\u6237\u70B9\u51FB\uFF09\uFF0C\u4E0D\u7528\u77ED\u8D85\u65F6\u8BEF\u62A5\u5931\u8D25\uFF1B15 \u79D2\u65E0\u54CD\u5E94\n // \u624D\u63D0\u793A\uFF0C\u907F\u514D\u83DC\u5355\u6C38\u4E45\u6302\u8D77\u3002\n text = await withTimeout(navigator.clipboard.readText(), 15000)\n } catch (error) {\n if (isFirefox()) {\n return { ok: false, message: FIREFOX_TIP }\n }\n if (isClipboardTimeout(error)) {\n return {\n ok: false,\n message: '\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF1A\u8BF7\u5728\u5F39\u51FA\u63D0\u793A\u4E2D\u9009\u62E9\u300C\u5141\u8BB8\u300D\uFF08\u82E5\u672A\u51FA\u73B0\uFF0C\u70B9\u5730\u5740\u680F\u5DE6\u4FA7\u56FE\u6807\u5F00\u542F\uFF09\uFF0C\u6216\u6309 Ctrl+V',\n }\n }\n return {\n ok: false,\n message: '\u672A\u83B7\u526A\u8D34\u677F\u8BFB\u53D6\u6388\u6743\uFF1A\u70B9\u51FB\u5730\u5740\u680F\u5DE6\u4FA7\u56FE\u6807 \u2192 \u7AD9\u70B9\u8BBE\u7F6E \u2192 \u526A\u8D34\u677F \u2192 \u5141\u8BB8\uFF1B\u6216\u76F4\u63A5\u6309 Ctrl+V \u7C98\u8D34',\n }\n }\n if (!document.activeElement || !root.contains(document.activeElement)) {\n root.focus({ preventScroll: true })\n }\n if (text === '') return { ok: true }\n return { ok: document.execCommand('insertText', false, text) }\n}\n", "/**\r\n * \u8BBE\u7F6E\u9762\u677F\u589E\u5F3A\uFF1A\u5BFC\u822A\u5217\u6EDA\u52A8\u6837\u5F0F + \u9762\u677F\u5C3A\u5BF8\u8C03\u6574\u624B\u67C4\u3002\r\n *\r\n * \u5B98\u65B9\u9762\u677F\u7ED3\u6784\uFF08ui-settings-general SettingsRoot\uFF09\uFF1A\r\n * .overlay\uFF08position:fixed; inset:0; **z-index:1000**\uFF09\r\n * \u251C\u2500\u2500 .mask\uFF08position:absolute; inset:0\uFF09\u2500\u2500 \u5168\u5C4F\u906E\u7F69\r\n * \u2514\u2500\u2500 [role=\"dialog\"][aria-modal=\"true\"] \u2500\u2500 .panel\uFF08position:relative; width:800; overflow:hidden\uFF09\r\n * \u251C\u2500\u2500 <nav> \u2500\u2500 \u6807\u9898 + navList\uFF08\u6761\u76EE\u8F83\u591A\u65F6\u6EA2\u51FA\uFF09\r\n * \u2514\u2500\u2500 <div> \u2500\u2500 header + .options\uFF08\u672C\u8EAB overflow-y:auto\uFF09\r\n *\r\n * \u26A0\uFE0F \u5C42\u53E0\u4E0A\u4E0B\u6587\u9677\u9631\uFF080.2.0 \u6574\u6BB5\u529F\u80FD\u56E0\u6B64\u5931\u6548\uFF0C\u52A1\u5FC5\u8BB0\u4F4F\uFF09\uFF1A\r\n * \u672C\u63D2\u4EF6\u80FD\u6302\u6D6E\u5C42\u7684\u4F4D\u7F6E\u53EA\u6709 `shell.overlay`\uFF0C\u800C\u5B83\u88AB\u5B98\u65B9\u5C01\u5728\r\n * `ui-layout` \u7684 `.overlayLayer { position:absolute; inset:0; z-index:20 }` \u91CC \u2014\u2014\r\n * `position` + `z-index` \u4F7F\u5B83**\u81EA\u6210\u5C42\u53E0\u4E0A\u4E0B\u6587**\uFF0C\u91CC\u9762\u7684\u5143\u7D20\u518D\u600E\u4E48\u628A z-index\r\n * \u5199\u6210 9998 \u4E5F**\u9003\u4E0D\u51FA\u53BB**\uFF0C\u6C38\u8FDC\u6392\u5728\u8BBE\u7F6E\u5F39\u7A97\uFF081000\uFF09\u4E0B\u9762\uFF0C\u88AB\u5168\u5C4F\u906E\u7F69\u5403\u6389\u9F20\u6807\u3002\r\n * \u6240\u4EE5\uFF1A**\u51E1\u662F\u7ED9\u8BBE\u7F6E\u5F39\u7A97\u505A\u6D6E\u5C42\uFF0C\u5FC5\u987B\u628A\u624B\u67C4\u6302\u8FDB\u9762\u677F\u5185\u90E8**\uFF08`createPortal` \u5230\r\n * panel\uFF09\uFF0C\u800C\u4E0D\u662F\u5728 shell.overlay \u91CC\u5BF9\u51C6\u5750\u6807\u753B\u3002\r\n */\r\nimport type { CSSProperties } from 'react'\r\n\r\n/** \u8BBE\u7F6E\u5BF9\u8BDD\u6846\u9009\u62E9\u5668\uFF08\u9762\u677F\u4E3A\u300C\u5E26 nav \u5B50\u5143\u7D20\u7684 aria-modal \u5BF9\u8BDD\u6846\u300D\uFF0C\u5728\u5E94\u7528\r\n * \u91CC\u552F\u4E00\uFF1A\u5176\u5B83\u5BF9\u8BDD\u6846\uFF08\u5BA1\u6279\u3001\u6A21\u578B\u7F16\u8F91\u5668\u7B49\uFF09\u4E0D\u4EE5 nav \u4E3A\u76F4\u63A5\u5B50\u5143\u7D20\uFF09\u3002 */\r\nexport const PANEL_SELECTOR = '[role=\"dialog\"][aria-modal=\"true\"]:has(> nav)'\r\n\r\n\r\n/** \u624B\u67C4\u5C42\u7C7B\u540D\uFF08\u7531\u4E0B\u65B9\u6CE8\u5165\u6837\u5F0F\u8868\u5B9A\u4E49\uFF09\u3002 */\r\nexport const RESIZE_LAYER_CLASS = 'dsh-ux-resize-layer'\r\n/** \u56DB\u8FB9\u63CF\u8FB9\uFF08\u7EAF\u89C6\u89C9\uFF0C\u4E0D\u5403\u6307\u9488\uFF09\u3002 */\r\nexport const RESIZE_OUTLINE_CLASS = 'dsh-ux-resize-outline'\r\n/** \u53EF\u62D6\u62FD\u7684\u8FB9\u3002 */\r\nexport const RESIZE_EDGE_CLASS = 'dsh-ux-resize-edge'\r\n/** \u53EF\u62D6\u62FD\u7684\u53F3\u4E0B\u89D2\u6293\u624B\u3002 */\r\nexport const RESIZE_GRIP_CLASS = 'dsh-ux-resize-grip'\r\n\r\n/** \u53EF\u62D6\u62FD\u7684\u4F4D\u7F6E\u3002 */\r\nexport type ResizeEdge = 'left' | 'right' | 'top' | 'bottom' | 'br'\r\n\r\n/** \u8FB9\u7684\u6293\u53D6\u5E26\u5BBD\uFF08\u53EF\u89C1\u63CF\u8FB9\u662F 1px\uFF0C\u8FD9 8px \u662F\"\u597D\u6293\"\u7684\u4F59\u91CF\uFF09\u3002 */\r\nconst BAND = 8\r\n/** \u8FB9\u6761\u4E24\u7AEF\u907F\u8BA9\u91CF\uFF0C\u8BA9\u5706\u89D2\u5904\u4E0D\u51FA\u73B0\u538B\u7EBF\u7684\u76F4\u89D2\u3002 */\r\nconst INSET = 14\r\n/** \u53F3\u4E0B\u89D2\u6293\u624B\u5C3A\u5BF8\u3002 */\r\nconst GRIP = 26\r\n\r\n/**\r\n * \u4E00\u6761\u624B\u67C4\u5728**\u9762\u677F\u5185\u90E8**\u7684\u7EDD\u5BF9\u5B9A\u4F4D\u76D2\u3002\r\n *\r\n * \u523B\u610F\u4E0D\u4F7F\u7528\u89C6\u53E3\u5750\u6807\uFF1A\u624B\u67C4\u662F\u9762\u677F\u7684\u5B50\u5143\u7D20\uFF08\u6302\u8FDB\u9762\u677F\u5185\u90E8\uFF09\uFF0C\u6240\u4EE5\u5B9A\u4F4D\u5168\u90E8\u76F8\u5BF9\r\n * \u9762\u677F\u672C\u8EAB \u2014\u2014 \u9762\u677F\u79FB\u52A8\u3001\u6EDA\u52A8\u3001\u6539\u5C3A\u5BF8\u90FD\u4F1A\u81EA\u52A8\u8DDF\u968F\uFF0C\u4E0D\u9700\u8981\u4EFB\u4F55\u91CD\u7B97\u6216\u8F6E\u8BE2\u3002\r\n * @param edge - \u8FB9\u6216\u53F3\u4E0B\u89D2\u3002\r\n * @returns \u8BE5\u624B\u67C4\u7684 CSS \u5B9A\u4F4D\u5C5E\u6027\u3002\r\n */\r\nexport function handleBox(edge: ResizeEdge): CSSProperties {\r\n switch (edge) {\r\n case 'left': return { left: 0, top: INSET, bottom: INSET, width: BAND, cursor: 'ew-resize' }\r\n case 'right': return { right: 0, top: INSET, bottom: INSET, width: BAND, cursor: 'ew-resize' }\r\n case 'top': return { top: 0, left: INSET, right: INSET, height: BAND, cursor: 'ns-resize' }\r\n case 'bottom': return { bottom: 0, left: INSET, right: INSET, height: BAND, cursor: 'ns-resize' }\r\n case 'br': return { right: 8, bottom: 8, width: GRIP, height: GRIP, cursor: 'nwse-resize' }\r\n }\r\n}\r\n\r\n/** \u56DB\u8FB9\u63CF\u8FB9\u5C42\uFF1A\u8D34\u7740\u9762\u677F\u5706\u89D2\u753B\u4E00\u5708 1px \u7EC6\u7EBF\uFF08\u7EAF\u89C6\u89C9\uFF0C`pointer-events: none`\uFF09\u3002 */\r\nexport const RESIZE_OUTLINE_STYLE: CSSProperties = {\r\n position: 'absolute',\r\n inset: 0,\r\n // \u8DDF\u968F\u9762\u677F\u81EA\u8EAB\u7684\u5706\u89D2\uFF08\u5B98\u65B9 .panel \u662F 32px\uFF09\u2014\u2014\u7528 inherit \u800C\u4E0D\u662F\u5199\u6B7B\u6570\u5B57\uFF0C\r\n // \u5B98\u65B9\u6539\u5706\u89D2\u65F6\u8FD9\u91CC\u81EA\u52A8\u8DDF\u4E0A\u3002\r\n borderRadius: 'inherit',\r\n border: '1px solid rgba(127, 127, 137, .28)',\r\n pointerEvents: 'none',\r\n}\r\n\r\n/** \u6CE8\u5165\u7684\u6EDA\u52A8\u6837\u5F0F\uFF08\u7531 html.dsh-ux-panel-scroll \u95E8\u63A7\uFF09\u3002 */\r\nconst PANEL_CSS = `\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) { min-height: 320px; }\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav {\r\n min-height: 0;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child {\r\n flex: 1 1 auto;\r\n min-height: 0;\r\n overflow-y: auto;\r\n overscroll-behavior: contain;\r\n scrollbar-width: thin;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar {\r\n width: 8px;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb {\r\n background: var(--dsh-scrollbar-thumb, var(--dsw-alias-scrollbar-bg-l2));\r\n border-radius: 8px;\r\n}\r\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb:hover {\r\n background: var(--dsh-scrollbar-thumb-hover, var(--dsw-alias-scrollbar-hover-l2));\r\n}\r\n`\r\n\r\n/**\r\n * \u5C3A\u5BF8\u624B\u67C4\u6837\u5F0F\u3002\r\n *\r\n * \u624B\u67C4\u5C42\u6302\u5728**\u8BBE\u7F6E\u9762\u677F\u5185\u90E8**\uFF08\u89C1\u6587\u4EF6\u5934\u7684\u5C42\u53E0\u4E0A\u4E0B\u6587\u8BF4\u660E\uFF09\uFF0C\u6240\u4EE5\u8FD9\u4E9B\u89C4\u5219\u91CC\u7684\r\n * \u5B9A\u4F4D\u4E00\u5F8B\u76F8\u5BF9\u9762\u677F\uFF1B`pointer-events` \u5728\u5C42\u4E0A\u5173\u6389\u3001\u53EA\u5728\u5177\u4F53\u624B\u67C4\u4E0A\u6253\u5F00\uFF0C\r\n * \u514D\u5F97\u6574\u5C42\u5403\u6389\u9762\u677F\u672C\u8EAB\u7684\u70B9\u51FB\u3002\r\n */\r\nconst RESIZE_CSS = `\r\n.${RESIZE_LAYER_CLASS} { position: absolute; inset: 0; pointer-events: none; }\r\n.${RESIZE_EDGE_CLASS}, .${RESIZE_GRIP_CLASS} {\r\n position: absolute;\r\n pointer-events: auto;\r\n background: transparent;\r\n border-radius: 6px;\r\n transition: background-color .12s ease, color .12s ease;\r\n touch-action: none;\r\n}\r\n.${RESIZE_EDGE_CLASS}:hover { background: rgba(127, 127, 137, .22); }\r\n.${RESIZE_EDGE_CLASS}[data-active=\"true\"] { background: rgba(127, 127, 137, .3); }\r\n.${RESIZE_GRIP_CLASS} {\r\n display: flex;\r\n align-items: flex-end;\r\n justify-content: flex-end;\r\n padding: 3px;\r\n color: rgba(127, 127, 137, .55);\r\n}\r\n.${RESIZE_GRIP_CLASS}:hover { color: rgba(127, 127, 137, .95); background: rgba(127, 127, 137, .16); }\r\n`\r\n\r\n/** \u6CE8\u5165\u6837\u5F0F\u8868\u9A71\u52A8\u6EDA\u52A8\u5F00\u5173\uFF08\u968F\u8BBE\u7F6E\u53D8\u5316\u5373\u65F6\u66F4\u65B0\uFF09\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\u3002 */\r\nexport function installPanelStyle(\r\n settings: () => boolean,\r\n subscribe: (listener: () => void) => () => void,\r\n): () => void {\r\n const tag = document.createElement('style')\r\n tag.dataset.plugin = 'dsh-composer-ux-panel'\r\n tag.textContent = `${PANEL_CSS}\\n${RESIZE_CSS}`\r\n document.head.appendChild(tag)\r\n const applyClass = (): void => {\r\n document.documentElement.classList.toggle('dsh-ux-panel-scroll', settings())\r\n }\r\n applyClass()\r\n const unsubscribe = subscribe(applyClass)\r\n return () => {\r\n unsubscribe()\r\n tag.remove()\r\n document.documentElement.classList.remove('dsh-ux-panel-scroll')\r\n }\r\n}\r\n\r\n/** \u67E5\u8BE2\u5F53\u524D\u6253\u5F00\u7684\u8BBE\u7F6E\u5BF9\u8BDD\u6846\u3002 */\r\nexport function findSettingsPanel(): HTMLElement | null {\r\n return document.querySelector<HTMLElement>(PANEL_SELECTOR)\r\n}\r\n\r\n/** \u5C3A\u5BF8\u8303\u56F4\u94B3\u5236\uFF08\u4E0E host schema \u4E00\u81F4\uFF09\u3002 */\r\nexport function clampPanelWidth(width: number): number {\r\n return Math.max(560, Math.min(width, Math.max(800, window.innerWidth - 48)))\r\n}\r\n\r\nexport function clampPanelHeight(height: number): number {\r\n return Math.max(320, Math.min(height, Math.max(400, window.innerHeight - 48)))\r\n}\r\n\r\n/** \u6301\u4E45\u5316\u5C3A\u5BF8\uFF08\u5199\u5165\u8BBE\u7F6E\uFF1B\u5931\u8D25\u9759\u9ED8\u2014\u2014\u4E0B\u6B21\u6253\u5F00\u56DE\u9000\u9ED8\u8BA4\uFF09\u3002 */\r\nexport function persistPanelSize(\r\n width: number,\r\n height: number,\r\n setField: (field: string, value: boolean | number) => void,\r\n): void {\r\n setField('panelWidth', clampPanelWidth(width))\r\n setField('panelHeight', clampPanelHeight(height))\r\n}\r\n", "/**\n * \u8BBE\u7F6E\u9875\u6298\u53E0\u5361\u7247\u6837\u5F0F\u3002\n *\n * \u89C2\u611F\u5BF9\u9F50\u793E\u533A\u63D2\u4EF6 @linxin666/dsh-web-all \u7684 SettingsCard\uFF1A12px \u5706\u89D2\u3001\n * 1px \u63CF\u8FB9\uFF08hover \u53D8 --dsw-alias-label-dimmed\uFF09\u3001\u5C55\u5F00\u65F6\u6362\u5E95\u8272\u5E76\u663E\u793A\u5206\u9694\u7EBF\u3001\n * \u53F3\u4FA7 chevron \u65CB\u8F6C 180\u00B0\u3002\u7C7B\u540D\u7EDF\u4E00 dsh-ux- \u524D\u7F00\uFF0C\u907F\u514D\u4E0E\u5BBF\u4E3B CSS Modules \u51B2\u7A81\u3002\n */\n\nconst CARD_CSS = `\n.dsh-ux-card {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 12px;\n margin-bottom: 12px;\n transition: border-color .16s, background .16s;\n}\n.dsh-ux-card:hover { border-color: var(--dsw-alias-label-dimmed); }\n.dsh-ux-cardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dsh-ux-cardHeader {\n appearance: none;\n box-sizing: border-box;\n width: 100%;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: 0 0;\n border: 0;\n border-radius: 12px;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n}\n.dsh-ux-cardHeader:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.dsh-ux-cardHeaderStatic {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n}\n.dsh-ux-cardHeadText {\n display: flex;\n flex-direction: column;\n flex: 1;\n gap: 4px;\n min-width: 0;\n}\n.dsh-ux-cardName {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n margin: 0;\n}\n.dsh-ux-cardDescription {\n color: var(--dsw-alias-label-secondary);\n font-size: 13px;\n line-height: 1.5;\n margin: 0;\n}\n.dsh-ux-cardChevron {\n color: var(--dsw-alias-label-tertiary);\n flex: none;\n transition: transform .16s;\n}\n.dsh-ux-cardChevronOpen { transform: rotate(180deg); }\n.dsh-ux-cardBody {\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin: 0 16px;\n padding-bottom: 8px;\n}\n`\n\n/** \u6CE8\u5165\u5361\u7247\u6837\u5F0F\u8868\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\uFF08\u968F\u63D2\u4EF6 fiber \u56DE\u6536\uFF09\u3002 */\nexport function installSettingsCardStyle(): () => void {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-composer-ux-settings'\n tag.textContent = CARD_CSS\n document.head.appendChild(tag)\n return () => { tag.remove() }\n}\n", "/**\n * \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\u7684\u6837\u5F0F\u8868\u3002\n *\n * \u4E3A\u4EC0\u4E48\u4E0D\u7528\u884C\u5185\u6837\u5F0F\uFF08React `style`\uFF09\uFF1A\u5B83\u8868\u8FBE\u4E0D\u4E86 `:hover` / `[aria-expanded]`\n * \u8FD9\u7C7B\u72B6\u6001\uFF0C\u800C\u300C\u548C\u65C1\u8FB9\u7684\u5B98\u65B9\u6309\u94AE\u957F\u5F97\u4E00\u6837\u300D\u6070\u6070\u8981\u9760 hover \u4E0E\u5E38\u6001\u900F\u660E\u5EA6\u3002\n *\n * \u53C2\u6570\u9010\u9879\u5BF9\u9F50\u793E\u533A\u63D2\u4EF6 `dsh-composer-expand` \u7684 `.cpex-btn`\uFF08\u540C\u4E00\u4E2A\u69FD\u4F4D\n * `conversation.input.right`\u3001\u540C\u4E00\u4E2A order \u90BB\u4F4D\uFF09\u2014\u2014 \u4E24\u4E2A\u6309\u94AE\u5E76\u6392\uFF0C\u5FC5\u987B\u540C\u9AD8\u3001\n * \u540C\u5706\u89D2\u3001\u540C\u5185\u8FB9\u8DDD\u3001\u540C\u8FB9\u6846\u3001\u540C\u5E38\u6001\u900F\u660E\u5EA6\uFF0C\u5426\u5219\u4E00\u773C\u5C31\u770B\u5F97\u51FA\u662F\u4E24\u5BB6\u4EBA\u505A\u7684\u3002\n * \u7279\u522B\u8BB0\u4E00\u7B14\uFF1A\u8FB9\u6846**\u4E0D\u7528**\u4E3B\u9898\u4EE4\u724C `--dsw-alias-border-l2`\uFF08\u5B83\u66F4\u4EAE\uFF0C\u4F1A\u5448\u73B0\u6210\n * \u7528\u6237\u622A\u56FE\u91CC\u90A3\u5708\u7A81\u5140\u7684\u767D\u7EBF\uFF09\uFF0C\u800C\u662F\u548C\u5BF9\u65B9\u4E00\u6837\u7528\u4E2D\u6027\u534A\u900F\u660E\u7070\uFF0C\u660E\u6697\u4E3B\u9898\u4E0B\u90FD\u534F\u8C03\u3002\n */\n\n/** \u5165\u53E3\u6309\u94AE\u7684\u57FA\u7840\u7C7B\u540D\u3002 */\nexport const QUICK_BUTTON_CLASS = 'composer-ux-quick-button'\n\n/** \u4E0E .cpex-btn \u9010\u9879\u5BF9\u9F50\u3002 */\nconst QUICK_BUTTON_CSS = `\n.${QUICK_BUTTON_CLASS} {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 24px;\n border: 1px solid rgba(127, 127, 137, .35);\n background: transparent;\n color: inherit;\n border-radius: 999px;\n padding: 0 9px;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n opacity: .75;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n transition: opacity .12s ease, background-color .12s ease;\n}\n.${QUICK_BUTTON_CLASS}:hover { opacity: 1; background: rgba(127, 127, 137, .12); }\n.${QUICK_BUTTON_CLASS}[aria-expanded=\"true\"] {\n opacity: 1;\n background: rgba(127, 127, 137, .18);\n border-color: rgba(127, 127, 137, .6);\n}\n.${QUICK_BUTTON_CLASS} svg { flex: 0 0 auto; }\n`\n\n/** \u6CE8\u5165\u5165\u53E3\u6309\u94AE\u6837\u5F0F\u8868\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\uFF08\u968F\u63D2\u4EF6 fiber \u56DE\u6536\uFF09\u3002 */\nexport function installQuickButtonStyle(): () => void {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-composer-ux-quick-button'\n tag.textContent = QUICK_BUTTON_CSS\n document.head.appendChild(tag)\n return () => { tag.remove() }\n}\n", "/**\n * \u53F3\u952E\u83DC\u5355\u5BBF\u4E3B\uFF1A\u6CE8\u518C\u8FDB shell.overlay\uFF08root \u7EA7 list \u69FD\uFF09\uFF0C\u83DC\u5355\u6253\u5F00\u65F6\u6E32\u67D3\n * \u4E00\u4E2A fixed \u5B9A\u4F4D\u7684\u6D6E\u5C42\uFF1B\u5173\u95ED\u65F6\u6E32\u67D3 null\u3002\n */\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n MENU_ITEMS, type ComposerUxSettings, type MenuState, type MenuField,\n} from '../settings-contract.ts'\nimport type { MenuActionId } from './interceptors.ts'\nimport { menu, menuItem, menuItemDim, menuNote, menuSeparator, menuShortcut } from './styles.ts'\n\n/** \u53F3\u952E\u83DC\u5355\u6CE8\u5165\u9762\u3002 */\nexport interface ContextMenuInjected {\n hooks: {\n /** \u83DC\u5355\u6253\u5F00\u72B6\u6001\uFF08null = \u5173\u95ED\uFF09\u3002 */\n menu: SnapshotStore<MenuState | null>\n /** \u5F53\u524D\u8BBE\u7F6E\uFF08\u51B3\u5B9A\u54EA\u4E9B\u83DC\u5355\u9879\u542F\u7528\uFF09\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n }\n actions: {\n /** \u6267\u884C\u4E00\u4E2A\u83DC\u5355\u52A8\u4F5C\uFF1Bresolve \u6210\u529F\u4E0E\u5426\u3002 */\n run: (id: MenuActionId) => Promise<{ ok: boolean; message?: string }>\n /** \u5173\u95ED\u83DC\u5355\u3002 */\n close: () => void\n /** \u5728\u83DC\u5355\u4E0A\u6302\u4E00\u6BB5\u77ED\u6682\u63D0\u793A\uFF08\u4FDD\u7559\u83DC\u5355\u6253\u5F00\uFF09\u3002 */\n note: (message: string | undefined) => void\n }\n}\n\nexport type ContextMenuHostProps =\n PropsRuntime<'shell.overlay'>\n & InjectFace<ContextMenuInjected>\n\n/** \u83DC\u5355\u7EC4\uFF1A\u4E0E\u56FE\u7247\u4E00\u81F4\u7684\u4E09\u7EC4\u5206\u9694\u5E03\u5C40\u3002 */\nconst GROUPS: readonly { readonly label: string; readonly shortcut: string; readonly field: MenuField; readonly id: MenuActionId | 'disabledOnly' }[][] = [\n [\n { label: '\u64A4\u9500', shortcut: 'Ctrl+Z', field: 'menuUndo', id: 'undo' },\n { label: '\u91CD\u505A', shortcut: 'Ctrl+Y', field: 'menuRedo', id: 'redo' },\n ],\n [\n { label: '\u526A\u5207', shortcut: 'Ctrl+X', field: 'menuCut', id: 'cut' },\n { label: '\u590D\u5236', shortcut: 'Ctrl+C', field: 'menuCopy', id: 'copy' },\n { label: '\u7C98\u8D34', shortcut: 'Ctrl+V', field: 'menuPaste', id: 'paste' },\n { label: '\u5220\u9664', shortcut: '', field: 'menuDelete', id: 'delete' },\n ],\n [\n { label: '\u5168\u9009', shortcut: 'Ctrl+A', field: 'menuSelectAll', id: 'selectAll' },\n ],\n]\n\nconst ITEM_STYLES: Record<MenuActionId, 'always' | 'selection'> = {\n undo: 'always',\n redo: 'always',\n cut: 'selection',\n copy: 'selection',\n paste: 'always',\n delete: 'selection',\n selectAll: 'always',\n}\n\n/** \u4E0E\u89C6\u53E3\u8FB9\u754C\u4FDD\u6301 8px\u3002 */\nfunction clamp(value: number, size: number, viewport: number): number {\n return Math.max(8, Math.min(value, viewport - size - 8))\n}\n\n/** \u6E32\u67D3\u53F3\u952E\u83DC\u5355\uFF1B\u65E0\u83DC\u5355\u65F6\u8FD4\u56DE null\u3002 */\nexport function ContextMenuHost({ useMenu, useLive, actions }: ContextMenuHostProps) {\n const menuState = useMenu(item => item)\n const settings = useLive(item => item)\n const ref = useRef<HTMLDivElement | null>(null)\n const [position, setPosition] = useState<{ x: number; y: number } | null>(null)\n\n // \u6253\u5F00\u540E\u6309\u5B9E\u9645\u5C3A\u5BF8\u94B3\u5236\u5728\u89C6\u53E3\u5185\u3002\n useLayoutEffect(() => {\n if (menuState === null) {\n setPosition(null)\n return\n }\n const el = ref.current\n if (el === null) return\n const rect = el.getBoundingClientRect()\n setPosition({\n x: clamp(menuState.x, rect.width, window.innerWidth),\n y: clamp(menuState.y, rect.height, window.innerHeight),\n })\n }, [menuState?.x, menuState?.y])\n\n // \u5916\u90E8\u70B9\u51FB / Escape / \u6EDA\u52A8 / \u7A97\u53E3\u53D8\u5316\u65F6\u5173\u95ED\u3002\n useEffect(() => {\n if (menuState === null) return\n const onPointerDown = (event: PointerEvent): void => {\n if (ref.current !== null && event.target instanceof Node && ref.current.contains(event.target)) return\n actions.close()\n }\n const onEscape = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n event.preventDefault()\n event.stopPropagation()\n actions.close()\n }\n window.addEventListener('pointerdown', onPointerDown, true)\n window.addEventListener('keydown', onEscape, true)\n window.addEventListener('scroll', actions.close, true)\n window.addEventListener('resize', actions.close)\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, true)\n window.removeEventListener('keydown', onEscape, true)\n window.removeEventListener('scroll', actions.close, true)\n window.removeEventListener('resize', actions.close)\n }\n }, [menuState === null, actions])\n\n // \u63D0\u793A 3 \u79D2\u540E\u6E05\u9664\u3002\n useEffect(() => {\n if (menuState?.note === undefined) return\n const timer = setTimeout(() => { actions.note(undefined) }, 3000)\n return () => { clearTimeout(timer) }\n }, [menuState?.note])\n\n if (menuState === null) return null\n\n const onItemClick = (id: MenuActionId): void => {\n // \u7C98\u8D34\u82E5\u7F13\u5B58\u672A\u547D\u4E2D\u4F1A\u5B9E\u65F6\u8BFB\u53D6\u526A\u8D34\u677F\uFF0C\u53EF\u80FD\u77ED\u6682\u7B49\u5F85\u6388\u6743\uFF0C\u7ED9\u51FA\u8FDB\u884C\u4E2D\u53CD\u9988\u3002\n if (id === 'paste') actions.note('\u6B63\u5728\u8BFB\u53D6\u526A\u8D34\u677F\u2026')\n // \u4E0D\u8BA9\u6309\u94AE\u62A2\u8D70\u7126\u70B9\uFF0C\u4FDD\u7559\u8F93\u5165\u6846\u9009\u533A\u3002\n void actions.run(id).then((result) => {\n if (result.ok) actions.close()\n else actions.note(result.message ?? '\u64CD\u4F5C\u5931\u8D25')\n })\n }\n\n const groups = GROUPS\n .map(group => group.filter(item => settings[item.field] === true))\n .filter(group => group.length > 0)\n\n return (\n <div\n ref={ref}\n role=\"menu\"\n style={{\n ...menu,\n left: position?.x ?? menuState.x,\n top: position?.y ?? menuState.y,\n }}\n >\n {groups.map((group, groupIndex) => (\n <React.Fragment key={group[0]!.field}>\n {groupIndex > 0 && <div role=\"separator\" style={menuSeparator} />}\n {group.map(item => {\n const needsSelection = ITEM_STYLES[item.id] === 'selection'\n const disabled = needsSelection && !menuState.hasSelection\n const style = disabled ? menuItemDim : menuItem\n return (\n <button\n key={item.field}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n style={style}\n onMouseDown={(event) => { event.preventDefault() }}\n onClick={() => { onItemClick(item.id) }}\n >\n <span>{item.label}</span>\n {item.shortcut !== '' && <span style={menuShortcut}>{item.shortcut}</span>}\n </button>\n )\n })}\n </React.Fragment>\n ))}\n {menuState.note !== undefined && <div style={menuNote}>{menuState.note}</div>}\n </div>\n )\n}\n", "/**\n * \u5185\u8054\u6837\u5F0F\u5DE5\u5177\uFF1A\u53EA\u4F7F\u7528 DSH Web \u7684 --dsw-* \u8BBE\u8BA1\u4EE4\u724C\uFF0C\u6DF1\u6D45\u4E3B\u9898\u81EA\u9002\u5E94\u3002\n */\nimport type { CSSProperties } from 'react'\n\n/** \u9875\u9762\u5361\u7247\u3002 */\nexport const card: CSSProperties = {\n background: 'var(--dsw-alias-bg-layer-2)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n padding: '14px 16px',\n marginBottom: 12,\n}\n\n/** \u5361\u7247\u6807\u9898\u3002 */\nexport const cardTitle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 14,\n fontWeight: 600,\n margin: '0 0 4px',\n}\n\n/** \u8BF4\u660E\u6587\u5B57\u3002 */\nexport const description: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 12,\n lineHeight: 1.6,\n margin: '0 0 12px',\n}\n\n/** \u8BBE\u7F6E\u884C\u3002 */\nexport const row: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n minHeight: 40,\n padding: '7px 0',\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n}\n\n/** \u884C\u5185\u6807\u7B7E\u533A\u3002 */\nexport const rowText: CSSProperties = {\n minWidth: 0,\n flex: 1,\n}\n\n/** \u884C\u6807\u9898\u3002 */\nexport const rowTitle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 13,\n lineHeight: 1.4,\n}\n\n/** \u884C\u8BF4\u660E\u3002 */\nexport const rowDesc: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1.4,\n marginTop: 2,\n}\n\n/** \u952E\u4F4D\u663E\u793A\u80F6\u56CA\u3002 */\nexport const kbd: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 6,\n padding: '3px 8px',\n fontSize: 12,\n fontFamily: 'var(--dsw-font-family)',\n whiteSpace: 'nowrap',\n}\n\n/** \u9884\u8BBE/\u52A8\u4F5C\u5C0F\u6309\u94AE\u3002 */\nexport const pill: CSSProperties = {\n background: 'var(--dsw-alias-interactive-bg-hover)',\n color: 'var(--dsw-alias-label-secondary)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 999,\n padding: '4px 10px',\n fontSize: 12,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n}\n\n/** \u9009\u4E2D\u6001\u6309\u94AE\u3002 */\nexport const pillActive: CSSProperties = {\n ...pill,\n color: 'var(--dsw-alias-button-primary-fill)',\n borderColor: 'var(--dsw-alias-button-primary-fill)',\n}\n\n/** \u5355\u884C\u6587\u672C\u8F93\u5165\uFF08\u8DDF\u968F\u4E3B\u9898\u4EE4\u724C\uFF09\u3002 */\nexport const textInput: CSSProperties = {\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n borderRadius: 8,\n padding: '6px 9px',\n fontSize: 12,\n lineHeight: 1.4,\n width: '100%',\n minWidth: 0,\n boxSizing: 'border-box',\n flex: 1,\n}\n\n/** \u63D0\u793A/\u9519\u8BEF\u6587\u5B57\u3002 */\nexport const hintError: CSSProperties = {\n color: 'var(--dsw-alias-state-error-primary)',\n fontSize: 12,\n lineHeight: 1.5,\n margin: '6px 0 0',\n}\n\n/** \u63D0\u793A\u6587\u5B57\uFF08\u4E2D\u6027\uFF09\u3002 */\nexport const hintInfo: CSSProperties = {\n color: 'var(--dsw-alias-label-secondary)',\n fontSize: 12,\n lineHeight: 1.5,\n margin: '6px 0 0',\n}\n\n/** \u83DC\u5355\uFF08\u4E0E\u56FE\u7247\u4E00\u81F4\u7684\u6DF1\u8272\u5706\u89D2\u83DC\u5355\uFF09\uFF1B\u80CC\u666F\u53D6\u81EA\u5B98\u65B9\u83DC\u5355\u4EE4\u724C\u3002 */\nexport const menu: CSSProperties = {\n position: 'fixed',\n zIndex: 9999,\n minWidth: 200,\n background: 'var(--dsw-specific-menu)',\n border: '0.5px solid var(--dsw-alias-border-l1)',\n borderRadius: 10,\n boxShadow: 'var(--dsw-elevation-prominent)',\n padding: 5,\n pointerEvents: 'auto',\n userSelect: 'none',\n}\n\n/** \u83DC\u5355\u9879\u3002 */\nexport const menuItem: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 24,\n padding: '6px 10px',\n borderRadius: 6,\n fontSize: 13,\n color: 'var(--dsw-alias-label-primary)',\n cursor: 'pointer',\n background: 'transparent',\n border: 'none',\n width: '100%',\n textAlign: 'left',\n}\n\nexport const menuItemDim: CSSProperties = {\n ...menuItem,\n color: 'var(--dsw-alias-label-dimmed)',\n cursor: 'default',\n}\n\n/** \u83DC\u5355\u9879\u5FEB\u6377\u952E\u3002 */\nexport const menuShortcut: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 12,\n fontFamily: 'var(--dsw-font-family)',\n}\n\n/** \u83DC\u5355\u5206\u9694\u7EBF\u3002 */\nexport const menuSeparator: CSSProperties = {\n height: 0,\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n margin: '4px 8px',\n}\n\n/** \u83DC\u5355\u5E95\u90E8\u63D0\u793A\u3002 */\nexport const menuNote: CSSProperties = {\n color: 'var(--dsw-alias-state-warn-label)',\n fontSize: 11,\n lineHeight: 1.4,\n padding: '4px 10px 2px',\n}\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\uFF1A\u8F93\u5165\u5361\u7247\u91CC\u7684\u5165\u53E3\u6309\u94AE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// \u6309\u94AE\u6837\u5F0F**\u6545\u610F\u4E0D\u653E\u5728\u8FD9\u91CC**\uFF1A\u5B83\u9700\u8981 hover \u4E0E\u5C55\u5F00\u6001\uFF0C\u884C\u5185\u6837\u5F0F\u8868\u8FBE\u4E0D\u4E86\uFF0C\u800C\u4E14\n// \u8981\u4E0E\u65C1\u8FB9\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\uFF08dsh-composer-expand \u7684 .cpex-btn\uFF09\u9010\u9879\u5BF9\u9F50\u3002\n// \u89C1 `quick-style.ts` \u7684\u6CE8\u5165\u6837\u5F0F\u8868\u3002\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\uFF1A\u5C55\u5F00\u9762\u677F \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** \u9762\u677F\u5BB9\u5668\uFF08fixed \u5B9A\u4F4D\uFF0C\u951A\u70B9\u5728\u5165\u53E3\u6309\u94AE\u4E0A\u65B9\uFF09\u3002 */\nexport const quickPanel: CSSProperties = {\n position: 'fixed',\n zIndex: 9999,\n width: 420,\n maxWidth: 'calc(100vw - 24px)',\n maxHeight: 'min(60vh, 520px)',\n display: 'flex',\n flexDirection: 'column',\n background: 'var(--dsw-specific-menu)',\n border: '0.5px solid var(--dsw-alias-border-l1)',\n borderRadius: 12,\n boxShadow: 'var(--dsw-elevation-prominent)',\n pointerEvents: 'auto',\n overflow: 'hidden',\n}\n\n/** \u9762\u677F\u9876\u90E8\u533A\uFF08\u6807\u9898 + \u6863\u4F4D + \u4F18\u5316\u6309\u94AE\uFF09\u3002 */\nexport const quickPanelHead: CSSProperties = {\n padding: '10px 12px 8px',\n borderBottom: '0.5px solid var(--dsw-alias-border-l2)',\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n}\n\n/** \u9762\u677F\u6807\u9898\u884C\u3002 */\nexport const quickPanelTitleRow: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n}\n\n/** \u9762\u677F\u6807\u9898\u3002 */\nexport const quickPanelTitle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 13,\n fontWeight: 600,\n}\n\n/** \u6863\u4F4D\u5206\u6BB5\u63A7\u4EF6\u3002 */\nexport const quickTierRow: CSSProperties = {\n display: 'inline-flex',\n gap: 2,\n padding: 2,\n borderRadius: 999,\n background: 'var(--dsw-alias-bg-layer-1)',\n border: '0.5px solid var(--dsw-alias-border-l2)',\n}\n\n/** \u5355\u4E2A\u6863\u4F4D\u6309\u94AE\u3002 */\nexport const quickTierButton: CSSProperties = {\n border: 'none',\n background: 'transparent',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n padding: '4px 8px',\n borderRadius: 999,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n}\n\n/** \u9009\u4E2D\u6863\u4F4D\u3002\n * \u524D\u666F\u5FC5\u987B\u7528\u914D\u5BF9\u4EE4\u724C `label-primary-foreground`\uFF1A`button-primary-fill` \u53D6\u81EA\n * `brand-primary`\uFF0C\u6D45\u8272\u4E3B\u9898\u4E0B\u662F\u58A8\u8272/\u6DF1\u8272\uFF0C**\u6DF1\u8272\u4E3B\u9898\u4E0B\u5B83\u662F\u767D**\u2014\u2014\u6B64\u65F6\u5199\u6B7B\n * `#fff` \u5C31\u662F\u767D\u5E95\u767D\u5B57\uFF080.2.0 \u771F\u8E29\u8FC7\uFF09\u3002\u5B98\u65B9 ui-primitives/Button \u7684\u6210\u5BF9\u5199\u6CD5\n * \u5C31\u662F fill + label-primary-foreground\u3002 */\nexport const quickTierButtonActive: CSSProperties = {\n ...quickTierButton,\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n}\n\n/** \u4E3B\u884C\u52A8\u6309\u94AE\uFF08\u4F18\u5316\u63D0\u793A\u8BCD\uFF09\u3002\u540C\u4E0A\uFF1Afill \u4E0E\u524D\u666F\u5FC5\u987B\u6210\u5BF9\u3002 */\nexport const quickPrimaryButton: CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 6,\n width: '100%',\n padding: '7px 12px',\n borderRadius: 8,\n border: '0.5px solid var(--dsw-alias-button-primary-fill)',\n background: 'var(--dsw-alias-button-primary-fill)',\n color: 'var(--dsw-alias-label-primary-foreground)',\n fontSize: 12,\n cursor: 'pointer',\n}\n\n/** \u4E3B\u884C\u52A8\u6309\u94AE\uFF08\u4E0D\u53EF\u7528\uFF09\uFF1A\u4E0E\u5B98\u65B9 .primary:disabled \u4E00\u81F4\u7528 0.4\u3002 */\nexport const quickPrimaryButtonDisabled: CSSProperties = {\n ...quickPrimaryButton,\n opacity: 0.4,\n cursor: 'default',\n}\n\n/** \u6761\u76EE\u5217\u8868\u5BB9\u5668\uFF08\u53EF\u6EDA\u52A8\uFF09\u3002 */\nexport const quickList: CSSProperties = {\n overflowY: 'auto',\n padding: '6px 6px 8px',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n}\n\n/** \u4E00\u6761\u5FEB\u6377\u6307\u4EE4\u3002\n * \u6CE8\u610F\uFF1A\u8FD9\u4E00\u884C\u91CC\u8FD8\u6709\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u52FE\u9009\u6846\uFF0C\u6240\u4EE5\u6309\u94AE\u5FC5\u987B\u53EF\u88AB\u538B\u7F29\n * \uFF08flex 1 1 auto + minWidth 0\uFF09\uFF0C\u5426\u5219\u957F\u9884\u89C8\u4F1A\u628A\u52FE\u9009\u6846\u6324\u51FA\u9762\u677F\n * \uFF08width:100% \u4F1A\u5403\u6EE1\u6574\u884C\uFF0C0.2.0 \u771F\u8E29\u8FC7\uFF09\u3002 */\nexport const quickItem: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '5px 8px',\n borderRadius: 7,\n cursor: 'pointer',\n background: 'transparent',\n border: 'none',\n flex: '1 1 auto',\n minWidth: 0,\n textAlign: 'left',\n}\n\n/** \u6761\u76EE\u540D\u79F0\u3002 */\nexport const quickItemLabel: CSSProperties = {\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 12,\n flex: '0 0 auto',\n whiteSpace: 'nowrap',\n}\n\n/** \u6761\u76EE\u5185\u5BB9\u9884\u89C8\u3002 */\nexport const quickItemPreview: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n flex: '1 1 auto',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n}\n\n/** \u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u52FE\u9009\u533A\u3002 */\nexport const quickAlwaysLabel: CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n flex: '0 0 auto',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n whiteSpace: 'nowrap',\n cursor: 'pointer',\n}\n\n/** \u52FE\u9009\u6846\u3002 */\nexport const quickAlwaysBox: CSSProperties = {\n margin: 0,\n cursor: 'pointer',\n}\n\n/** \u9762\u677F\u5E95\u90E8\u63D0\u793A\u6761\u3002 */\nexport const quickPanelFoot: CSSProperties = {\n padding: '5px 12px 7px',\n borderTop: '0.5px solid var(--dsw-alias-border-l2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 8,\n}\n\n/** \u9762\u677F\u91CC\u7684\u63D0\u793A\u6587\u5B57\u3002 */\nexport const quickNotice: CSSProperties = {\n color: 'var(--dsw-alias-state-warn-label)',\n fontSize: 11,\n lineHeight: 1.4,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n}\n\n/** \u9762\u677F\u91CC\u7684\u6B21\u8981\u8BF4\u660E\u3002 */\nexport const quickFootHint: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n whiteSpace: 'nowrap',\n flex: '0 0 auto',\n}\n\n/** \u7A7A\u5217\u8868\u5360\u4F4D\u3002 */\nexport const quickEmpty: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 12,\n lineHeight: 1.6,\n padding: '14px 10px',\n textAlign: 'center',\n}\n\n// \u2500\u2500 \u5FEB\u6377\u6307\u4EE4\uFF1A\u5206\u7C7B\uFF080.3.0 \u8D77\u7684\u4E24\u7EA7\u7ED3\u6784\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** \u5206\u7C7B\u5207\u6362\u884C\uFF08\u9762\u677F\u91CC\u5728\u6863\u4F4D\u884C\u4E0B\u65B9\uFF09\u3002 */\nexport const quickCategoryRow: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n flexWrap: 'wrap',\n}\n\n/** \u5355\u4E2A\u5206\u7C7B\u6807\u7B7E\u3002 */\nexport const quickCategoryTab: CSSProperties = {\n border: '0.5px solid var(--dsw-alias-border-l2)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n padding: '4px 8px',\n borderRadius: 999,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n maxWidth: 160,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n}\n\n/** \u9009\u4E2D\u7684\u5206\u7C7B\u6807\u7B7E\u3002\n * \u53EA\u6539\u8FB9\u6846\u4E0E\u6587\u5B57\u8272\uFF0C**\u4E0D\u7528\u5B9E\u8272\u586B\u5145**\uFF1A\u8FD9\u6837\u4E0D\u9700\u8981\u586B/\u524D\u666F\u6210\u5BF9\u4EE4\u724C\uFF0C\n * \u4E5F\u5C31\u4E0D\u4F1A\u91CD\u6F14 0.2.0 \u90A3\u6B21\u300C\u6DF1\u8272\u4E3B\u9898\u767D\u5E95\u767D\u5B57\u300D\u3002 */\nexport const quickCategoryTabActive: CSSProperties = {\n ...quickCategoryTab,\n border: '0.5px solid var(--dsw-alias-brand-primary)',\n color: 'var(--dsw-alias-label-primary)',\n fontWeight: 600,\n}\n\n/** \u300C\uFF0B \u5206\u7C7B\u300D\u5C0F\u6309\u94AE\u3002 */\nexport const quickCategoryAdd: CSSProperties = {\n ...quickCategoryTab,\n color: 'var(--dsw-alias-label-tertiary)',\n padding: '4px 7px',\n cursor: 'pointer',\n}\n", "/**\n * \u8BBE\u7F6E\u9762\u677F\u5C3A\u5BF8\u624B\u67C4\uFF1A\u56DB\u8FB9\u53EF\u62D6 + \u53F3\u4E0B\u89D2\u6293\u624B\u3002\n *\n * **\u4E3A\u4EC0\u4E48\u7528 `createPortal` \u6302\u8FDB\u9762\u677F\u5185\u90E8\uFF0C\u800C\u4E0D\u662F\u5728 `shell.overlay` \u91CC\u5BF9\u51C6\u5750\u6807\u753B**\n * \uFF080.2.0 \u6574\u6BB5\u529F\u80FD\u5931\u6548\u7684\u539F\u56E0\uFF0C\u52A1\u5FC5\u522B\u6539\u56DE\u53BB\uFF09\uFF1A\n * `shell.overlay` \u88AB\u5B98\u65B9\u5C01\u5728 `ui-layout` \u7684\n * `.overlayLayer { position:absolute; inset:0; z-index:20 }` \u91CC\u3002`position` +\n * `z-index` \u8BA9\u5B83**\u81EA\u6210\u5C42\u53E0\u4E0A\u4E0B\u6587**\uFF0C\u91CC\u9762\u7684\u5143\u7D20\u65E0\u8BBA z-index \u5199\u591A\u5927\u90FD\u51FA\u4E0D\u53BB\uFF0C\n * \u6C38\u8FDC\u6392\u5728\u8BBE\u7F6E\u5F39\u7A97\uFF08`.overlay` z-index:1000\uFF09\u4E0B\u9762\uFF0C\u88AB\u5168\u5C4F\u906E\u7F69\n * \uFF08`.mask { position:absolute; inset:0 }`\uFF09\u5403\u6389\u9F20\u6807 \u21D2 \u624B\u67C4\u6839\u672C\u6293\u4E0D\u5230\u3002\n * \u6302\u8FDB\u9762\u677F\u5185\u90E8\u5C31\u5B8C\u5168\u4E0D\u9700\u8981\u6BD4\u5C42\u53E0\uFF1A\u5B83\u5728\u6700\u9AD8\u90A3\u4E00\u5C42\u7684**\u91CC\u9762**\u3002\n *\n * \u9644\u5E26\u597D\u5904\uFF1A\u5B9A\u4F4D\u7531\u300C\u89C6\u53E3\u5750\u6807 + \u8F6E\u8BE2\u91CD\u7B97\u300D\u53D8\u6210\u300C\u9762\u677F\u5185\u7684\u7EDD\u5BF9\u5B9A\u4F4D\u300D\uFF0C\u9762\u677F\u79FB\u52A8/\n * \u6EDA\u52A8/\u6539\u5C3A\u5BF8\u90FD\u81EA\u52A8\u8DDF\u968F\uFF0C\u4E0D\u518D\u9700\u8981 250ms \u7684\u77E9\u5F62\u91CD\u7B97\uFF08\u8F6E\u8BE2\u53EA\u7528\u6765\u53D1\u73B0\u9762\u677F\u51FA\u73B0\uFF09\u3002\n *\n * \u672C\u7EC4\u4EF6\u4ECD\u6CE8\u518C\u5728 `shell.overlay`\u2014\u2014\u5B83\u53EA\u662F**\u6E32\u67D3\u51FA\u53E3**\u5728\u90A3\u91CC\uFF08\u4E3A\u4E86\u62FF\u5230\n * `useLive` \u4E0E\u5199\u5165\u52A8\u4F5C\uFF09\uFF0C\u5B9E\u9645 DOM \u901A\u8FC7 portal \u843D\u5728\u9762\u677F\u5185\u3002\n */\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { PANEL_HEIGHT_FIELD, PANEL_WIDTH_FIELD, type ComposerUxSettings } from '../settings-contract.ts'\nimport {\n RESIZE_EDGE_CLASS, RESIZE_GRIP_CLASS, RESIZE_LAYER_CLASS, RESIZE_OUTLINE_CLASS,\n RESIZE_OUTLINE_STYLE, clampPanelHeight, clampPanelWidth, findSettingsPanel, handleBox,\n type ResizeEdge,\n} from './panel.ts'\n\nexport interface PanelResizeInjected {\n hooks: { live: SnapshotStore<ComposerUxSettings> }\n actions: {\n /** \u5199\u4E00\u4E2A\u5B57\u6BB5\uFF08boolean \u6216 number\uFF09\u3002 */\n setField: (field: string, value: boolean | number) => void\n }\n}\n\nexport type PanelResizeProps = PropsRuntime<'shell.overlay'> & InjectFace<PanelResizeInjected>\n\n/** \u62D6\u62FD\u8D77\u59CB\u72B6\u6001\uFF08move/up \u95ED\u5305\u5171\u4EAB\uFF09\u3002 */\ninterface DragStart {\n readonly edge: ResizeEdge\n readonly x: number\n readonly y: number\n readonly left: number\n readonly top: number\n readonly width: number\n readonly height: number\n}\n\n/** \u53EF\u62D6\u62FD\u7684\u56DB\u8FB9 + \u53F3\u4E0B\u89D2\u3002 */\nconst EDGES: readonly ResizeEdge[] = ['left', 'right', 'top', 'bottom', 'br']\n\n/** \u6E32\u67D3\u8BBE\u7F6E\u9762\u677F\u5C3A\u5BF8\u624B\u67C4\uFF1B\u65E0\u9762\u677F\u6216\u5F00\u5173\u5173\u95ED\u65F6\u4E0D\u6E32\u67D3\u3002 */\nexport function PanelResizeHandles({ useLive, actions }: PanelResizeProps) {\n const settings = useLive(value => ({\n enabled: value.enabled,\n panelResize: value.panelResize,\n panelWidth: value.panelWidth,\n panelHeight: value.panelHeight,\n }))\n const enabled = settings.enabled === true && settings.panelResize === true\n const [panel, setPanel] = useState<HTMLElement | null>(null)\n const [active, setActive] = useState<ResizeEdge | null>(null)\n const dragRef = useRef<DragStart | null>(null)\n\n // \u53D1\u73B0/\u5931\u53BB\u8BBE\u7F6E\u5BF9\u8BDD\u6846\uFF08\u5B98\u65B9 shell \u5143\u7D20\u6302\u8F7D React \u611F\u77E5\u4E0D\u5230\uFF0C\u6545\u8F6E\u8BE2\uFF1B\n // \u53EA\u5728\u300C\u6709\u6CA1\u6709\u9762\u677F\u300D\u771F\u7684\u53D8\u5316\u65F6\u624D setState\uFF0C\u907F\u514D\u65E0\u8C13\u91CD\u6E32\u67D3\uFF09\u3002\n useEffect(() => {\n if (!enabled) {\n setPanel(null)\n return\n }\n let current: HTMLElement | null = null\n const probe = (): void => {\n const found = findSettingsPanel()\n if (found === current) return\n current = found\n setPanel(found)\n }\n probe()\n const timer = setInterval(probe, 250)\n return () => { clearInterval(timer) }\n }, [enabled])\n\n // \u5957\u7528\u6301\u4E45\u5316\u5C3A\u5BF8\uFF1A\u9762\u677F\u51FA\u73B0\u65F6\u3001\u4EE5\u53CA**\u5C3A\u5BF8\u8BBE\u7F6E\u53D8\u5316\u65F6**\uFF08\u8FD9\u6837\u8BBE\u7F6E\u9875\u91CC\u70B9\n // \u300C\u5C3A\u5BF8\u9884\u8BBE\u300D\u5F53\u573A\u5C31\u53D8\uFF0C\u4E0D\u5FC5\u5173\u6389\u8BBE\u7F6E\u518D\u91CD\u5F00\uFF09\u3002\u8BBE\u7F6E\u88AB\u6E05\u7A7A\u65F6\u79FB\u9664\u5185\u8054\u6837\u5F0F\uFF0C\n // \u56DE\u843D\u5230\u5B98\u65B9\u9ED8\u8BA4 800\u3002\n useEffect(() => {\n if (panel === null) return\n const width = settings.panelWidth\n const height = settings.panelHeight\n if (width === undefined) panel.style.removeProperty('width')\n else panel.style.width = `${clampPanelWidth(width)}px`\n if (height === undefined) panel.style.removeProperty('height')\n else panel.style.height = `${clampPanelHeight(height)}px`\n }, [panel, settings.panelWidth, settings.panelHeight])\n\n if (!enabled || panel === null) return null\n\n const onPointerDown = (edge: ResizeEdge, event: React.PointerEvent): void => {\n event.preventDefault()\n event.stopPropagation()\n const el = panel\n const rect = el.getBoundingClientRect()\n // \u628A\u300C\u5C45\u4E2D flex \u5B50\u9879\u300D\u8F6C\u6210\u56FA\u5B9A\u5B9A\u4F4D\u540E\u518D\u62D6\uFF1A\u5C45\u4E2D\u7684\u5143\u7D20\u4E00\u6539\u5BBD\u5EA6\u4F1A**\u4E24\u4FA7\u540C\u65F6\n // \u4F38\u7F29**\uFF0C\u62D6\u53F3\u8FB9\u5DE6\u8FB9\u4E5F\u8DDF\u7740\u52A8\uFF0C\u624B\u611F\u662F\u9519\u7684\u3002\u8F6C\u6210 fixed \u4E4B\u540E\u62D6\u54EA\u8FB9\u5C31\u53EA\u52A8\u54EA\u8FB9\u3002\n el.style.position = 'fixed'\n el.style.margin = '0'\n el.style.left = `${rect.left}px`\n el.style.top = `${rect.top}px`\n el.style.width = `${rect.width}px`\n el.style.height = `${rect.height}px`\n\n const start: DragStart = {\n edge, x: event.clientX, y: event.clientY,\n left: rect.left, top: rect.top, width: rect.width, height: rect.height,\n }\n dragRef.current = start\n setActive(edge)\n document.body.style.cursor = String(handleBox(edge).cursor ?? 'default')\n document.body.style.userSelect = 'none'\n\n const onMove = (move: PointerEvent): void => {\n if (dragRef.current !== start) return\n move.preventDefault()\n const dx = move.clientX - start.x\n const dy = move.clientY - start.y\n let { left, top, width, height } = start\n if (edge === 'right' || edge === 'br') width = clampPanelWidth(start.width + dx)\n if (edge === 'bottom' || edge === 'br') height = clampPanelHeight(start.height + dy)\n if (edge === 'left') {\n width = clampPanelWidth(start.width - dx)\n left = start.left + (start.width - width)\n }\n if (edge === 'top') {\n height = clampPanelHeight(start.height - dy)\n top = start.top + (start.height - height)\n }\n el.style.left = `${Math.round(left)}px`\n el.style.top = `${Math.round(top)}px`\n el.style.width = `${Math.round(width)}px`\n el.style.height = `${Math.round(height)}px`\n }\n const onUp = (): void => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n dragRef.current = null\n setActive(null)\n const box = el.getBoundingClientRect()\n actions.setField(PANEL_WIDTH_FIELD, Math.round(clampPanelWidth(box.width)))\n actions.setField(PANEL_HEIGHT_FIELD, Math.round(clampPanelHeight(box.height)))\n document.body.style.removeProperty('cursor')\n document.body.style.removeProperty('user-select')\n }\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n }\n\n return createPortal(\n <div className={RESIZE_LAYER_CLASS} data-composer-ux-resize>\n <div className={RESIZE_OUTLINE_CLASS} style={RESIZE_OUTLINE_STYLE} />\n {EDGES.map(edge => (\n <div\n key={edge}\n className={edge === 'br' ? RESIZE_GRIP_CLASS : RESIZE_EDGE_CLASS}\n data-active={active === edge ? 'true' : undefined}\n title={edge === 'br' ? '\u62D6\u52A8\u6539\u9762\u677F\u5927\u5C0F' : undefined}\n style={handleBox(edge)}\n onPointerDown={event => { onPointerDown(edge, event) }}\n >\n {edge === 'br' && (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" aria-hidden>\n <path\n d=\"M11 1 1 11M11 6 6 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n strokeLinecap=\"round\"\n />\n </svg>\n )}\n </div>\n ))}\n </div>,\n panel,\n )\n}\n", "/**\n * \u8BBE\u7F6E\u9875\u300C\u8F93\u5165\u4F53\u9A8C\u300D\u3002\n *\n * \u7248\u5F0F\u5BF9\u9F50\u793E\u533A\u63D2\u4EF6 @linxin666/dsh-web-all \u7684\u300CWeb \u63D2\u4EF6\u300D\u9875\uFF1A\n * \u9876\u90E8\u5E38\u663E\uFF1A\u4E2D\u6587\u540D + \u4E00\u884C\u63CF\u8FF0\uFF08\u5185\u5D4C\u82F1\u6587\u5305\u540D dsh-composer-ux\uFF09+ \u603B\u5F00\u5173\uFF1B\n * \u5176\u4E0B\u4E09\u4E2A\u680F\u76EE\uFF08\u952E\u4F4D / \u53F3\u952E\u83DC\u5355 / \u8BBE\u7F6E\u9762\u677F\uFF09\u4E3A\u6298\u53E0\u5361\uFF0C\u6807\u9898\u884C\u53EA\u653E\u4E00\u53E5\n * \u6982\u89C8\uFF0C\u957F\u8BF4\u660E\u4E0E\u5177\u4F53\u63A7\u4EF6\u90FD\u5728\u5C55\u5F00\u540E\u7684\u5185\u5BB9\u533A\u91CC\uFF1B\u9ED8\u8BA4\u5168\u90E8\u6298\u53E0\u3001\u4E0D\u8BB0\u5FC6\u3002\n */\nimport React, { useEffect, useRef, useState, type CSSProperties } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsSectionOwnerProps } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n DEFAULT_CATEGORY_NAME, DEFAULT_HEADER_NAME, ENABLED_FIELD, HEADER_ENABLED_FIELD,\n HEADER_NAME_FIELD, HEADER_NAME_MAX, HEADER_ROUTES_FIELD, HEADER_VALUE_FIELD, HEADER_VALUE_MAX,\n MENU_ITEMS, MENU_NATIVE_FIELD, NEWLINE_PRESETS, OPTIMIZER_TIERS, OPTIMIZER_TIER_FIELD,\n PANEL_HEIGHT_FIELD,\n PANEL_RESIZE_FIELD, PANEL_SCROLL_FIELD, PANEL_WIDTH_FIELD, QUICK_CATEGORY_MAX,\n QUICK_CATEGORY_NAME_MAX, QUICK_LABEL_MAX,\n QUICK_PROMPTS_FIELD, QUICK_PROMPT_MAX, QUICK_TEXT_MAX, SEND_PRESETS,\n newQuickPromptId, newSessionId,\n type ComposerUxSettings, type MenuField, type OptimizerTier, type QuickPrompt,\n type QuickPromptBook, type SettingsField,\n} from '../settings-contract.ts'\nimport {\n bookCounts, withCategoryAdded, withCategoryMoved, withCategoryRemoved, withCategoryRenamed,\n withPromptAdded, withPromptMoved, withPromptPatched, withPromptRemoved,\n} from './prompt-book.ts'\nimport {\n evaluateRecordedKey, displayChord, type ChordEvent,\n} from './chords.ts'\nimport {\n description, hintError, hintInfo, kbd, pill, pillActive, row, rowDesc, rowText, rowTitle,\n textInput,\n} from './styles.ts'\n\n/** \u8BBE\u7F6E\u9875\u6CE8\u5165\u9762\u3002 */\nexport interface SettingsSectionInjected {\n hooks: {\n /** \u5F53\u524D\u89E3\u6790\u540E\u7684\u8BBE\u7F6E\u5FEB\u7167\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n /** \u5FEB\u6377\u6307\u4EE4\u672C\uFF08\u771F\u76F8\u5728\u78C1\u76D8\u90A3\u4EFD quick-prompts.json\uFF1B\u8FD9\u91CC\u53EA\u662F\u5B83\u7684\u5BA2\u6237\u7AEF\u5FEB\u7167\uFF09\u3002 */\n book: SnapshotStore<QuickPromptBook>\n /** '' = \u6B63\u5E38\uFF1B'saving' = \u6B63\u5728\u5199\uFF1B\u5176\u4F59 = \u4E0A\u4E00\u6B21\u7684\u9519\u8BEF\u6587\u6848\u3002 */\n bookStatus: SnapshotStore<string>\n }\n actions: {\n /** \u5199\u4E00\u4E2A\u5B57\u6BB5\uFF08\u952E\u4F4D\u4E3A\u89C4\u8303\u4E32\uFF0C\u5F00\u5173\u4E3A\u5E03\u5C14\uFF0C\u5C3A\u5BF8\u4E3A\u6570\u5B57\uFF09\u3002 */\n setField: (field: SettingsField, value: unknown) => void\n /** \u6E05\u7A7A\u4E00\u4E2A\u5B57\u6BB5\uFF08\u56DE\u843D\u5230 schema \u9ED8\u8BA4\uFF09\u3002 */\n clearField: (field: SettingsField) => void\n /** \u5168\u90E8\u6062\u590D\u9ED8\u8BA4\uFF08\u6E05\u7A7A\u7528\u6237\u8986\u76D6\uFF0C\u56DE\u843D\u5230 schema \u9ED8\u8BA4\uFF1B\u5FEB\u6377\u6307\u4EE4\u53E6\u89C1 resetBook\uFF09\u3002 */\n resetAll: () => void\n /** \u6574\u672C\u5199\u56DE\uFF08\u7F16\u8F91\u5668\u91CC\u7684\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\uFF09\u3002 */\n saveBook: (next: QuickPromptBook) => void\n /** \u4ECE\u78C1\u76D8\u91CD\u65B0\u8BFB\u53D6\uFF08\u522B\u7684\u7A97\u53E3\u6539\u8FC7\u65F6\u7684\u515C\u5E95\uFF09\u3002 */\n reloadBook: () => void\n /** \u6062\u590D\u5185\u7F6E 9 \u6761\uFF08\u5199\u56DE\u9ED8\u8BA4\u672C\uFF09\u3002 */\n resetBook: () => void\n }\n}\n\nexport type SettingsSectionProps =\n PropsRuntime<'settings.section'>\n & SettingsSectionOwnerProps\n & InjectFace<SettingsSectionInjected>\n\n/** \u5C55\u5F00\u533A\u5185\u7684\u5BFC\u8BED\u3002 */\nconst bodyLead: CSSProperties = { ...description, margin: '12px 0' }\n\n/** \u6298\u53E0\u7BAD\u5934\uFF08\u5185\u8054 SVG\uFF0C\u5C55\u5F00\u65F6\u9760\u7236\u7EA7 class \u65CB\u8F6C 180\u00B0\uFF09\u3002 */\nfunction Chevron() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.25 5.5L7 9.25L10.75 5.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\n/**\n * \u53EF\u6298\u53E0\u680F\u76EE\uFF1A\u6574\u884C\u6807\u9898\u5C31\u662F\u6309\u94AE\uFF0C\u9ED8\u8BA4\u6298\u53E0\u4E14\u4E0D\u8BB0\u5FC6\u5C55\u5F00\u72B6\u6001\n * \uFF08\u6BCF\u6B21\u6253\u5F00\u8BBE\u7F6E\u9875\u90FD\u56DE\u5230\u6298\u53E0\uFF09\u3002\n */\nfunction FoldCard(props: { name: string; summary: string; children: React.ReactNode }) {\n const [open, setOpen] = useState(false)\n return (\n <section className={open ? 'dsh-ux-card dsh-ux-cardOpen' : 'dsh-ux-card'}>\n <button\n type=\"button\"\n className=\"dsh-ux-cardHeader\"\n aria-expanded={open}\n onClick={() => { setOpen(current => !current) }}\n >\n <span className=\"dsh-ux-cardHeadText\">\n <span className=\"dsh-ux-cardName\">{props.name}</span>\n <span className=\"dsh-ux-cardDescription\">{props.summary}</span>\n </span>\n <span className={open ? 'dsh-ux-cardChevron dsh-ux-cardChevronOpen' : 'dsh-ux-cardChevron'}>\n <Chevron />\n </span>\n </button>\n {open && <div className=\"dsh-ux-cardBody\">{props.children}</div>}\n </section>\n )\n}\n\n/** \u952E\u4F4D\u884C\uFF1A\u5F53\u524D\u503C + \u9884\u8BBE + \u5F55\u5236 + \u6E05\u9664\u3002 */\nfunction KeyRow(props: {\n title: string\n desc: string\n value: string\n presets: readonly string[]\n conflict: (chord: string) => boolean\n onChange: (chord: string) => void\n /** \u5C55\u5F00\u533A\u91CC\u7684\u7B2C\u4E00\u884C\uFF1A\u4E0D\u753B\u4E0A\u8FB9\u6846\uFF08\u5185\u5BB9\u533A\u81EA\u5DF1\u6709\u4E00\u6761\u5206\u9694\u7EBF\uFF09\u3002 */\n first?: boolean\n}) {\n const { title, desc, value, presets, conflict, onChange, first } = props\n const [recording, setRecording] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (!recording) return\n const onKeyDown = (event: KeyboardEvent): void => {\n // \u5F55\u5236\u671F\u95F4\u541E\u6389\u6240\u6709\u6309\u952E\uFF0C\u907F\u514D\u6C61\u67D3\u8F93\u5165\u6846\u6216\u9875\u9762\u3002\n event.preventDefault()\n event.stopPropagation()\n if (event.isComposing) return\n const result = evaluateRecordedKey(event as unknown as ChordEvent)\n if (result.kind === 'ignore') return\n if (result.kind === 'cancel') {\n setRecording(false)\n setError(null)\n return\n }\n if (result.kind === 'clear') {\n setRecording(false)\n setError(null)\n onChange('')\n return\n }\n if (result.kind === 'reject') {\n setError(result.message)\n return\n }\n if (conflict(result.chord)) {\n setRecording(false)\n setError('\u53D1\u9001\u4E0E\u6362\u884C\u4E0D\u80FD\u8BBE\u4E3A\u76F8\u540C\u6309\u952E\uFF08\u53EF\u5148\u7ED9\u53E6\u4E00\u4FA7\u6362\u952E\uFF0C\u518D\u7ED1\u5B9A\u8BE5\u952E\uFF09\u3002')\n return\n }\n setRecording(false)\n setError(null)\n onChange(result.chord)\n }\n window.addEventListener('keydown', onKeyDown, true)\n return () => { window.removeEventListener('keydown', onKeyDown, true) }\n }, [recording, conflict, onChange])\n\n const base = first === true ? { ...row, borderTop: 'none' } : row\n\n return (\n <div style={{ ...base, flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>{title}</div>\n <div style={rowDesc}>{desc}</div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n <span style={kbd}>{displayChord(value)}</span>\n {!recording && presets.map(preset => (\n <button\n key={preset}\n type=\"button\"\n style={value === preset ? pillActive : pill}\n onClick={() => { setError(null); onChange(preset) }}\n >\n {displayChord(preset)}\n </button>\n ))}\n {!recording && value !== '' && (\n <button type=\"button\" style={pill} onClick={() => { setError(null); onChange('') }}>\n \u6E05\u9664\n </button>\n )}\n <button\n type=\"button\"\n style={recording ? pillActive : pill}\n onClick={() => { setRecording(true); setError(null) }}\n >\n {recording ? '\u8BF7\u6309\u4E0B\u65B0\u7EC4\u5408\u952E\u2026' : '\u81EA\u5B9A\u4E49\u2026'}\n </button>\n {recording && (\n <button type=\"button\" style={pill} onClick={() => { setRecording(false); setError(null) }}>\n Esc \u53D6\u6D88\n </button>\n )}\n {error !== null && (\n <span style={{ color: 'var(--dsw-alias-state-error-primary)', fontSize: 12 }}>{error}</span>\n )}\n </div>\n </div>\n )\n}\n\n/** \u5F00\u5173\u884C\u3002 */\nfunction ToggleRow(props: {\n label: string\n desc?: string\n checked: boolean\n onChange: (next: boolean) => void\n /** \u5C55\u5F00\u533A\u91CC\u7684\u7B2C\u4E00\u884C\uFF1A\u4E0D\u753B\u4E0A\u8FB9\u6846\u3002 */\n first?: boolean\n}) {\n const { label, desc, checked, onChange, first } = props\n return (\n <div style={first === true ? { ...row, borderTop: 'none' } : row}>\n <div style={rowText}>\n <div style={rowTitle}>{label}</div>\n {desc !== undefined && desc !== '' && <div style={rowDesc}>{desc}</div>}\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n onClick={() => { onChange(!checked) }}\n style={{\n width: 36,\n height: 20,\n borderRadius: 999,\n border: '0.5px solid var(--dsw-alias-border-l2)',\n cursor: 'pointer',\n background: checked\n ? 'var(--dsw-alias-button-primary-fill)'\n : 'var(--dsw-alias-interactive-bg-hover)',\n position: 'relative',\n flex: '0 0 auto',\n padding: 0,\n }}\n >\n <span\n style={{\n position: 'absolute',\n top: 2,\n left: checked ? 18 : 2,\n width: 14,\n height: 14,\n borderRadius: '50%',\n background: checked\n ? 'var(--dsw-alias-label-primary-foreground)'\n : 'var(--dsw-alias-label-secondary)',\n transition: 'left 0.12s ease',\n }}\n />\n </button>\n </div>\n )\n}\n\n/** \u6587\u672C\u5B57\u6BB5\u884C\uFF1A\u6807\u9898 + \u8BF4\u660E + \u8F93\u5165\u6846\uFF08\u53EF\u9009\u52A8\u4F5C\u6309\u94AE\uFF09\u3002\n * \u8F93\u5165\u8FC7\u7A0B\u4E2D\u53EA\u6539\u672C\u5730\u8349\u7A3F\uFF0C\u5931\u7126\u6216\u56DE\u8F66\u624D\u843D\u76D8\u2014\u2014\u907F\u514D\u6BCF\u6572\u4E00\u4E2A\u5B57\u5C31\u5199\u4E00\u6B21\u914D\u7F6E\u6587\u4EF6\u3002 */\nfunction TextFieldRow(props: {\n title: string\n desc: string\n value: string\n placeholder?: string\n maxLength: number\n onChange: (next: string) => void\n action?: { label: string; onClick: () => void }\n /** \u5C55\u5F00\u533A\u91CC\u7684\u7B2C\u4E00\u884C\uFF1A\u4E0D\u753B\u4E0A\u8FB9\u6846\u3002 */\n first?: boolean\n}) {\n const { title, desc, value, placeholder, maxLength, onChange, action, first } = props\n const [draft, setDraft] = useState(value)\n const focused = useRef(false)\n\n // \u53EA\u5728\u6CA1\u6709\u7126\u70B9\u65F6\u8DDF\u968F\u5916\u90E8\u503C\uFF1A\u5199\u76D8\u662F\u5F02\u6B65\u5F80\u8FD4\uFF0C\u8F93\u5165\u4E2D\u540C\u6B65\u4F1A\u628A\u7528\u6237\u6B63\u5728\u6253\u7684\u5B57\u56DE\u6EDA\u3002\n useEffect(() => {\n if (!focused.current) setDraft(value)\n }, [value])\n\n const commit = (): void => {\n if (draft === value) return\n onChange(draft.trim())\n }\n\n const base = first === true ? { ...row, borderTop: 'none' } : row\n\n return (\n <div style={{ ...base, flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>{title}</div>\n <div style={rowDesc}>{desc}</div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <input\n type=\"text\"\n value={draft}\n placeholder={placeholder ?? ''}\n maxLength={maxLength}\n spellCheck={false}\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n onFocus={() => { focused.current = true }}\n onChange={event => { setDraft(event.target.value) }}\n onBlur={() => { focused.current = false; commit() }}\n onKeyDown={event => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n commit()\n event.currentTarget.blur()\n }}\n style={textInput}\n />\n {action !== undefined && (\n <button type=\"button\" style={pill} onClick={action.onClick}>{action.label}</button>\n )}\n </div>\n </div>\n )\n}\n\n/** \u5FEB\u6377\u6307\u4EE4\u7F16\u8F91\u533A\uFF1A\u672C\u5730\u8349\u7A3F + \u663E\u5F0F\u4FDD\u5B58\uFF08\u907F\u514D\u6BCF\u6572\u4E00\u4E2A\u5B57\u5C31\u5199\u4E00\u6B21\u914D\u7F6E\u6587\u4EF6\uFF09\u3002 */\n/**\n * \u5FEB\u6377\u6307\u4EE4\u7F16\u8F91\u5668\uFF080.3.0 \u8D77\u7684\u5206\u7C7B\u4E24\u7EA7\u7ED3\u6784\uFF09\u3002\n *\n * \u7F16\u8F91\u5728**\u672C\u5730\u8349\u7A3F**\u4E0A\u505A\uFF1A\u8349\u7A3F\u7528 `prompt-book.ts` \u90A3\u5957\u7EAF\u51FD\u6570\u6539\uFF08\u4E0E\u670D\u52A1\u7AEF\u540C\u4E00\u5957\u903B\u8F91\uFF09\uFF0C\n * \u53EA\u6709\u70B9\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\u624D\u6574\u672C\u5199\u56DE \u2014\u2014 \u5426\u5219\u6BCF\u6572\u4E00\u4E2A\u5B57\u5C31\u662F\u4E00\u6B21 HTTP + \u4E00\u6B21\u539F\u5B50\u5199\u3002\n *\n * \u4FDD\u5B58\u540E\u5BBF\u4E3B\u4F1A\u56DE\u8BFB\u78C1\u76D8\u771F\u5B9E\u5185\u5BB9\u5E76\u8986\u76D6\u672C\u5730\u5FEB\u7167\uFF0C\u8349\u7A3F\u8DDF\u7740\u5B83\u8D70\uFF1A\u4E8E\u662F\u300C\u7A7A\u6B63\u6587\u7684\u6761\u76EE\u88AB\n * \u51C0\u5316\u4E22\u5F03\u300D\u8FD9\u7C7B\u6536\u7A84\u4F1A\u5728\u754C\u9762\u4E0A\u7ACB\u523B\u663E\u73B0\uFF0C\u800C\u4E0D\u662F\u7B49\u5230\u4E0B\u6B21\u6253\u5F00\u8BBE\u7F6E\u624D\u53D1\u73B0\u4E0D\u4E00\u6837\u3002\n */\nfunction QuickPromptsEditor(props: {\n book: QuickPromptBook\n status: string\n onSave: (next: QuickPromptBook) => void\n onReset: () => void\n onReload: () => void\n}) {\n const [draft, setDraft] = useState<QuickPromptBook>(() => props.book)\n const [activeId, setActiveId] = useState(() => props.book.categories[0]?.id ?? '')\n const [dirty, setDirty] = useState(false)\n const [newName, setNewName] = useState('')\n /** \u4E0A\u4E00\u6B21\u4FDD\u5B58\u65F6\u8DF3\u8FC7\u7A7A\u6761\u76EE\u7684\u8BF4\u660E\uFF08\u7A7A\u4E32 = \u65E0\uFF09\u3002 */\n const [note, setNote] = useState('')\n\n // \u672C\u5730\u6CA1\u6709\u672A\u4FDD\u5B58\u4FEE\u6539\u65F6\u8DDF\u968F\u5916\u90E8\u5FEB\u7167\u3002\n useEffect(() => {\n if (dirty) return\n setDraft(props.book)\n if (!props.book.categories.some(category => category.id === activeId)) {\n setActiveId(props.book.categories[0]?.id ?? '')\n }\n }, [props.book, dirty, activeId])\n\n const edit = (next: QuickPromptBook): void => {\n setDirty(true)\n setDraft(next)\n }\n const current = draft.categories.find(category => category.id === activeId) ?? draft.categories[0]\n const counts = bookCounts(draft)\n const saving = props.status === 'saving'\n const failed = props.status !== '' && props.status !== 'saving'\n\n const rowBox: CSSProperties = {\n display: 'flex', flexDirection: 'column', gap: 6,\n padding: 8, borderRadius: 8,\n border: '0.5px solid var(--dsw-alias-border-l2)',\n background: 'var(--dsw-alias-bg-layer-1)',\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {/* \u5206\u7C7B\u5207\u6362 + \u65B0\u589E */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' }}>\n {draft.categories.map(category => (\n <button\n key={category.id}\n type=\"button\"\n style={category.id === current?.id ? pillActive : pill}\n onClick={() => { setActiveId(category.id) }}\n >\n {category.name}\uFF08{category.prompts.length}\uFF09\n </button>\n ))}\n <input\n type=\"text\"\n value={newName}\n placeholder=\"\u65B0\u5206\u7C7B\u540D\"\n maxLength={QUICK_CATEGORY_NAME_MAX}\n spellCheck={false}\n onChange={event => { setNewName(event.target.value) }}\n style={{ ...textInput, flex: '0 0 110px' }}\n />\n <button\n type=\"button\"\n style={pill}\n disabled={draft.categories.length >= QUICK_CATEGORY_MAX}\n onClick={() => {\n edit(withCategoryAdded(draft, newName === '' ? DEFAULT_CATEGORY_NAME : newName))\n setNewName('')\n }}\n >\n + \u52A0\u5206\u7C7B\n </button>\n </div>\n\n {current === undefined && (\n <p style={rowDesc}>\u8FD8\u6CA1\u6709\u5206\u7C7B\u3002\u5148\u52A0\u4E00\u4E2A\u5206\u7C7B\uFF0C\u518D\u5F80\u91CC\u653E\u6761\u76EE\u3002</p>\n )}\n\n {current !== undefined && (\n <>\n {/* \u5F53\u524D\u5206\u7C7B\uFF1A\u6539\u540D / \u6362\u4F4D / \u5220\u9664 */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>\n <input\n type=\"text\"\n value={current.name}\n aria-label=\"\u5206\u7C7B\u540D\"\n maxLength={QUICK_CATEGORY_NAME_MAX}\n spellCheck={false}\n onChange={event => { edit(withCategoryRenamed(draft, current.id, event.target.value)) }}\n style={{ ...textInput, flex: '0 0 150px' }}\n />\n <button type=\"button\" style={pill} title=\"\u5206\u7C7B\u4E0A\u79FB\" onClick={() => { edit(withCategoryMoved(draft, current.id, -1)) }}>\u2191</button>\n <button type=\"button\" style={pill} title=\"\u5206\u7C7B\u4E0B\u79FB\" onClick={() => { edit(withCategoryMoved(draft, current.id, 1)) }}>\u2193</button>\n <button\n type=\"button\"\n style={pill}\n title=\"\u5220\u9664\u8FD9\u4E2A\u5206\u7C7B\uFF08\u8FDE\u540C\u5B83\u91CC\u9762\u7684\u6761\u76EE\uFF09\"\n onClick={() => { edit(withCategoryRemoved(draft, current.id)) }}\n >\n \u2715 \u5220\u9664\u5206\u7C7B\n </button>\n <span style={rowDesc}>{current.prompts.length} / {QUICK_PROMPT_MAX} \u6761</span>\n </div>\n\n {current.prompts.map(prompt => (\n <div key={prompt.id} style={rowBox}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <input\n type=\"text\"\n value={prompt.label}\n placeholder=\"\u540D\u79F0\uFF0C\u5982\uFF1A\u4EC5\u8BF4\u660E\u539F\u56E0\"\n maxLength={QUICK_LABEL_MAX}\n spellCheck={false}\n onChange={event => { edit(withPromptPatched(draft, current.id, prompt.id, { label: event.target.value })) }}\n style={{ ...textInput, flex: '0 0 150px' }}\n />\n <label style={{ display: 'inline-flex', alignItems: 'center', gap: 4, ...rowDesc, margin: 0, flex: '0 0 auto' }}>\n <input\n type=\"checkbox\"\n checked={prompt.always}\n style={{ margin: 0, cursor: 'pointer' }}\n onChange={event => { edit(withPromptPatched(draft, current.id, prompt.id, { always: event.target.checked })) }}\n />\n \u9ED8\u8BA4\u63D2\u5165\n </label>\n <span style={{ flex: 1 }} />\n <button type=\"button\" style={pill} title=\"\u4E0A\u79FB\" onClick={() => { edit(withPromptMoved(draft, current.id, prompt.id, -1)) }}>\u2191</button>\n <button type=\"button\" style={pill} title=\"\u4E0B\u79FB\" onClick={() => { edit(withPromptMoved(draft, current.id, prompt.id, 1)) }}>\u2193</button>\n <button type=\"button\" style={pill} title=\"\u5220\u9664\u8FD9\u6761\" onClick={() => { edit(withPromptRemoved(draft, current.id, prompt.id)) }}>\u2715</button>\n </div>\n <textarea\n value={prompt.prompt}\n placeholder=\"\u63D0\u793A\u8BCD\u6B63\u6587\uFF1A\u70B9\u51FB\u8BE5\u6761\u76EE\u65F6\u63D2\u5165\u8F93\u5165\u6846\uFF1B\u52FE\u4E86\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u5219\u5728\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\"\n maxLength={QUICK_TEXT_MAX}\n spellCheck={false}\n rows={Math.min(4, Math.max(2, Math.ceil(prompt.prompt.length / 46)))}\n onChange={event => { edit(withPromptPatched(draft, current.id, prompt.id, { prompt: event.target.value })) }}\n style={{ ...textInput, resize: 'vertical', fontFamily: 'inherit', lineHeight: 1.5 }}\n />\n </div>\n ))}\n\n <div>\n <button type=\"button\" style={pill} onClick={() => { edit(withPromptAdded(draft, current.id)) }}>+ \u6DFB\u52A0\u4E00\u6761</button>\n </div>\n </>\n )}\n\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n <button\n type=\"button\"\n style={dirty ? pillActive : pill}\n disabled={!dirty || saving}\n onClick={() => {\n // \u5148\u628A\u6B63\u6587\u4E3A\u7A7A\u7684\u6761\u76EE\u5254\u6389**\u5E76\u8BF4\u660E**\uFF1A\u51C0\u5316\u7AEF\u4E5F\u4F1A\u4E22\u5B83\u4EEC\uFF0C\u4F46\u82E5\u8BA9\u7528\u6237\u81EA\u5DF1\u53D1\u73B0\n // \u300C\u6211\u52A0\u7684\u8FD9\u6761\u600E\u4E48\u6CA1\u4E86\u300D\uFF0C\u90A3\u662F\u4E00\u6B21\u8BF4\u4E0D\u6E05\u7684\u9759\u9ED8\u4E22\u5931\u3002\n const next: QuickPromptBook = {\n version: draft.version,\n categories: draft.categories.map(category => ({\n ...category,\n prompts: category.prompts.filter(prompt => prompt.prompt.trim() !== ''),\n })),\n }\n const skipped = counts.prompts - bookCounts(next).prompts\n setNote(skipped > 0 ? `\u5DF2\u8DF3\u8FC7 ${String(skipped)} \u6761\u6B63\u6587\u4E3A\u7A7A\u7684\u6761\u76EE` : '')\n props.onSave(next)\n setDirty(false)\n }}\n >\n {saving ? '\u4FDD\u5B58\u4E2D\u2026' : (dirty ? '\u4FDD\u5B58\u4FEE\u6539' : '\u5DF2\u4FDD\u5B58')}\n </button>\n <button type=\"button\" style={pill} onClick={() => { props.onReload() }}>\u91CD\u65B0\u8BFB\u53D6</button>\n <button type=\"button\" style={pill} onClick={() => { props.onReset() }}>\u6062\u590D\u5185\u7F6E 9 \u6761</button>\n <span style={rowDesc}>\n \u5171 {counts.categories} \u4E2A\u5206\u7C7B \u00B7 {counts.prompts} \u6761 \u00B7 \u9ED8\u8BA4\u63D2\u5165 {counts.always} \u6761\n {note === '' ? '' : ` \u00B7 ${note}`}\n {failed ? ` \u00B7 ${props.status}` : ''}\n </span>\n </div>\n <p style={rowDesc}>\n \u6570\u636E\u5B58\u5728 <code>~/.dsh/quick-prompts.json</code>\uFF08\u4E0E\u4F1A\u8BDD\u3001\u9879\u76EE\u65E0\u5173\uFF0C\u53EF\u5355\u72EC\u5907\u4EFD\u6216\u624B\u5DE5\u7F16\u8F91\uFF0C\n \u6539\u5B8C\u70B9\u300C\u91CD\u65B0\u8BFB\u53D6\u300D\u5373\u53EF\u52A0\u8F7D\uFF09\u3002\n </p>\n </div>\n )\n}\n\n/** \u8BBE\u7F6E\u9875\u4E3B\u4F53\u3002 */\nexport function SettingsSection({ useLive, useBook, useBookStatus, actions }: SettingsSectionProps) {\n const settings = useLive(item => item)\n const book = useBook(item => item)\n const bookStatus = useBookStatus(item => item)\n const [conflict, setConflict] = useState<string | null>(null)\n\n const setKey = (side: 'send' | 'newline', chord: string): void => {\n const other = side === 'send' ? settings.newlineKey : settings.sendKey\n if (chord !== '' && chord === other) {\n setConflict(chord)\n return\n }\n setConflict(null)\n actions.setField(side === 'send' ? 'sendKey' : 'newlineKey', chord)\n }\n\n const conflictHint = conflict !== null\n ? `\u300C${displayChord(conflict)}\u300D\u5DF2\u88AB\u53E6\u4E00\u4FA7\u5360\u7528\uFF0C\u8BF7\u5148\u4E3A\u53E6\u4E00\u4FA7\u9009\u62E9\u5176\u5B83\u6309\u952E\u3002`\n : null\n\n const menuEnabled = MENU_ITEMS.filter(item => settings[item.field]).length\n const keySummary = `\u53D1\u9001 ${displayChord(settings.sendKey)} \u00B7 \u6362\u884C ${displayChord(settings.newlineKey)}`\n const menuSummary = settings.menuNative\n ? '\u5F53\u524D\uFF1A\u7CFB\u7EDF\u539F\u751F\u83DC\u5355\uFF08\u7C98\u8D34\u514D\u6388\u6743\uFF09'\n : `\u5F53\u524D\uFF1A\u81EA\u5B9A\u4E49\u83DC\u5355 \u00B7 ${menuEnabled} / ${MENU_ITEMS.length} \u9879\u5F00\u542F`\n const panelSummary = `\u5BFC\u822A\u6EDA\u52A8 ${settings.panelScroll ? '\u5F00' : '\u5173'}`\n + ` \u00B7 \u8FB9\u7F18\u7F29\u653E ${settings.panelResize ? '\u5F00' : '\u5173'}`\n + ` \u00B7 ${settings.panelWidth}\u00D7${settings.panelHeight}`\n // \u8BF7\u6C42\u5934\u680F\u76EE\u7684\u6982\u89C8\u76F4\u63A5\u590D\u7528\u5BBF\u4E3B\u534A\u5199\u56DE\u6765\u7684\u6267\u884C\u7ED3\u679C\uFF08'\u5DF2\u5199\u5165 opencode-go' \u8FD9\u7C7B\uFF09\u3002\n const headerSummary = settings.headerEnabled\n ? (settings.headerStatus === '' ? '\u5DF2\u542F\u7528' : settings.headerStatus)\n : '\u672A\u542F\u7528'\n const quickCounts = bookCounts(book)\n const quickSummary = `${quickCounts.categories} \u4E2A\u5206\u7C7B \u00B7 ${quickCounts.prompts} \u6761`\n + ` \u00B7 \u9ED8\u8BA4\u63D2\u5165 ${quickCounts.always} \u6761`\n + ` \u00B7 \u4F18\u5316\u6863\u4F4D ${OPTIMIZER_TIERS.find(item => item.id === settings.optimizerTier)?.label ?? '\u9AD8\u7EA7'}`\n const headerStatusText = settings.headerEnabled\n ? (settings.headerStatus === '' ? '\u7B49\u5F85\u9996\u6B21\u5199\u5165\u2026' : settings.headerStatus)\n : '\u672A\u542F\u7528\uFF08\u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u5199\u5165\uFF09'\n\n return (\n <div style={{ padding: '4px 2px' }}>\n {/* \u9876\u90E8\u5E38\u663E\u533A\uFF1A\u4E2D\u6587\u540D + \u5185\u5D4C\u82F1\u6587\u5305\u540D\u7684\u4E00\u884C\u63CF\u8FF0 + \u603B\u5F00\u5173\u3002 */}\n <section className=\"dsh-ux-card\">\n <div className=\"dsh-ux-cardHeaderStatic\">\n <span className=\"dsh-ux-cardHeadText\">\n <h2 className=\"dsh-ux-cardName\">\u8F93\u5165\u4F53\u9A8C</h2>\n <p className=\"dsh-ux-cardDescription\">\n dsh-composer-ux \u00B7 \u4E3B\u804A\u5929\u8F93\u5165\u6846\u7684\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\uFF1B\u8BBE\u7F6E\u5373\u65F6\u751F\u6548\u5E76\u6301\u4E45\u4FDD\u5B58\u3002\n </p>\n </span>\n </div>\n <div className=\"dsh-ux-cardBody\">\n <ToggleRow\n first\n label=\"\u542F\u7528\u8F93\u5165\u589E\u5F3A\"\n desc=\"\u5173\u95ED\u540E\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u4E0E\u8BBE\u7F6E\u9762\u677F\u6EDA\u52A8/\u7F29\u653E\u5168\u90E8\u505C\u7528\uFF08\u672C\u9875\u4FDD\u7559\u7528\u4E8E\u91CD\u65B0\u5F00\u542F\uFF09\"\n checked={settings.enabled}\n onChange={next => { actions.setField(ENABLED_FIELD, next) }}\n />\n {!settings.enabled && (\n <p style={hintInfo}>\n \u5DF2\u505C\u7528\uFF1A\u53D1\u9001/\u6362\u884C\u952E\u4F4D\u3001\u53F3\u952E\u83DC\u5355\u3001\u8BBE\u7F6E\u9762\u677F\u6EDA\u52A8\u4E0E\u8FB9\u7F18\u7F29\u653E\u5747\u4E0D\u518D\u751F\u6548\uFF0C\u8F93\u5165\u6846\u6062\u590D DSH \u539F\u751F\u884C\u4E3A\u3002\n \u6253\u5F00\u4E0A\u65B9\u5F00\u5173\u5373\u53EF\u4E00\u952E\u6062\u590D\uFF1B\u6240\u6709\u8BBE\u7F6E\u503C\u4ECD\u4FDD\u7559\u3002\n </p>\n )}\n </div>\n </section>\n\n {settings.enabled && (<>\n <FoldCard name=\"\u952E\u4F4D\" summary={keySummary}>\n <p style={bodyLead}>\n \u652F\u6301\u5E38\u7528\u9884\u8BBE\uFF0C\u4E5F\u53EF\u4EE5\u70B9\u51FB\u300C\u81EA\u5B9A\u4E49\u2026\u300D\u540E\u76F4\u63A5\u6309\u4E0B\u4EFB\u610F\u7EC4\u5408\u952E\u5F55\u5236\uFF08Esc \u53D6\u6D88\uFF0CBackspace \u6E05\u9664\uFF09\u3002\n \u672A\u7ED1\u5B9A\u7684 Enter \u7CFB\u6309\u952E\u4E0D\u4F1A\u89E6\u53D1\u53D1\u9001\u6216\u6362\u884C\uFF1BCtrl+Enter / \u2318+Enter \u672A\u88AB\u7ED1\u5B9A\u65F6\u4FDD\u7559\u539F\u300C\u52A0\u901F\u63D0\u4EA4\u300D\u884C\u4E3A\uFF1B\n \u4E2D\u6587\u8F93\u5165\u6CD5\u7EC4\u5408\u671F\u95F4\u4E0D\u53D7\u5F71\u54CD\u3002\n </p>\n <KeyRow\n first\n title=\"\u53D1\u9001\u952E\"\n desc=\"\u6309\u4E0B\u540E\u53D1\u9001\u5F53\u524D\u8F93\u5165\"\n value={settings.sendKey}\n presets={SEND_PRESETS}\n conflict={chord => chord !== '' && chord === settings.newlineKey}\n onChange={chord => { setKey('send', chord) }}\n />\n <KeyRow\n title=\"\u6362\u884C\u952E\"\n desc=\"\u6309\u4E0B\u540E\u5728\u8F93\u5165\u5185\u6362\u884C\"\n value={settings.newlineKey}\n presets={NEWLINE_PRESETS}\n conflict={chord => chord !== '' && chord === settings.sendKey}\n onChange={chord => { setKey('newline', chord) }}\n />\n {conflictHint !== null && <p style={hintError}>{conflictHint}</p>}\n <div style={{ marginTop: 10 }}>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { setConflict(null); actions.resetAll() }}\n >\n \u6062\u590D\u9ED8\u8BA4\n </button>\n </div>\n </FoldCard>\n\n <FoldCard name=\"\u53F3\u952E\u83DC\u5355\" summary={menuSummary}>\n <p style={bodyLead}>\n \u53F3\u952E\u70B9\u51FB\u8F93\u5165\u6846\u65F6\u7684\u884C\u4E3A\u3002\u7CFB\u7EDF\u539F\u751F\u6A21\u5F0F\u4E0B\u7531\u6D4F\u89C8\u5668\u5F39\u51FA\u81EA\u5DF1\u7684\u83DC\u5355\uFF08\u6837\u5F0F\u968F\u6D4F\u89C8\u5668\u800C\u53D8\u5316\uFF0C\n \u7C98\u8D34\u514D\u6388\u6743\u3001\u96F6\u914D\u7F6E\uFF09\uFF1B\u81EA\u5B9A\u4E49\u6A21\u5F0F\u4F7F\u7528\u56FA\u5B9A\u6837\u5F0F\u83DC\u5355\uFF08\u672A\u9009\u4E2D\u6587\u672C\u65F6\u300C\u526A\u5207 / \u590D\u5236 / \u5220\u9664\u300D\u7F6E\u7070\uFF0C\n \u7C98\u8D34\u9700\u8981\u6D4F\u89C8\u5668\u526A\u8D34\u677F\u6388\u6743\uFF0CFirefox \u8981\u5728 about:config \u4E2D\u8BBE\u7F6E\n permissions.default.clipboard-read = 1 \u624D\u80FD\u514D\u5F39\u7A97\uFF09\u3002\n </p>\n <ToggleRow\n first\n label=\"\u4F7F\u7528\u7CFB\u7EDF\u539F\u751F\u83DC\u5355\"\n desc=\"\u6253\u5F00\u540E\u53F3\u952E\u7C98\u8D34\u514D\u6388\u6743\uFF08\u70B9\u51FB\u6D4F\u89C8\u5668\u83DC\u5355\u7684\u7C98\u8D34\u76F4\u63A5\u6210\u529F\uFF09\uFF1B\u5173\u95ED\u540E\u6062\u590D\u81EA\u5B9A\u4E49\u83DC\u5355\"\n checked={settings.menuNative}\n onChange={next => { actions.setField(MENU_NATIVE_FIELD, next) }}\n />\n {!settings.menuNative && (<>\n {MENU_ITEMS.map(item => (\n <ToggleRow\n key={item.field}\n label={item.label}\n desc={item.shortcut !== '' ? `\u5FEB\u6377\u952E ${item.shortcut}` : ''}\n checked={settings[item.field]}\n onChange={next => { actions.setField(item.field as MenuField, next) }}\n />\n ))}\n <div style={{ marginTop: 10 }}>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { for (const item of MENU_ITEMS) actions.setField(item.field as MenuField, true) }}\n >\n \u5168\u90E8\u5F00\u542F\n </button>\n </div>\n </>)}\n </FoldCard>\n\n <FoldCard name=\"\u5FEB\u6377\u6307\u4EE4\" summary={quickSummary}>\n <p style={bodyLead}>\n \u8F93\u5165\u6846\u5DE5\u5177\u884C\u91CC\u90A3\u4E2A\u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6309\u94AE\u70B9\u5F00\u5C31\u662F\u8FD9\u5F20\u6E05\u5355\uFF1A\u70B9\u6761\u76EE\u628A\u5185\u5BB9\u63D2\u5165\u8F93\u5165\u6846\uFF1B\n \u6761\u76EE\u53F3\u4FA7\u52FE\u4E0A\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF0C\u5219\u5728\u4F60**\u70B9\u53D1\u9001\u65F6**\u628A\u8FD9\u6761\u63D0\u793A\u8BCD\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F**\u672B\u5C3E**\n \u4E00\u8D77\u53D1\u51FA\u53BB\uFF08\u591A\u6761\u6309\u5217\u8868\u987A\u5E8F\u62FC\u63A5\uFF0C\u8F93\u5165\u6846\u91CC\u4E0D\u63D0\u524D\u663E\u793A\uFF09\u3002\n \u300C\u4F18\u5316\u63D0\u793A\u8BCD\u300D\u4F1A\u7528\u53E6\u4E00\u4E2A AI \u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u6574\u7406\u6210\u4E00\u6761\u80FD\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C\n \u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\uFF08Ctrl+Z \u53EF\u8FD8\u539F\uFF09\u2014\u2014\u4E0D\u4F1A\u6C61\u67D3\u5F53\u524D\u5BF9\u8BDD\uFF0C\u4E5F\u4E0D\u5360\u4F60\u7684\u5BF9\u8BDD\u8F6E\u6B21\u3002\n </p>\n <div style={{ ...row, borderTop: 'none', flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>\u4F18\u5316\u5F3A\u5EA6</div>\n <div style={rowDesc}>\n {OPTIMIZER_TIERS.find(item => item.id === settings.optimizerTier)?.hint ?? ''}\n </div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>\n {OPTIMIZER_TIERS.map(item => (\n <button\n key={item.id}\n type=\"button\"\n title={item.hint}\n style={settings.optimizerTier === item.id ? pillActive : pill}\n onClick={() => { actions.setField(OPTIMIZER_TIER_FIELD, item.id as OptimizerTier) }}\n >\n {item.label}\n </button>\n ))}\n </div>\n </div>\n <div style={{ ...row, borderTop: 'none', flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <div style={rowText}>\n <div style={rowTitle}>\u5FEB\u6377\u6307\u4EE4\u6E05\u5355</div>\n <div style={rowDesc}>\n \u5206\u7C7B\u5728\u8FD9\u91CC\u7BA1\u7406\uFF08\u9762\u677F\u91CC\u53EA\u505A\u5207\u6362\uFF09\uFF1B\u5185\u7F6E 9 \u6761\u53EF\u4EE5\u76F4\u63A5\u7528\uFF0C\u6539\u5B8C\u8BB0\u5F97\u70B9\u300C\u4FDD\u5B58\u4FEE\u6539\u300D\u3002\n </div>\n </div>\n <QuickPromptsEditor\n book={book}\n status={bookStatus}\n onSave={next => { actions.saveBook(next) }}\n onReload={() => { actions.reloadBook() }}\n onReset={() => { actions.resetBook() }}\n />\n </div>\n </FoldCard>\n\n <FoldCard name=\"\u8BBE\u7F6E\u9762\u677F\" summary={panelSummary}>\n <p style={bodyLead}>\n \u63D2\u4EF6\u88C5\u5F97\u591A\u65F6\u8BBE\u7F6E\u6761\u76EE\u5F88\u957F\uFF1A\u5F00\u542F\u300C\u5BFC\u822A\u53EF\u6EDA\u52A8\u300D\u540E\uFF0C\u5DE6\u4FA7\u5BFC\u822A\u5728\u6EA2\u51FA\u65F6\u4F1A\u51FA\u73B0\u6EDA\u52A8\u6761\u3002\n \u5F00\u542F\u300C\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u300D\u540E\uFF0C\u628A\u9F20\u6807\u79FB\u5230\u8BBE\u7F6E\u9762\u677F\u7684\u8FB9\u6216\u89D2\u4E0A\uFF08\u51FA\u73B0\u9AD8\u4EAE\u6216\u5149\u6807\u53D8\u5316\uFF09\u62D6\u52A8\u5373\u53EF\u6539\u53D8\u9762\u677F\u5927\u5C0F\uFF0C\n \u5C3A\u5BF8\u4F1A\u8BB0\u4F4F\uFF0C\u4E0B\u6B21\u6253\u5F00\u4FDD\u6301\u3002\n </p>\n <ToggleRow\n first\n label=\"\u5BFC\u822A\u53EF\u6EDA\u52A8\"\n desc=\"\u8BBE\u7F6E\u6761\u76EE\u8D85\u51FA\u9762\u677F\u9AD8\u5EA6\u65F6\u663E\u793A\u6EDA\u52A8\u6761\"\n checked={settings.panelScroll}\n onChange={next => { actions.setField(PANEL_SCROLL_FIELD, next) }}\n />\n <ToggleRow\n label=\"\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\"\n desc=\"\u62D6\u52A8\u9762\u677F\u56DB\u8FB9 / \u56DB\u89D2\u6539\u53D8\u9762\u677F\u5C3A\u5BF8\"\n checked={settings.panelResize}\n onChange={next => { actions.setField(PANEL_RESIZE_FIELD, next) }}\n />\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginTop: 10 }}>\n <span style={rowDesc}>\u5C3A\u5BF8\u9884\u8BBE\uFF1A</span>\n <button\n type=\"button\"\n style={pill}\n onClick={() => { actions.clearField(PANEL_WIDTH_FIELD); actions.clearField(PANEL_HEIGHT_FIELD) }}\n >\n \u9ED8\u8BA4\uFF08800\uFF09\n </button>\n <button\n type=\"button\"\n style={settings.panelWidth === 640 && settings.panelHeight === 600 ? pillActive : pill}\n onClick={() => {\n actions.setField(PANEL_WIDTH_FIELD, 640)\n actions.setField(PANEL_HEIGHT_FIELD, 600)\n }}\n >\n \u7D27\u51D1\uFF08640\u00D7600\uFF09\n </button>\n <button\n type=\"button\"\n style={settings.panelWidth === 1040 && settings.panelHeight === 760 ? pillActive : pill}\n onClick={() => {\n actions.setField(PANEL_WIDTH_FIELD, 1040)\n actions.setField(PANEL_HEIGHT_FIELD, 760)\n }}\n >\n \u5BBD\u655E\uFF081040\u00D7760\uFF09\n </button>\n </div>\n </FoldCard>\n\n <FoldCard name=\"OpenCode \u8BF7\u6C42\u5934\" summary={headerSummary}>\n <p style={bodyLead}>\n OpenCode \u7684\u63A5\u53E3\u8981\u6C42\u5BA2\u6237\u7AEF\u6BCF\u6B21\u8BF7\u6C42\u90FD\u5E26\u4E0A\u4E00\u4E2A\u7A33\u5B9A\u7684\u4F1A\u8BDD ID \u8BF7\u6C42\u5934\uFF08\u5B98\u65B9 Go \u6587\u6863\n \u300C\u53EF\u4EE5\u5728\u54EA\u91CC\u4F7F\u7528\uFF1F\u300D\u7B2C 3 \u6761\uFF1A\u4E3A\u6BCF\u6BB5\u5BF9\u8BDD\u5728 x-opencode-session \u4E2D\u53D1\u9001\u4F1A\u8BDD ID\uFF0C\n \u4EE5\u4FBF\u5176\u4F18\u5316\u8DEF\u7531\u4E0E\u63D0\u793A\u8BCD\u7F13\u5B58\uFF09\u3002DSH \u7684\u8BBE\u7F6E\u9875\u4E0D\u63D0\u4F9B\u8BF7\u6C42\u5934\u7F16\u8F91\u5668\uFF0C\u6240\u4EE5\u8FD9\u91CC\u76F4\u63A5\u628A\u5B83\u5199\u8FDB\n llm-pi-ai \u7684 provider \u914D\u7F6E\u2014\u2014\u4E0B\u4E00\u6B21\u6A21\u578B\u8BF7\u6C42\u5C31\u751F\u6548\uFF0C\u4E0D\u7528\u91CD\u542F\uFF0C\u4E5F\u4E0D\u7528\u624B\u5DE5\u6539 settings.yaml\u3002\n \u53EA\u5BF9 llm-pi-ai \u91CC\u300C\u5DF2\u5B58\u5728\u300D\u7684 opencode \u7CFB\u8DEF\u7531\u751F\u6548\uFF0C\u4E0D\u4F1A\u51ED\u7A7A\u65B0\u5EFA provider\uFF1B\n \u603B\u5F00\u5173\u5173\u95ED\u6216\u672C\u680F\u76EE\u505C\u7528\u65F6\uFF0C\u5199\u5165\u7684\u5934\u4F1A\u81EA\u52A8\u64A4\u9500\u3002\n </p>\n <ToggleRow\n first\n label=\"\u9644\u52A0\u8BF7\u6C42\u5934\"\n desc=\"\u6253\u5F00\u5373\u5199\u5165\uFF0C\u5E76\u5728\u6BCF\u6B21\u542F\u52A8\u65F6\u8865\u9F50\uFF1B\u5173\u95ED\u5373\u64A4\u9500\"\n checked={settings.headerEnabled}\n onChange={next => { actions.setField(HEADER_ENABLED_FIELD, next) }}\n />\n <TextFieldRow\n title=\"\u5934\u540D\"\n desc={`\u9ED8\u8BA4 ${DEFAULT_HEADER_NAME}\uFF08OpenCode \u5B98\u65B9\u8981\u6C42\u7684\u90A3\u4E00\u4E2A\uFF09`}\n value={settings.headerName}\n placeholder={DEFAULT_HEADER_NAME}\n maxLength={HEADER_NAME_MAX}\n onChange={next => { actions.setField(HEADER_NAME_FIELD, next) }}\n />\n <TextFieldRow\n title=\"\u503C\"\n desc=\"\u6240\u6709\u5BF9\u8BDD\u5171\u7528\u8FD9\u4E00\u4E2A\u503C\uFF1B\u7559\u7A7A\u65F6\u9996\u6B21\u542F\u7528\u4F1A\u81EA\u52A8\u751F\u6210\u4E00\u4E2A UUID \u5E76\u4FDD\u5B58\u6CBF\u7528\"\n value={settings.headerValue}\n placeholder=\"\u7559\u7A7A = \u81EA\u52A8\u751F\u6210\"\n maxLength={HEADER_VALUE_MAX}\n onChange={next => { actions.setField(HEADER_VALUE_FIELD, next) }}\n action={{\n label: '\u91CD\u65B0\u751F\u6210',\n onClick: () => { actions.setField(HEADER_VALUE_FIELD, newSessionId()) },\n }}\n />\n <TextFieldRow\n title=\"\u4F5C\u7528\u8DEF\u7531\"\n desc=\"\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u7559\u7A7A = \u81EA\u52A8\u5339\u914D OpenCode \u8DEF\u7531\uFF08\u540D\u5B57\u4EE5 opencode \u5F00\u5934\uFF0C\u6216 baseURL \u6307\u5411 opencode.ai\uFF09\"\n value={settings.headerRoutes}\n placeholder=\"\u7559\u7A7A = \u81EA\u52A8\uFF08opencode* \u6216 opencode.ai \u7AEF\u70B9\uFF09\"\n maxLength={HEADER_VALUE_MAX}\n onChange={next => { actions.setField(HEADER_ROUTES_FIELD, next) }}\n />\n <p style={hintInfo}>\u72B6\u6001\uFF1A{headerStatusText}</p>\n </FoldCard>\n </>)}\n </div>\n )\n}\n", "/**\n * \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6309\u94AE\uFF1A\u5750\u5728\u5B98\u65B9\u8F93\u5165\u5361\u7247\u5DE5\u5177\u884C\u91CC\u300C\u5C55\u5F00\u300D\u6309\u94AE\u7684\u65C1\u8FB9\n * \uFF08\u69FD\u4F4D `conversation.input.right`\uFF0Corder 89 < \u5C55\u5F00\u7684 90\uFF09\uFF0C\u5F62\u72B6\u4E0E\u5B83\u540C\u6B3E\u80F6\u56CA\u3002\n *\n * \u672C\u7EC4\u4EF6\u53EA\u505A\u4E09\u4EF6\u4E8B\uFF1A\n * 1. \u628A\u5B98\u65B9\u7684 `inputActions` \u4E0E\u5F53\u524D\u8349\u7A3F\u6295\u9012\u7ED9 quick-commands \u6865\u63A5\n * \uFF08\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\u7684\u53D1\u9001\u62E6\u622A\u5FC5\u987B\u62FF\u5230\u5B83\u4EEC\uFF0C\u62E6\u622A\u5668\u6D3B\u5728 React \u4E4B\u5916\uFF09\uFF1B\n * 2. \u6E32\u67D3\u6309\u94AE\u3001\u70B9\u51FB\u540E\u628A\u81EA\u8EAB\u77E9\u5F62\u4EA4\u7ED9\u9762\u677F\u505A\u951A\u70B9\uFF1B\n * 3. \u628A\u9762\u677F\u7684\u5F00\u5408\u72B6\u6001\u53CD\u5C04\u5230 `aria-expanded`\u3002\n */\nimport React, { useEffect, useRef } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { ComposerUxSettings } from '../settings-contract.ts'\nimport { publishInputBridge, releaseInputBridge, type InputActionsLike } from './quick-commands.ts'\nimport { QUICK_BUTTON_CLASS } from './quick-style.ts'\n\n/** \u9762\u677F\u951A\u70B9\uFF1A\u6309\u94AE\u7684\u89C6\u53E3\u77E9\u5F62\uFF08\u9762\u677F\u636E\u6B64\u8D34\u5728\u4E0A\u65B9\uFF09\u3002 */\nexport interface QuickPanelAnchor {\n readonly left: number\n readonly bottom: number\n readonly width: number\n}\n\n/** \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u6CE8\u5165\u9762\u3002 */\nexport interface QuickCommandsInjected {\n hooks: {\n /** \u5F53\u524D\u8BBE\u7F6E\uFF08\u603B\u5F00\u5173\u4E0E\u5FEB\u6377\u6307\u4EE4\u5217\u8868\uFF09\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n /** \u9762\u677F\u951A\u70B9\uFF1Bnull = \u9762\u677F\u5173\u95ED\u3002 */\n panel: SnapshotStore<QuickPanelAnchor | null>\n }\n actions: {\n /** \u4EE5\u7ED9\u5B9A\u951A\u70B9\u6253\u5F00\u9762\u677F\uFF1B\u5DF2\u5F00\u5219\u5173\u95ED\uFF08\u70B9\u6309\u94AE\u5373\u5F00\u5408\uFF09\u3002 */\n toggle: (anchor: QuickPanelAnchor) => void\n }\n}\n\nexport type QuickCommandsButtonProps =\n PropsRuntime<'conversation.input.right'>\n & InjectFace<QuickCommandsInjected>\n\n/** \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5165\u53E3\u6309\u94AE\u3002 */\nexport function QuickCommandsButton({\n useInput, inputActions, sessionId, useLive, usePanel, actions,\n}: QuickCommandsButtonProps) {\n const settings = useLive(item => item)\n const anchor = usePanel(item => item)\n const draft = useInput(state => state.draft)\n const ref = useRef<HTMLButtonElement | null>(null)\n\n // \u6BCF\u6B21\u6E32\u67D3\u628A\u5B98\u65B9\u8F93\u5165\u52A8\u4F5C\u4E0E\u8349\u7A3F\u6295\u9012\u7ED9\u6865\u63A5\uFF1A\u62E6\u622A\u5668\u8981\u5728 React \u4E4B\u5916\u8BFB\u5B83\u4EEC\u3002\n useEffect(() => {\n const sid = typeof sessionId === 'string' ? sessionId : ''\n publishInputBridge({\n actions: (inputActions ?? null) as InputActionsLike | null,\n draft: typeof draft === 'string' ? draft : '',\n sessionId: sid,\n })\n return () => { releaseInputBridge(sid) }\n }, [inputActions, draft, sessionId])\n\n if (settings.enabled !== true) return null\n\n const open = anchor !== null\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={QUICK_BUTTON_CLASS}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n title=\"\u5FEB\u6377\u6307\u4EE4\uFF1A\u4E00\u952E\u63D2\u5165\u5E38\u7528\u63D0\u793A\u8BCD\uFF0C\u6216\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4F18\u5316\u6210\u4E00\u6761\u6E05\u6670\u7684\u6307\u4EE4\"\n // \u6837\u5F0F\u5168\u90E8\u6765\u81EA\u6CE8\u5165\u7684\u6837\u5F0F\u8868\uFF08\u89C1 quick-style.ts\uFF09\uFF1A\u4E0E\u65C1\u8FB9\u5B98\u65B9\u300C\u5C55\u5F00\u300D\u6309\u94AE\n // \u9010\u9879\u5BF9\u9F50\uFF0C\u4E14 hover / \u5C55\u5F00\u6001\u53EA\u6709\u6837\u5F0F\u8868\u80FD\u8868\u8FBE\u3002\n // \u4E0D\u8BA9\u6309\u94AE\u62A2\u8D70\u62D6\u52A8\u65F6\u53EF\u80FD\u5B58\u5728\u7684\u8F93\u5165\u6846\u9009\u533A\uFF08\u4E0E\u5B98\u65B9\u5DE5\u5177\u884C\u4E00\u81F4\uFF09\u3002\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => {\n const rect = ref.current?.getBoundingClientRect()\n actions.toggle({\n left: rect?.left ?? 0,\n bottom: rect?.bottom ?? 0,\n width: rect?.width ?? 0,\n })\n }}\n >\n <svg\n viewBox=\"0 0 16 16\"\n width=\"12\"\n height=\"12\"\n aria-hidden\n >\n <path\n d=\"M9.2 1.2 3.4 9.1h3.5l-0.9 5.7 6-8.1H8.4l0.8-5.5Z\"\n fill=\"currentColor\"\n />\n </svg>\n <span>\u5FEB\u6377\u6307\u4EE4</span>\n </button>\n )\n}\n", "/**\n * \u300C\u5FEB\u6377\u6307\u4EE4\u300D\u5C55\u5F00\u9762\u677F\uFF1A\u6CE8\u518C\u8FDB shell.overlay\uFF08root \u7EA7\u6D6E\u5C42\uFF0C\u4E0D\u53D7\u8F93\u5165\u5361\u7247\u88C1\u526A\uFF09\u3002\n *\n * \u9762\u677F\u5F62\u6001\uFF080.3.0 \u8D77\u662F**\u5206\u7C7B\u4E24\u7EA7**\u7ED3\u6784\uFF09\uFF1A\n * - \u9876\u90E8\uFF1A\u300C\u2728 \u4F18\u5316\u63D0\u793A\u8BCD\u300D\u4E3B\u6309\u94AE + \u4E09\u6863\u5F3A\u5EA6\u5206\u6BB5\u63A7\u4EF6\uFF1B\n * - \u5206\u7C7B\u884C\uFF1A\u4E00\u4E2A\u5206\u7C7B\u4E00\u4E2A\u6807\u7B7E\uFF0C\u70B9\u5B83\u5207\u6362\uFF1B\u300C\uFF0B \u65B0\u5206\u7C7B\u300D\u76F4\u63A5\u52A0\u4E00\u4E2A\uFF08\u6539\u540D/\u5220\u9664\u5728\u8BBE\u7F6E\u9875\uFF0C\n * \u9762\u677F\u4FDD\u6301\u8F7B\u91CF\uFF0C\u907F\u514D\u5728\u8FD9\u91CC\u585E\u4E00\u5957\u91CD\u547D\u540D UI\uFF09\uFF1B\n * - \u4E2D\u90E8\uFF1A\u5F53\u524D\u5206\u7C7B\u7684\u6761\u76EE \u2014\u2014 \u70B9\u6761\u76EE\u628A\u5185\u5BB9\u63D2\u5165\u8F93\u5165\u6846\uFF0C\u53F3\u4FA7\u52FE\u9009\u6846\u662F\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\n * \uFF08\u52FE\u4E0A\u540E\u70B9\u53D1\u9001\u65F6\u81EA\u52A8\u9644\u52A0\u5230\u6D88\u606F\u672B\u5C3E\uFF0C**\u8DE8\u5206\u7C7B\u751F\u6548**\uFF09\uFF1B\n * - \u5E95\u90E8\uFF1A\u72B6\u6001\u63D0\u793A + \u6307\u8DEF\u8BBE\u7F6E\u9875\u3002\n */\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n DEFAULT_CATEGORY_NAME, OPTIMIZER_TIERS, QUICK_CATEGORY_MAX,\n type ComposerUxSettings, type OptimizerTier, type QuickPromptBook,\n} from '../settings-contract.ts'\nimport { bookCounts } from './prompt-book.ts'\nimport type { QuickPanelAnchor } from './QuickCommandsButton.tsx'\nimport {\n quickAlwaysBox, quickAlwaysLabel, quickCategoryAdd, quickCategoryRow, quickCategoryTab,\n quickCategoryTabActive, quickEmpty, quickFootHint, quickItem, quickItemLabel,\n quickItemPreview, quickList, quickNotice, quickPanel, quickPanelFoot, quickPanelHead,\n quickPanelTitle, quickPanelTitleRow, quickPrimaryButton, quickPrimaryButtonDisabled,\n quickTierButton, quickTierButtonActive, quickTierRow,\n} from './styles.ts'\n\n/** \u9762\u677F\u6CE8\u5165\u9762\u3002 */\nexport interface QuickPanelInjected {\n hooks: {\n /** \u5F53\u524D\u8BBE\u7F6E\uFF08\u6863\u4F4D + \u603B\u5F00\u5173\uFF09\u3002 */\n live: SnapshotStore<ComposerUxSettings>\n /** \u9762\u677F\u951A\u70B9\uFF1Bnull = \u9762\u677F\u5173\u95ED\u3002 */\n panel: SnapshotStore<QuickPanelAnchor | null>\n /** \u662F\u5426\u6709\u4E00\u6B21\u4F18\u5316\u5728\u98DE\u3002 */\n busy: SnapshotStore<boolean>\n /** \u9762\u677F\u72B6\u6001\u63D0\u793A\uFF08\u7A7A\u4E32 = \u65E0\uFF09\u3002 */\n notice: SnapshotStore<string>\n /** \u5FEB\u6377\u6307\u4EE4\u672C\uFF08\u771F\u76F8\u5728\u78C1\u76D8\u90A3\u4EFD quick-prompts.json\uFF09\u3002 */\n book: SnapshotStore<QuickPromptBook>\n /** '' = \u6B63\u5E38\uFF1B'saving' = \u6B63\u5728\u5199\uFF1B\u5176\u4F59 = \u4E0A\u4E00\u6B21\u7684\u9519\u8BEF\u6587\u6848\u3002 */\n bookStatus: SnapshotStore<string>\n }\n actions: {\n /** \u5173\u95ED\u9762\u677F\u3002 */\n close: () => void\n /** \u628A\u4E00\u6BB5\u6587\u672C\u63D2\u8FDB\u8F93\u5165\u6846\u3002 */\n insert: (text: string) => void\n /** \u7528\u5F53\u524D\u8F93\u5165\u6846\u5185\u5BB9\u8DD1\u4E00\u6B21\u4F18\u5316\uFF0C\u7ED3\u679C\u5199\u56DE\u8F93\u5165\u6846\u3002 */\n optimize: () => void\n /** \u5207\u6362\u4F18\u5316\u6863\u4F4D\u3002 */\n setTier: (tier: OptimizerTier) => void\n /** \u52FE\u9009/\u53D6\u6D88\u67D0\u6761\u7684\u300C\u9ED8\u8BA4\u63D2\u5165\u300D\uFF08\u6309 id \u8DE8\u5206\u7C7B\u627E\uFF09\u3002 */\n setAlways: (id: string, value: boolean) => void\n /** \u65B0\u589E\u4E00\u4E2A\u5206\u7C7B\uFF08\u540D\u5B57\u7531\u8BBE\u7F6E\u9875\u518D\u6539\uFF09\u3002 */\n addCategory: (name: string) => void\n /** \u4ECE\u78C1\u76D8\u91CD\u8BFB\uFF08\u6587\u4EF6\u88AB\u624B\u5DE5\u6539\u8FC7\u65F6\u7684\u515C\u5E95\uFF09\u3002 */\n reloadBook: () => void\n }\n}\n\nexport type QuickCommandsPanelProps =\n PropsRuntime<'shell.overlay'>\n & InjectFace<QuickPanelInjected>\n\n/** \u4E0E\u89C6\u53E3\u8FB9\u754C\u4FDD\u6301\u7684\u95F4\u8DDD\u3002 */\nconst MARGIN = 8\n/** \u9762\u677F\u4E0E\u951A\u70B9\u6309\u94AE\u4E4B\u95F4\u7684\u95F4\u8DDD\u3002 */\nconst GAP = 8\n\n/** \u5C55\u5F00\u9762\u677F\u3002 */\nexport function QuickCommandsPanel({\n useLive, usePanel, useBusy, useNotice, useBook, useBookStatus, actions,\n}: QuickCommandsPanelProps) {\n const settings = useLive(item => item)\n const anchor = usePanel(item => item)\n const busy = useBusy(item => item)\n const notice = useNotice(item => item)\n const book = useBook(item => item)\n const status = useBookStatus(item => item)\n const ref = useRef<HTMLDivElement | null>(null)\n const [position, setPosition] = useState<{ left: number; top: number } | null>(null)\n const [activeId, setActiveId] = useState('')\n\n const counts = bookCounts(book)\n const categories = book.categories\n const active = categories.find(category => category.id === activeId) ?? categories[0]\n\n // \u8D34\u951A\u70B9\u6309\u94AE\u4E0A\u65B9\uFF1B\u653E\u4E0D\u4E0B\u5C31\u7FFB\u5230\u4E0B\u65B9\uFF1B\u5DE6\u53F3\u94B3\u5236\u5728\u89C6\u53E3\u5185\u3002\n useLayoutEffect(() => {\n if (anchor === null) {\n setPosition(null)\n return\n }\n const el = ref.current\n const height = el === null ? 320 : el.getBoundingClientRect().height\n const width = el === null ? 420 : el.getBoundingClientRect().width\n const left = Math.max(MARGIN, Math.min(anchor.left, window.innerWidth - width - MARGIN))\n const above = anchor.bottom - height - GAP\n const top = above >= MARGIN ? above : Math.min(anchor.bottom + GAP, window.innerHeight - height - MARGIN)\n setPosition({ left, top: Math.max(MARGIN, top) })\n }, [anchor?.left, anchor?.bottom, counts.prompts, categories.length, busy])\n\n // \u5916\u90E8\u70B9\u51FB / Escape / \u6EDA\u52A8 / \u7F29\u653E\u65F6\u5173\u95ED\uFF08\u4E0E\u53F3\u952E\u83DC\u5355\u540C\u4E00\u5957\u89C4\u5219\uFF09\u3002\n useEffect(() => {\n if (anchor === null) return\n const onPointerDown = (event: PointerEvent): void => {\n if (ref.current !== null && event.target instanceof Node && ref.current.contains(event.target)) return\n // \u70B9\u5165\u53E3\u6309\u94AE\u672C\u8EAB\u7531\u5B83\u81EA\u5DF1 toggle\uFF0C\u8FD9\u91CC\u8BA9\u8DEF\uFF0C\u514D\u5F97\u300C\u5173\u4E86\u53C8\u5F00\u300D\u3002\n if (event.target instanceof Element && event.target.closest('.composer-ux-quick-button') !== null) return\n actions.close()\n }\n const onEscape = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n event.preventDefault()\n event.stopPropagation()\n actions.close()\n }\n window.addEventListener('pointerdown', onPointerDown, true)\n window.addEventListener('keydown', onEscape, true)\n window.addEventListener('resize', actions.close)\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, true)\n window.removeEventListener('keydown', onEscape, true)\n window.removeEventListener('resize', actions.close)\n }\n }, [anchor === null, actions])\n\n if (anchor === null) return null\n\n const tier = settings.optimizerTier\n const items = active?.prompts ?? []\n const failure = status !== '' && status !== 'saving' ? status : ''\n\n return (\n <div\n ref={ref}\n role=\"dialog\"\n aria-label=\"\u5FEB\u6377\u6307\u4EE4\"\n style={{ ...quickPanel, left: position?.left ?? anchor.left, top: position?.top ?? anchor.bottom }}\n >\n <div style={quickPanelHead}>\n <div style={quickPanelTitleRow}>\n <span style={quickPanelTitle}>\u5FEB\u6377\u6307\u4EE4</span>\n <div style={quickTierRow} role=\"group\" aria-label=\"\u4F18\u5316\u5F3A\u5EA6\">\n {OPTIMIZER_TIERS.map(item => (\n <button\n key={item.id}\n type=\"button\"\n title={item.hint}\n aria-pressed={tier === item.id}\n style={tier === item.id ? quickTierButtonActive : quickTierButton}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { actions.setTier(item.id) }}\n >\n {item.label}\n </button>\n ))}\n </div>\n </div>\n <button\n type=\"button\"\n disabled={busy}\n title=\"\u628A\u8F93\u5165\u6846\u91CC\u7684\u8BDD\u4EA4\u7ED9\u53E6\u4E00\u4E2A AI \u6574\u7406\u6210\u4E00\u6761\u53EF\u4EE5\u76F4\u63A5\u53D1\u51FA\u53BB\u7684\u6E05\u6670\u6307\u4EE4\uFF0C\u7ED3\u679C\u76F4\u63A5\u5199\u56DE\u8F93\u5165\u6846\"\n style={busy ? quickPrimaryButtonDisabled : quickPrimaryButton}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { actions.optimize() }}\n >\n <span aria-hidden>\u2728</span>\n <span>{busy ? '\u4F18\u5316\u4E2D\u2026' : '\u4F18\u5316\u63D0\u793A\u8BCD'}</span>\n </button>\n <div style={quickCategoryRow}>\n {categories.map(category => (\n <button\n key={category.id}\n type=\"button\"\n title={`${category.name}\uFF08${String(category.prompts.length)} \u6761\uFF09`}\n aria-pressed={category.id === active?.id}\n style={category.id === active?.id ? quickCategoryTabActive : quickCategoryTab}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { setActiveId(category.id) }}\n >\n {category.name}\n </button>\n ))}\n <button\n type=\"button\"\n style={quickCategoryAdd}\n disabled={categories.length >= QUICK_CATEGORY_MAX}\n title=\"\u65B0\u589E\u4E00\u4E2A\u5206\u7C7B\uFF08\u540D\u5B57\u5230\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C\u300D\u91CC\u6539\uFF09\"\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => {\n actions.addCategory(DEFAULT_CATEGORY_NAME)\n }}\n >\n \uFF0B\n </button>\n </div>\n </div>\n\n <div style={quickList}>\n {items.length === 0 && (\n <div style={quickEmpty}>\n \u8FD9\u4E2A\u5206\u7C7B\u91CC\u8FD8\u6CA1\u6709\u6761\u76EE\u3002<br />\n \u5728\u300C\u8BBE\u7F6E \u2192 \u8F93\u5165\u4F53\u9A8C \u2192 \u5FEB\u6377\u6307\u4EE4\u6E05\u5355\u300D\u91CC\u6DFB\u52A0\u3002\n </div>\n )}\n {items.map(item => (\n <div key={item.id} style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <button\n type=\"button\"\n title={item.prompt}\n style={quickItem}\n onMouseDown={event => { event.preventDefault() }}\n onClick={() => { actions.insert(item.prompt) }}\n >\n <span style={quickItemLabel}>{item.label}</span>\n <span style={quickItemPreview}>{item.prompt.replace(/\\s+/g, ' ')}</span>\n </button>\n <label style={quickAlwaysLabel} title=\"\u52FE\u4E0A\u540E\uFF0C\u70B9\u53D1\u9001\u65F6\u8FD9\u6761\u63D0\u793A\u8BCD\u4F1A\u81EA\u52A8\u9644\u52A0\u5230\u4F60\u7684\u6D88\u606F\u672B\u5C3E\uFF08\u5BF9\u6240\u6709\u5206\u7C7B\u751F\u6548\uFF09\">\n <input\n type=\"checkbox\"\n style={quickAlwaysBox}\n checked={item.always}\n onChange={event => { actions.setAlways(item.id, event.target.checked) }}\n />\n \u9ED8\u8BA4\u63D2\u5165\n </label>\n </div>\n ))}\n </div>\n\n <div style={quickPanelFoot}>\n <span style={quickNotice} role=\"status\">{notice !== '' ? notice : failure}</span>\n <span\n style={quickFootHint}\n title=\"\u6570\u636E\u5728 ~/.dsh/quick-prompts.json\"\n >\n {counts.categories} \u5206\u7C7B \u00B7 {counts.prompts} \u6761\n </span>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["row", "name", "row", "row", "name", "text", "React", "import_react", "import_jsx_runtime", "import_react", "import_jsx_runtime", "import_react", "import_jsx_runtime", "state", "import_react", "import_jsx_runtime", "menu", "name", "state"]
|
|
7
7
|
}
|