dsh-composer-ux 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/client.tsx", "../src/settings-contract.ts", "../src/client/chords.ts", "../src/client/interceptors.ts", "../src/client/panel.ts", "../src/client/settings-style.ts", "../src/client/ContextMenuHost.tsx", "../src/client/styles.ts", "../src/client/PanelResizeHandles.tsx", "../src/client/SettingsSection.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, PANEL_SCROLL_FIELD, PANEL_RESIZE_FIELD, PANEL_WIDTH_FIELD,\n PANEL_HEIGHT_FIELD, SEND_KEY_FIELD, sanitizeSettings,\n type ComposerUxSettings, type MenuState, 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 { ContextMenuHost } from './client/ContextMenuHost.tsx'\nimport { PanelResizeHandles } from './client/PanelResizeHandles.tsx'\nimport { SettingsSection } from './client/SettingsSection.tsx'\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\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: boolean | string | number): void => {\n void scope.set(field, value).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 ].map(field => ({ op: 'unset', path: [field] })),\n ).catch((error: unknown) => {\n console.error('[composer-ux] settings reset failed', error)\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 // \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 // \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 }\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 }\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 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 \u7CFB\u8DEF\u7531\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/** \u4F5C\u7528\u8DEF\u7531\u7684\u81EA\u52A8\u5339\u914D\u524D\u7F00\uFF1A`providers` \u91CC\u4EE5\u5B83\u5F00\u5934\u7684\u8DEF\u7531\u3002 */\nexport const OPENCODE_ROUTE_PREFIX = 'opencode'\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 | 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}\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}\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 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 }\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", "/** \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 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/** \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 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 window.addEventListener('keydown', onKeyDown, true)\n window.addEventListener('contextmenu', onContextMenu, true)\n return () => {\n window.removeEventListener('keydown', onKeyDown, true)\n window.removeEventListener('contextmenu', onContextMenu, 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", "/**\n * \u8BBE\u7F6E\u9762\u677F\u589E\u5F3A\uFF1A\u5BFC\u822A\u5217\u6EDA\u52A8\u6837\u5F0F + \u9762\u677F\u5B9A\u4F4D/\u5C3A\u5BF8\u5DE5\u5177\u3002\n *\n * \u5B98\u65B9\u9762\u677F\u7ED3\u6784\uFF08ui-settings-general SettingsPanel\uFF09\uFF1A\n * [role=\"dialog\"][aria-modal=\"true\"] \u2500\u2500 .panel\uFF08width:800, overflow:hidden\uFF09\n * \u251C\u2500\u2500 <nav> \u2500\u2500 \u6807\u9898 + navList\uFF08\u6761\u76EE\u8F83\u591A\u65F6\u6EA2\u51FA\u4E14\u4E0D\u53EF\u6EDA\u52A8\uFF09\n * \u2514\u2500\u2500 <div> \u2500\u2500 header + .options\uFF08\u672C\u8EAB overflow-y:auto\uFF09\n *\n * \u91C7\u7528\u7A33\u5B9A\u7ED3\u6784\u9009\u62E9\u5668\uFF08role/aria + \u76F4\u63A5\u5B50\u5143\u7D20 nav\uFF09\uFF0CCSS Modules \u54C8\u5E0C\u7C7B\u540D\n * \u4E0D\u53EF\u4F9D\u8D56\u3002\u6EDA\u52A8\u6837\u5F0F\u901A\u8FC7 <html> \u4E0A\u7684\u7C7B\u95E8\u63A7\uFF0C\u968F\u8BBE\u7F6E\u5F00\u5173\u5373\u65F6\u5207\u6362\u3002\n */\n\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\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 */\nexport const PANEL_SELECTOR = '[role=\"dialog\"][aria-modal=\"true\"]:has(> nav)'\n\n/** \u6CE8\u5165\u7684\u6EDA\u52A8/\u6EDA\u52A8\u6761\u6837\u5F0F\uFF08\u7531 html.dsh-ux-panel-scroll \u95E8\u63A7\uFF09\u3002 */\nconst PANEL_CSS = `\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) { min-height: 320px; }\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav {\n min-height: 0;\n}\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-width: thin;\n}\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar {\n width: 8px;\n}\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb {\n background: var(--dsh-scrollbar-thumb, var(--dsw-alias-scrollbar-bg-l2));\n border-radius: 8px;\n}\nhtml.dsh-ux-panel-scroll [role=\"dialog\"][aria-modal=\"true\"]:has(> nav) > nav > div:last-child::-webkit-scrollbar-thumb:hover {\n background: var(--dsh-scrollbar-thumb-hover, var(--dsw-alias-scrollbar-hover-l2));\n}\n`\n\n/** \u6CE8\u5165\u6837\u5F0F\u8868\u5E76\u540C\u6B65\u6EDA\u52A8\u5F00\u5173\u5230 <html> \u7C7B\uFF08\u968F\u8BBE\u7F6E\u53D8\u5316\u5373\u65F6\u66F4\u65B0\uFF09\uFF1B\u8FD4\u56DE\u5378\u8F7D\u5668\u3002 */\nexport function installPanelStyle(\n settings: () => boolean,\n subscribe: (listener: () => void) => () => void,\n): () => void {\n const tag = document.createElement('style')\n tag.dataset.plugin = 'dsh-composer-ux-panel'\n tag.textContent = PANEL_CSS\n document.head.appendChild(tag)\n const applyClass = (): void => {\n document.documentElement.classList.toggle('dsh-ux-panel-scroll', settings())\n }\n applyClass()\n const unsubscribe = subscribe(applyClass)\n return () => {\n unsubscribe()\n tag.remove()\n document.documentElement.classList.remove('dsh-ux-panel-scroll')\n }\n}\n\n/** \u67E5\u8BE2\u5F53\u524D\u6253\u5F00\u7684\u8BBE\u7F6E\u5BF9\u8BDD\u6846\u3002 */\nexport function findSettingsPanel(): HTMLElement | null {\n return document.querySelector<HTMLElement>(PANEL_SELECTOR)\n}\n\n/** \u5C3A\u5BF8\u8303\u56F4\u94B3\u5236\uFF08\u4E0E host schema \u4E00\u81F4\uFF09\u3002 */\nexport function clampPanelWidth(width: number): number {\n return Math.max(560, Math.min(width, Math.max(800, window.innerWidth - 48)))\n}\n\nexport function clampPanelHeight(height: number): number {\n return Math.max(320, Math.min(height, Math.max(400, window.innerHeight - 48)))\n}\n\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 */\nexport function persistPanelSize(\n width: number,\n height: number,\n setField: (field: string, value: boolean | number) => void,\n): void {\n setField('panelWidth', clampPanelWidth(width))\n setField('panelHeight', clampPanelHeight(height))\n}\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 * \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 * \u8BBE\u7F6E\u9762\u677F\u8FB9\u7F18\u62D6\u62FD\u624B\u67C4\uFF1A\u6CE8\u518C\u8FDB shell.overlay\uFF08root \u7EA7\uFF09\uFF0C\u4EC5\u5728\u8BBE\u7F6E\u5BF9\u8BDD\u6846\n * \u6253\u5F00\u4E14\u300C\u8FB9\u7F18\u8C03\u6574\u5927\u5C0F\u300D\u5F00\u5173\u5F00\u542F\u65F6\u6E32\u67D3 8 \u6761\u624B\u67C4\uFF08\u56DB\u8FB9 + \u56DB\u89D2\uFF09\u3002\n * \u62D6\u62FD\u53EA\u6539\u5BF9\u8BDD\u6846\u5185\u8054 width/height\uFF08\u9762\u677F\u7531 overlay flex \u5C45\u4E2D\uFF0C\u65E0\u9700\u79FB\u52A8\n * \u5B9A\u4F4D\uFF09\uFF1B\u677E\u624B\u65F6\u628A\u5C3A\u5BF8\u5199\u5165\u8BBE\u7F6E\u6301\u4E45\u5316\u3002\n */\nimport React, { useEffect, 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 { PANEL_HEIGHT_FIELD, PANEL_WIDTH_FIELD, type ComposerUxSettings } from '../settings-contract.ts'\nimport {\n clampPanelHeight, clampPanelWidth, findSettingsPanel,\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\ntype Edge = 'left' | 'right' | 'top' | 'bottom' | 'tl' | 'tr' | 'bl' | 'br'\n\ninterface StripRect {\n readonly left: number\n readonly top: number\n readonly width: number\n readonly height: number\n readonly cursor: string\n}\n\nfunction stripRect(edge: Edge, rect: DOMRect): StripRect {\n const horizontal = (left: number, width: number): StripRect => ({\n left, top: rect.top + 12, width, height: Math.max(0, rect.height - 24), cursor: 'ew-resize',\n })\n const vertical = (top: number, height: number): StripRect => ({\n left: rect.left + 16, top, width: Math.max(0, rect.width - 32), height, cursor: 'ns-resize',\n })\n const corner = (left: number, top: number, horizontalCursor: string, verticalCursor: string): StripRect => ({\n left, top, width: 18, height: 18, cursor: horizontalCursor,\n })\n const corners: Record<'tl' | 'tr' | 'bl' | 'br', string> = {\n tl: 'nwse-resize', tr: 'nesw-resize', bl: 'nesw-resize', br: 'nwse-resize',\n }\n switch (edge) {\n case 'left': return horizontal(rect.left - 4, 8)\n case 'right': return horizontal(rect.right - 4, 8)\n case 'top': return vertical(rect.top - 4, 8)\n case 'bottom': return vertical(rect.bottom - 4, 8)\n case 'tl': return corner(rect.left - 6, rect.top - 6, corners.tl, 'nwse')\n case 'tr': return corner(rect.right - 12, rect.top - 6, corners.tr, 'nesw')\n case 'bl': return corner(rect.left - 6, rect.bottom - 14, corners.bl, 'nesw')\n case 'br': return corner(rect.right - 12, rect.bottom - 14, corners.br, 'nwse')\n }\n}\n\n/** \u6E32\u67D3\u8BBE\u7F6E\u9762\u677F\u8FB9\u7F18\u624B\u67C4\uFF1B\u65E0\u9762\u677F\u3001\u603B\u5F00\u5173\u5173\u95ED\u6216\u5F00\u5173\u5173\u95ED\u65F6\u8FD4\u56DE null\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 // \u63A2\u6D4B\u8F6E\u8BE2\u95ED\u5305\u53EA\u6302\u5728 enabled \u4E0A\uFF0C\u9700\u7ECF ref \u8BFB\u6700\u65B0\u503C\uFF0C\u907F\u514D\u6355\u83B7\u9648\u65E7\u5FEB\u7167\u3002\n const settingsRef = useRef(settings)\n settingsRef.current = settings\n const enabled = settings.enabled === true && settings.panelResize === true\n const [rect, setRect] = useState<DOMRect | null>(null)\n const appliedRef = useRef(false)\n\n // \u63A2\u6D4B\u8BBE\u7F6E\u5BF9\u8BDD\u6846\u51FA\u73B0/\u6D88\u5931\uFF08250ms \u8F6E\u8BE2\u8DB3\u591F\u4FBF\u5B9C\uFF0C\u4E14\u89C4\u907F React \u65E0\u6CD5\u611F\u77E5\n // \u7684 shell \u5143\u7D20\u6302\u8F7D\u4E8B\u4EF6\uFF09\uFF1B\u7A97\u53E3\u5C3A\u5BF8\u53D8\u5316\u65F6\u540C\u6B65\u5237\u65B0\u3002\n useEffect(() => {\n if (!enabled) {\n setRect(null)\n return\n }\n const probe = (): void => {\n const panel = findSettingsPanel()\n if (panel === null) {\n appliedRef.current = false\n setRect(current => (current === null ? null : null))\n return\n }\n // \u6253\u5F00\u77AC\u95F4\u5957\u7528\u4E00\u6B21\u6301\u4E45\u5316\u5C3A\u5BF8\u3002\n if (!appliedRef.current) {\n appliedRef.current = true\n const width = settingsRef.current.panelWidth\n const height = settingsRef.current.panelHeight\n if (width !== undefined) panel.style.width = `${clampPanelWidth(width)}px`\n if (height !== undefined) panel.style.height = `${clampPanelHeight(height)}px`\n }\n setRect(panel.getBoundingClientRect())\n }\n probe()\n const timer = setInterval(probe, 250)\n const onResize = (): void => { setRect(current => current === null ? null : findSettingsPanel()?.getBoundingClientRect() ?? null) }\n window.addEventListener('resize', onResize)\n return () => { clearInterval(timer); window.removeEventListener('resize', onResize) }\n }, [enabled])\n\n if (!enabled || rect === null) return null\n\n const onPointerDown = (edge: Edge, event: React.PointerEvent): void => {\n event.preventDefault()\n event.stopPropagation()\n const panel = findSettingsPanel()\n if (panel === null) return\n const start = {\n edge,\n startX: event.clientX,\n startY: event.clientY,\n startWidth: panel.clientWidth,\n startHeight: panel.clientHeight,\n }\n const onMove = (move: PointerEvent): void => {\n if (dragStartRef.current !== start || dragStartRef.current === null) return\n move.preventDefault()\n const panelEl = findSettingsPanel()\n if (panelEl === null) return\n const dx = move.clientX - start.startX\n const dy = move.clientY - start.startY\n let width = start.startWidth\n let height = start.startHeight\n if (edge === 'left' || edge === 'right' || edge === 'tl' || edge === 'bl' || edge === 'tr' || edge === 'br') {\n width = start.startWidth + (edge === 'left' || edge === 'tl' || edge === 'bl' ? -dx : dx)\n }\n if (edge === 'top' || edge === 'bottom' || edge === 'tl' || edge === 'bl' || edge === 'tr' || edge === 'br') {\n height = start.startHeight + (edge === 'top' || edge === 'tl' || edge === 'tr' ? -dy : dy)\n }\n panelEl.style.width = `${Math.round(clampPanelWidth(width))}px`\n panelEl.style.height = `${Math.round(clampPanelHeight(height))}px`\n setRect(panelEl.getBoundingClientRect())\n }\n const onUp = (): void => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n dragStartRef.current = null\n const panelEl = findSettingsPanel()\n if (panelEl !== null) {\n actions.setField(PANEL_WIDTH_FIELD, Math.round(clampPanelWidth(panelEl.clientWidth)))\n actions.setField(PANEL_HEIGHT_FIELD, Math.round(clampPanelHeight(panelEl.clientHeight)))\n }\n document.body.style.removeProperty('cursor')\n document.body.style.removeProperty('user-select')\n }\n dragStartRef.current = start\n document.body.style.cursor = stripRect(edge, rect).cursor\n document.body.style.userSelect = 'none'\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n }\n\n const edges: readonly Edge[] = ['left', 'right', 'top', 'bottom', 'tl', 'tr', 'bl', 'br']\n\n return (\n <>\n {edges.map(edge => {\n const pos = stripRect(edge, rect)\n return (\n <div\n key={edge}\n onPointerDown={event => { onPointerDown(edge, event) }}\n onPointerEnter={event => { event.currentTarget.style.background = 'var(--dsw-alias-state-business-primary)'; event.currentTarget.style.opacity = '0.75' }}\n onPointerLeave={event => { event.currentTarget.style.background = 'transparent'; event.currentTarget.style.opacity = '0' }}\n style={{\n position: 'fixed',\n zIndex: 9998,\n left: pos.left,\n top: pos.top,\n width: pos.width,\n height: pos.height,\n cursor: pos.cursor,\n background: 'transparent',\n opacity: 0,\n borderRadius: 6,\n pointerEvents: 'auto',\n touchAction: 'none',\n }}\n />\n )\n })}\n </>\n )\n}\n\n/** \u62D6\u62FD\u8D77\u59CB\u72B6\u6001\uFF08onMove/onUp \u95ED\u5305\u5171\u4EAB\uFF09\u3002 */\nconst dragStartRef: { current: null | { edge: Edge; startX: number; startY: number; startWidth: number; startHeight: number } } = { current: null }\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, PANEL_HEIGHT_FIELD,\n PANEL_RESIZE_FIELD, PANEL_SCROLL_FIELD, PANEL_WIDTH_FIELD, SEND_PRESETS,\n newSessionId,\n type ComposerUxSettings, type MenuField, 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\uFF09\u3002 */\n setField: (field: SettingsField, value: boolean | string | number) => 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/** \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 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=\"\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 \u7CFB\u8DEF\u7531\"\n value={settings.headerRoutes}\n placeholder=\"\u7559\u7A7A = \u81EA\u52A8\uFF08opencode*\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"],
5
+ "mappings": "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",
6
+ "names": ["text", "React", "import_react", "import_jsx_runtime", "import_react", "import_jsx_runtime", "menu"]
7
+ }