@monaco-ai-editor/react 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","<define:import.meta.env>","../src/components/EditorPanel.tsx","../src/hooks/useOptionalCoordinator.ts","../src/context/internal.ts","../src/components/AiChatPanel.tsx","../src/components/Toolbar.tsx","../src/components/StatusBar.tsx","../src/components/MonacoAiEditor.tsx","../src/context/EditorCoordinator.tsx","../src/utils/configureMonaco.ts"],"sourcesContent":["// ─── 公共组件 ─────────────────────────────────────────────────────────\nexport { EditorPanel, type EditorPanelProps } from './components/EditorPanel';\nexport { AiChatPanel, type AiChatPanelProps } from './components/AiChatPanel';\nexport { Toolbar, type ToolbarProps } from './components/Toolbar';\nexport { StatusBar, type StatusBarProps } from './components/StatusBar';\nexport { MonacoAiEditor, type MonacoAiEditorProps } from './components/MonacoAiEditor';\n\n// ─── Monaco 配置 ─────────────────────────────────────────────────────\nexport { configureMonaco, type ConfigureMonacoOptions } from './utils/configureMonaco';\n\n// ─── 协调器 ───────────────────────────────────────────────────────────\nexport {\n EditorCoordinator,\n useEditorCoordinator,\n type EditorCoordinatorProps,\n type EditorCoordinatorValue,\n} from './context/EditorCoordinator';\n\n// ─── 透传 core 的类型,避免使用方需要额外安装 core ────────────────────\nexport type {\n ApiConfig,\n SqlSchema,\n ChatMessage,\n EditorSnapshot,\n CompletionContext,\n CompletionProvider,\n PendingCompletion,\n EditorController,\n AiChatController,\n EditorBus,\n} from '@monaco-ai-editor/core';\n\nexport {\n LANGUAGES,\n THEMES,\n LOCALES,\n type Locale,\n SQL_KEYWORDS,\n SQL_FUNCTIONS,\n SQL_DATA_TYPES,\n} from '@monaco-ai-editor/core';","{}","import { type FC, useRef, useEffect, useState, useMemo } from 'react';\nimport Editor, { loader, type OnMount, type BeforeMount } from '@monaco-editor/react';\nimport type * as MonacoType from 'monaco-editor';\nimport {\n EditorController,\n registerSqlCompletion,\n registerAiInlineCompletion,\n registerAiCompletionCommand,\n type ApiConfig,\n type SqlSchema,\n type CompletionProvider,\n type PendingCompletion,\n} from '@monaco-ai-editor/core';\nimport { useOptionalCoordinator } from '../hooks/useOptionalCoordinator';\n\nexport interface EditorPanelProps {\n /** 受控/非受控通用:初始值(独立模式下使用) */\n value?: string;\n onChange?: (value: string) => void;\n language?: string;\n theme?: string;\n\n /** 高级:自定义 Monaco loader 路径(默认走 CDN) */\n vsPath?: string;\n\n /** SQL 表结构(启用 SQL 时) */\n sqlSchema?: SqlSchema;\n\n /**\n * 需要从内置 SQL 关键字/函数补全中排除的 label(大写不敏感)。\n * 用于让 completionProviders 中的自定义同名词条覆盖内置项,避免重复提示。\n */\n builtinSqlExcludeLabels?: string[];\n\n /** AI 配置(用于 Ctrl+Alt+L 触发的 AI 行内补全) */\n apiConfig?: ApiConfig | null;\n\n /** 自定义补全扩展 */\n completionProviders?: CompletionProvider[];\n\n /** Monaco 实例就绪回调(拿到 controller) */\n onMount?: (controller: EditorController) => void;\n\n /**\n * 右侧代码缩略图(minimap)配置。\n * - 传 `true`/`false` 快捷开关\n * - 传对象可细粒度自定义(仅覆盖指定字段,其余沿用默认值)\n * - 默认开启\n */\n minimap?: boolean | MonacoType.editor.IEditorMinimapOptions;\n\n /** 自定义 Monaco editor options */\n editorOptions?: MonacoType.editor.IStandaloneEditorConstructionOptions;\n\n /** AI 补全错误回调 */\n onAiError?: (message: string) => void;\n\n /** 容器样式类 */\n className?: string;\n\n /** 编辑器加载时的占位内容(覆盖 @monaco-editor/react 默认的 \"Loading...\") */\n loading?: React.ReactNode;\n}\n\n/**\n * Monaco 编辑器面板。\n * - 独立模式:通过 props 完全控制\n * - 联动模式:自动从 EditorCoordinator 继承配置,并向 bus 注册 controller\n */\nexport const EditorPanel: FC<EditorPanelProps> = ({\n value,\n onChange,\n language,\n theme,\n vsPath,\n sqlSchema,\n builtinSqlExcludeLabels,\n apiConfig: apiConfigProp,\n completionProviders,\n onMount,\n minimap,\n editorOptions,\n onAiError,\n className,\n loading,\n}) => {\n const coordinator = useOptionalCoordinator();\n\n // 合并 props 与 coordinator 配置(props 优先)\n const effectiveLanguage = language ?? coordinator?.editorState.language ?? 'typescript';\n const effectiveTheme = theme ?? coordinator?.editorState.theme ?? 'vs-dark';\n const effectiveApiConfig = apiConfigProp ?? coordinator?.apiConfig ?? null;\n const effectiveSqlSchema = sqlSchema ?? coordinator?.sqlSchema ?? {};\n const effectiveProviders = completionProviders ?? coordinator?.completionProviders ?? [];\n\n const controllerRef = useRef<EditorController | null>(null);\n const apiConfigRef = useRef<ApiConfig | null>(effectiveApiConfig);\n const pendingRef = useRef<PendingCompletion | null>(null);\n const [aiLoading, setAiLoading] = useState(false);\n const [aiError, setAiError] = useState<string | null>(null);\n const errorTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // 配置 loader 路径(中文语言包已在模块顶层配置)\n useEffect(() => {\n if (vsPath) {\n loader.config({ paths: { vs: vsPath } });\n }\n }, [vsPath]);\n\n useEffect(() => {\n apiConfigRef.current = effectiveApiConfig;\n }, [effectiveApiConfig]);\n\n const showAiError = (msg: string) => {\n if (errorTimerRef.current) clearTimeout(errorTimerRef.current);\n setAiError(msg);\n onAiError?.(msg);\n errorTimerRef.current = setTimeout(() => setAiError(null), 4000);\n };\n\n // SQL schema 通过 ref 注入到 core 的 SQL 补全\n const schemaRef = useRef<SqlSchema>(effectiveSqlSchema);\n useEffect(() => {\n schemaRef.current = effectiveSqlSchema;\n }, [effectiveSqlSchema]);\n\n // 内置 SQL 补全需要排除的 label(大写),通过 ref 支持动态更新\n const excludeLabelsRef = useRef<Set<string>>(\n new Set((builtinSqlExcludeLabels ?? []).map((l) => l.toUpperCase())),\n );\n useEffect(() => {\n excludeLabelsRef.current = new Set((builtinSqlExcludeLabels ?? []).map((l) => l.toUpperCase()));\n }, [builtinSqlExcludeLabels]);\n\n const handleBeforeMount: BeforeMount = (monaco) => {\n // 把 monaco 实例附加到 controller 备用\n (window as unknown as { __monaco_ai_monaco?: typeof monaco }).__monaco_ai_monaco = monaco;\n };\n\n const handleMount: OnMount = (editor, monaco) => {\n // 注册 SQL 补全(使用 core 的注册函数)\n registerSqlCompletion(monaco, schemaRef, excludeLabelsRef);\n // 注册 AI 内联幽灵文本提供者\n registerAiInlineCompletion(monaco, pendingRef);\n\n // 注册自定义 completionProviders\n for (const provider of effectiveProviders) {\n const langs = provider.languages ?? ['*'];\n for (const lang of langs) {\n monaco.languages.registerCompletionItemProvider(lang, {\n triggerCharacters: provider.triggerCharacters,\n provideCompletionItems: async (\n model: MonacoType.editor.ITextModel,\n position: MonacoType.Position,\n context: MonacoType.languages.CompletionContext,\n ) => {\n const ctx = {\n monaco,\n model,\n position,\n lineText: model.getLineContent(position.lineNumber),\n currentWord: model.getWordUntilPosition(position).word,\n fullText: model.getValue(),\n triggerCharacter: context.triggerCharacter,\n };\n if (provider.shouldTrigger && !provider.shouldTrigger(ctx)) {\n return { suggestions: [] };\n }\n return { suggestions: await provider.provide(ctx) };\n },\n });\n }\n }\n\n // 注册 AI 补全命令\n registerAiCompletionCommand(\n editor,\n () => apiConfigRef.current,\n pendingRef,\n setAiLoading,\n showAiError,\n );\n\n // 创建轻量 controller(包装现有 editor)\n const controller = createControllerFromEditor(editor, monaco);\n controllerRef.current = controller;\n\n // 更新光标、内容到 coordinator\n if (coordinator) {\n coordinator.setEditor(controller);\n coordinator.bus.registerEditor(controller);\n\n editor.onDidChangeCursorPosition((e) => {\n coordinator.patchEditorState({\n cursorLine: e.position.lineNumber,\n cursorColumn: e.position.column,\n });\n });\n editor.onDidChangeModelContent(() => {\n coordinator.patchEditorState({ value: editor.getValue() });\n });\n }\n\n onMount?.(controller);\n };\n\n // 卸载时清理\n useEffect(() => {\n return () => {\n if (errorTimerRef.current) clearTimeout(errorTimerRef.current);\n if (coordinator && controllerRef.current) {\n coordinator.setEditor(null);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const mergedOptions = useMemo<MonacoType.editor.IStandaloneEditorConstructionOptions>(\n () => {\n // 缩略图默认配置,使用方可通过 minimap prop 或 editorOptions.minimap 局部覆盖\n const defaultMinimap: MonacoType.editor.IEditorMinimapOptions = {\n enabled: true,\n side: 'right',\n showSlider: 'mouseover',\n renderCharacters: true,\n maxColumn: 120,\n };\n\n // 归一化 minimap prop:boolean -> { enabled },对象 -> 原样\n const minimapFromProp: MonacoType.editor.IEditorMinimapOptions | undefined =\n typeof minimap === 'boolean' ? { enabled: minimap } : minimap;\n\n // 深合并优先级:默认值 < minimap prop < editorOptions.minimap\n const mergedMinimap: MonacoType.editor.IEditorMinimapOptions = {\n ...defaultMinimap,\n ...minimapFromProp,\n ...editorOptions?.minimap,\n };\n\n return {\n fontSize: 14,\n scrollBeyondLastLine: false,\n automaticLayout: true,\n // 让 suggest/hover/find 等溢出浮层以 fixed 定位渲染到 body 层级,\n // 避免被祖先的 overflow:hidden 裁剪(如 tooltip 贴边被遮挡)\n fixedOverflowWidgets: true,\n lineNumbers: 'on',\n renderLineHighlight: 'all',\n smoothScrolling: true,\n cursorBlinking: 'smooth',\n bracketPairColorization: { enabled: true },\n tabSize: 2,\n wordWrap: 'on',\n folding: true,\n formatOnPaste: true,\n formatOnType: false,\n suggestOnTriggerCharacters: true,\n quickSuggestions: { other: true, comments: false, strings: false },\n acceptSuggestionOnCommitCharacter: true,\n acceptSuggestionOnEnter: 'on',\n inlineSuggest: { enabled: true },\n tabCompletion: 'on',\n ...editorOptions,\n minimap: mergedMinimap,\n };\n },\n [minimap, editorOptions],\n );\n\n return (\n <div className={className} style={{ position: 'relative', flex: 1, height: '100%' }}>\n {aiLoading && (\n <div className=\"mae-ai-loading\" style={loadingStyle}>\n <span className=\"mae-spinner\" style={spinnerStyle} /> AI 补全中…\n </div>\n )}\n {aiError && (\n <div onClick={() => setAiError(null)} style={errorStyle} title=\"点击关闭\">\n {aiError}\n </div>\n )}\n <Editor\n height=\"100%\"\n language={effectiveLanguage}\n theme={effectiveTheme}\n value={value}\n loading={loading}\n onChange={(val) => onChange?.(val ?? '')}\n beforeMount={handleBeforeMount}\n onMount={handleMount}\n options={mergedOptions}\n />\n </div>\n );\n};\n\n// ── 辅助:把 @monaco-editor/react 创建的 editor 包装成 controller ──\nfunction createControllerFromEditor(\n editor: MonacoType.editor.IStandaloneCodeEditor,\n monaco: typeof MonacoType,\n): EditorController {\n // 直接构造一个轻量的 controller-like 对象,但保持 EditorController 接口\n const fake = Object.create(EditorController.prototype) as EditorController;\n // @ts-expect-error 私有字段写入\n fake.editor = editor;\n // @ts-expect-error 私有字段写入\n fake.monaco = monaco;\n // @ts-expect-error 私有字段写入\n fake.disposables = [];\n // @ts-expect-error 私有字段写入\n fake.pendingCompletionRef = { current: null };\n // @ts-expect-error 私有字段写入\n fake.customProviders = [];\n // 初始化 EventEmitter 内部 listeners 字段\n // @ts-expect-error 父类私有字段\n fake.listeners = {};\n return fake;\n}\n\nconst loadingStyle: React.CSSProperties = {\n position: 'absolute', bottom: 32, right: 16, zIndex: 10,\n display: 'flex', alignItems: 'center', gap: 6,\n borderRadius: 9999, border: '1px solid rgba(59,130,246,0.3)',\n background: 'rgba(17,24,39,0.9)', padding: '4px 12px',\n fontSize: 12, color: '#60a5fa',\n};\n\nconst spinnerStyle: React.CSSProperties = {\n display: 'inline-block', width: 12, height: 12,\n border: '2px solid rgba(96,165,250,0.3)', borderTopColor: '#60a5fa',\n borderRadius: '50%', animation: 'mae-spin 0.8s linear infinite',\n};\n\nconst errorStyle: React.CSSProperties = {\n position: 'absolute', bottom: 32, right: 16, zIndex: 10,\n maxWidth: 320, cursor: 'pointer',\n borderRadius: 8, border: '1px solid rgba(239,68,68,0.4)',\n background: 'rgba(17,24,39,0.95)', padding: '8px 12px',\n fontSize: 12, color: '#f87171', lineHeight: 1.5,\n};\n\nexport default EditorPanel;","import { useContext } from 'react';\nimport { EditorCoordinatorContext } from '../context/internal';\nimport type { EditorCoordinatorValue } from '../context/EditorCoordinator';\n\n/** 内部 hook:尝试读取协调器上下文,没有则返回 null(独立模式) */\nexport function useOptionalCoordinator(): EditorCoordinatorValue | null {\n return useContext(EditorCoordinatorContext);\n}","import { createContext } from 'react';\nimport type { EditorCoordinatorValue } from './EditorCoordinator';\n\n/** 内部共享 Context,让组件可选择性地读取协调器值 */\nexport const EditorCoordinatorContext = createContext<EditorCoordinatorValue | null>(null);","import {\n type FC,\n useState,\n useRef,\n useEffect,\n useCallback,\n type KeyboardEvent,\n} from 'react';\nimport { DiffEditor } from '@monaco-editor/react';\nimport {\n AiChatController,\n type ChatMessage,\n type ApiConfig,\n} from '@monaco-ai-editor/core';\nimport { useOptionalCoordinator } from '../hooks/useOptionalCoordinator';\n\nexport interface AiChatPanelProps {\n /** 独立模式:编辑器当前内容 */\n editorContent?: string;\n /** 独立模式:当前语言 */\n language?: string;\n /** 独立模式:插入代码回调 */\n onInsertCode?: (code: string) => void;\n /** 独立模式:替换全部代码回调 */\n onReplaceCode?: (code: string) => void;\n /** 关闭面板 */\n onClose?: () => void;\n /** AI 配置 */\n apiConfig?: ApiConfig;\n /** 设置保存后回调 */\n onApiConfigChange?: (config: ApiConfig) => void;\n /** 容器宽度(默认 320) */\n defaultWidth?: number;\n className?: string;\n}\n\ntype Part =\n | { type: 'text'; content: string }\n | { type: 'code'; lang: string; content: string };\n\ninterface DiffState {\n original: string;\n modified: string;\n language: string;\n}\n\nfunction parseContent(raw: string, isStreaming?: boolean): Part[] {\n const parts: Part[] = [];\n const blockRe = /```(\\w*)\\n?([\\s\\S]*?)```/g;\n let last = 0;\n let m: RegExpExecArray | null;\n while ((m = blockRe.exec(raw)) !== null) {\n if (m.index > last) parts.push({ type: 'text', content: raw.slice(last, m.index) });\n parts.push({ type: 'code', lang: m[1] || 'code', content: m[2].trimEnd() });\n last = m.index + m[0].length;\n }\n const remaining = raw.slice(last);\n if (remaining) {\n const idx = remaining.indexOf('```');\n if (idx !== -1) {\n if (idx > 0) parts.push({ type: 'text', content: remaining.slice(0, idx) });\n const block = remaining.slice(idx + 3);\n const lm = block.match(/^(\\w*)\\n?/);\n parts.push({ type: 'code', lang: lm?.[1] ?? '', content: block.slice(lm?.[0]?.length ?? 0) + (isStreaming ? '▋' : '') });\n } else {\n parts.push({ type: 'text', content: remaining + (isStreaming ? '▋' : '') });\n }\n } else if (isStreaming && raw.length > 0 && !raw.endsWith('```')) {\n parts.push({ type: 'text', content: '▋' });\n }\n return parts;\n}\n\nconst MessageContent: FC<{\n content: string; isStreaming?: boolean;\n onInsertCode?: (code: string) => void; onShowDiff?: (code: string, lang: string) => void;\n}> = ({ content, isStreaming, onInsertCode, onShowDiff }) => {\n const parts = parseContent(content, isStreaming);\n if (isStreaming && content === '') return <span style={{ animation: 'pulse 1s infinite', color: '#9ca3af' }}>▋</span>;\n return (\n <>\n {parts.map((p, i) =>\n p.type === 'code' ? (\n <div key={i} style={{ margin: '8px 0', borderRadius: 8, overflow: 'hidden', border: '1px solid rgb(75,85,99)' }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '4px 12px', background: 'rgb(55,65,71)' }}>\n <span style={{ fontSize: 11, color: 'rgb(156,163,175)' }}>{p.lang}</span>\n <div style={{ display: 'flex', gap: 8 }}>\n <button onClick={() => navigator.clipboard.writeText(p.content)} style={codeBtnStyle}>复制</button>\n {onShowDiff && <button onClick={() => onShowDiff(p.content, p.lang)} style={{ ...codeBtnStyle, color: '#fbbf24' }}>差异</button>}\n {onInsertCode && <button onClick={() => onInsertCode(p.content)} style={{ ...codeBtnStyle, color: '#60a5fa' }}>插入</button>}\n </div>\n </div>\n <pre style={{ margin: 0, padding: 12, overflowX: 'auto', background: 'rgb(3,7,18)', fontSize: 12, lineHeight: 1.6, color: 'rgb(229,231,235)' }}>\n <code>{p.content}</code>\n </pre>\n </div>\n ) : (\n <span key={i} style={{ whiteSpace: 'pre-wrap', lineHeight: 1.6 }}>{p.content}</span>\n ),\n )}\n </>\n );\n};\n\nconst codeBtnStyle: React.CSSProperties = {\n fontSize: 11, color: 'rgb(156,163,175)', background: 'transparent',\n border: 'none', cursor: 'pointer', padding: 0,\n};\n\nconst MIN_WIDTH = 260;\nconst MAX_WIDTH = 720;\n\nexport const AiChatPanel: FC<AiChatPanelProps> = (props) => {\n const coordinator = useOptionalCoordinator();\n const [width, setWidth] = useState(props.defaultWidth ?? 320);\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [input, setInput] = useState('');\n const [loading, setLoading] = useState(false);\n const [showSettings, setShowSettings] = useState(false);\n const [configDraft, setConfigDraft] = useState<ApiConfig>(props.apiConfig ?? coordinator?.apiConfig ?? { baseUrl: '', apiKey: '', model: '' });\n const [diffState, setDiffState] = useState<DiffState | null>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const abortRef = useRef<AbortController | null>(null);\n const ctrlRef = useRef<AiChatController | null>(null);\n const isDragging = useRef(false);\n const dragStartX = useRef(0);\n const dragStartW = useRef(0);\n\n // 获取编辑器内容(联动或独立)\n const editorContent = props.editorContent ?? coordinator?.editor?.getValue() ?? '';\n const language = props.language ?? coordinator?.editorState.language;\n\n const effectiveApiConfig = props.apiConfig ?? coordinator?.apiConfig ?? configDraft;\n\n // 初始化 controller\n useEffect(() => {\n const ctrl = new AiChatController(effectiveApiConfig);\n ctrlRef.current = ctrl;\n\n const offAdd = ctrl.on('messageAdded', (msg) => setMessages((prev) => [...prev, msg]));\n const offUpd = ctrl.on('messageUpdated', (msg) =>\n setMessages((prev) => prev.map((m) => (m.id === msg.id ? msg : m))));\n const offClear = ctrl.on('cleared', () => setMessages([]));\n const offLoad = ctrl.on('loadingChange', ({ loading: l }) => setLoading(l));\n\n if (coordinator) coordinator.setChat(ctrl);\n\n return () => {\n offAdd(); offUpd(); offClear(); offLoad();\n ctrl.dispose();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // 同步 API 配置变更\n useEffect(() => {\n if (ctrlRef.current) ctrlRef.current.setApiConfig(effectiveApiConfig);\n setConfigDraft(effectiveApiConfig);\n }, [effectiveApiConfig]);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages]);\n\n const handleSend = useCallback(() => {\n ctrlRef.current?.send(input, { editorContent, language });\n setInput('');\n }, [input, editorContent, language]);\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleStop = () => ctrlRef.current?.stop();\n const handleClear = () => ctrlRef.current?.clear();\n\n const handleSaveConfig = () => {\n if (coordinator?.onApiConfigChange) {\n coordinator.onApiConfigChange(configDraft);\n }\n if (props.onApiConfigChange) {\n props.onApiConfigChange(configDraft);\n }\n setShowSettings(false);\n };\n\n const handleAddEditorContext = () => {\n if (!editorContent) return;\n const snippet = `以下是当前编辑器中的${language ? ` ${language} ` : ''}代码:\\n\\`\\`\\`${language}\\n${editorContent}\\n\\`\\`\\``;\n setInput((prev) => (prev.trim() ? `${prev}\\n\\n${snippet}` : snippet));\n };\n\n const handleInsert = props.onInsertCode\n ? props.onInsertCode\n : (code: string) => coordinator?.bus?.insertToEditor(code);\n\n const handleReplace = props.onReplaceCode\n ? props.onReplaceCode\n : (code: string) => coordinator?.bus?.replaceEditor(code);\n\n const handleShowDiff = useCallback((aiCode: string, codeLang: string) => {\n setDiffState({ original: editorContent ?? '', modified: aiCode, language: codeLang || language || 'plaintext' });\n }, [editorContent, language]);\n\n const handleApplyDiff = () => {\n if (!diffState) return;\n if (handleReplace) handleReplace(diffState.modified);\n else if (handleInsert) handleInsert(diffState.modified);\n setDiffState(null);\n };\n\n const handleResizeMouseDown = (e: React.MouseEvent) => {\n e.preventDefault();\n isDragging.current = true;\n dragStartX.current = e.clientX;\n dragStartW.current = width;\n const onMove = (ev: MouseEvent) => {\n const next = Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, dragStartW.current + (dragStartX.current - ev.clientX)));\n setWidth(next);\n };\n const onUp = () => {\n isDragging.current = false;\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n document.body.style.cursor = '';\n };\n document.body.style.cursor = 'col-resize';\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n };\n\n return (\n <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', borderLeft: '1px solid rgb(55,65,81)', background: 'rgb(17,24,39)', width, height: '100%' }}>\n {/* 拖拽缩放 */}\n <div onMouseDown={handleResizeMouseDown} style={{ position: 'absolute', left: 0, top: 0, width: 4, height: '100%', cursor: 'col-resize', zIndex: 10 }} />\n\n {/* 头部 */}\n <div style={{ display: 'flex', alignItems: 'center', padding: '8px 12px', borderBottom: '1px solid rgb(55,65,81)' }}>\n <svg style={{ width: 16, height: 16, color: '#60a5fa', marginRight: 8 }} viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M2 5a2 2 0 012-2h7a2 2 0 012 2v4a2 2 0 01-2 2H9l-3 3v-3H4a2 2 0 01-2-2V5z\" />\n <path d=\"M15 7v2a4 4 0 01-4 4H9.828l-1.766 1.767c.28.149.599.233.938.233h2l3 3v-3h2a2 2 0 002-2V9a2 2 0 00-2-2h-1z\" />\n </svg>\n <span style={{ flex: 1, fontSize: 13, fontWeight: 500, color: '#fff' }}>AI 对话</span>\n\n <button onClick={() => { setConfigDraft(effectiveApiConfig); setShowSettings((v) => !v); }} style={{ ...iconBtnStyle, color: showSettings ? '#60a5fa' : '#9ca3af' }} title=\"设置\">\n <svg style={{ width: 16, height: 16 }} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n </button>\n <button onClick={handleClear} style={iconBtnStyle} title=\"清空\"><svg style={{ width: 16, height: 16 }} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}><path d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\" /></svg></button>\n {props.onClose && <button onClick={props.onClose} style={iconBtnStyle} title=\"关闭\"><svg style={{ width: 16, height: 16 }} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}><path d=\"M6 18L18 6M6 6l12 12\" /></svg></button>}\n </div>\n\n {/* 设置面板 */}\n {showSettings && (\n <div style={{ padding: 12, borderBottom: '1px solid rgb(55,65,81)', background: 'rgb(31,41,55)' }}>\n <div style={{ fontSize: 11, fontWeight: 600, color: '#d1d5db', marginBottom: 12 }}>API 配置</div>\n {(['baseUrl', 'apiKey', 'model'] as const).map((field) => (\n <div key={field}>\n <label style={{ display: 'block', fontSize: 11, color: '#9ca3af', marginBottom: 4 }}>\n {field === 'baseUrl' ? 'Base URL' : field === 'apiKey' ? 'API Key' : '模型'}\n </label>\n <input\n type={field === 'apiKey' ? 'password' : 'text'}\n value={configDraft[field]}\n onChange={(e) => setConfigDraft((p) => ({ ...p, [field]: e.target.value }))}\n placeholder={field === 'baseUrl' ? 'https://api.openai.com/v1' : field === 'model' ? 'gpt-4o-mini' : ''}\n style={inputStyle}\n />\n </div>\n ))}\n <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>\n <button onClick={handleSaveConfig} style={{ flex: 1, padding: '6px 0', fontSize: 12, background: 'rgb(37,99,235)', color: '#fff', border: 'none', borderRadius: 4, cursor: 'pointer' }}>保存</button>\n <button onClick={() => setShowSettings(false)} style={{ flex: 1, padding: '6px 0', fontSize: 12, background: 'rgb(75,85,99)', color: '#fff', border: 'none', borderRadius: 4, cursor: 'pointer' }}>取消</button>\n </div>\n </div>\n )}\n\n {/* Diff 对比 */}\n {diffState && (\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: 'rgb(17,24,39)' }}>\n <div style={{ padding: '4px 8px', borderBottom: '1px solid rgb(55,65,81)', background: 'rgb(31,41,55)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n <span style={{ fontSize: 12, color: '#fff' }}>Diff 对比</span>\n <div style={{ display: 'flex', gap: 8 }}>\n <button onClick={handleApplyDiff} style={{ fontSize: 11, color: '#60a5fa', background: 'transparent', border: 'none', cursor: 'pointer' }}>应用更改</button>\n <button onClick={() => setDiffState(null)} style={{ fontSize: 11, color: '#9ca3af', background: 'transparent', border: 'none', cursor: 'pointer' }}>关闭</button>\n </div>\n </div>\n <DiffEditor\n height=\"100%\"\n language={diffState.language}\n original={diffState.original}\n modified={diffState.modified}\n theme=\"vs-dark\"\n />\n </div>\n )}\n\n {/* 消息列表 */}\n {!diffState && (\n <div style={{ flex: 1, overflowY: 'auto', padding: 12 }}>\n {messages.length === 0 && (\n <div style={{ display: 'flex', height: '100%', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center' }}>\n {!effectiveApiConfig.apiKey.trim() && (\n <div style={{ width: '100%', marginBottom: 16, padding: '8px 12px', borderRadius: 8, border: '1px solid rgba(250,204,21,0.4)', background: 'rgba(250,204,21,0.1)', textAlign: 'left' }}>\n <p style={{ marginBottom: 4, fontSize: 11, fontWeight: 600, color: '#fbbf24' }}>⚠️ 未配置 API Key</p>\n <p style={{ fontSize: 11, color: 'rgba(251,191,36,0.8)', lineHeight: 1.5 }}>请点击右上角 ⚙️ 按钮填写配置后开始对话</p>\n </div>\n )}\n <svg style={{ width: 40, height: 40, color: 'rgb(75,85,99)', marginBottom: 12 }} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path d=\"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z\" />\n </svg>\n {!loading && <p style={{ fontSize: 12, color: '#6b7280' }}>开始你的 AI 编程对话吧</p>}\n </div>\n )}\n {messages.map((msg) => (\n <div key={msg.id} style={{ marginBottom: 12, display: 'flex', flexDirection: 'column', alignItems: msg.role === 'user' ? 'flex-end' : 'flex-start' }}>\n <div style={{ maxWidth: '90%', padding: '8px 12px', borderRadius: 8, fontSize: 12, color: '#e5e7eb', background: msg.role === 'user' ? 'rgb(55,65,81)' : 'rgb(31,41,55)', lineHeight: 1.5 }}>\n {msg.role === 'assistant' ? (\n <MessageContent content={msg.content} isStreaming={msg.isStreaming} onInsertCode={handleInsert} onShowDiff={handleShowDiff} />\n ) : (\n <span style={{ whiteSpace: 'pre-wrap' }}>{msg.content}</span>\n )}\n </div>\n </div>\n ))}\n <div ref={messagesEndRef} />\n </div>\n )}\n\n {/* 输入区域 */}\n {!diffState && (\n <div style={{ padding: '8px 12px', borderTop: '1px solid rgb(55,65,81)' }}>\n <div style={{ display: 'flex', gap: 4, marginBottom: 4 }}>\n <button onClick={handleAddEditorContext} style={{ fontSize: 11, color: '#9ca3af', background: 'transparent', border: 'none', cursor: 'pointer' }} title=\"引用编辑器代码\">+ 引用代码</button>\n </div>\n <div style={{ display: 'flex', gap: 8 }}>\n <textarea\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"输入消息,Ctrl+Enter 发送...\"\n style={{ flex: 1, padding: '6px 8px', fontSize: 12, background: 'rgb(31,41,55)', color: '#e5e7eb', border: '1px solid rgb(75,85,99)', borderRadius: 4, outline: 'none', resize: 'none', minHeight: 32 }}\n rows={2}\n />\n {loading ? (\n <button onClick={handleStop} style={{ padding: '6px 12px', fontSize: 12, background: 'rgb(220,38,38)', color: '#fff', border: 'none', borderRadius: 4, cursor: 'pointer', whiteSpace: 'nowrap' }}>停止</button>\n ) : (\n <button onClick={handleSend} style={{ padding: '6px 12px', fontSize: 12, background: 'rgb(37,99,235)', color: '#fff', border: 'none', borderRadius: 4, cursor: 'pointer', whiteSpace: 'nowrap' }}>发送</button>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nconst iconBtnStyle: React.CSSProperties = {\n padding: 4, color: '#9ca3af', background: 'transparent',\n border: 'none', cursor: 'pointer', display: 'flex',\n borderRadius: 4,\n};\n\nconst inputStyle: React.CSSProperties = {\n width: '100%', padding: '4px 8px', fontSize: 12,\n background: 'rgb(55,65,81)', color: 'rgb(229,231,235)',\n border: '1px solid rgb(75,85,99)', borderRadius: 4,\n outline: 'none', marginBottom: 8, boxSizing: 'border-box',\n};\n\nexport default AiChatPanel;","import { type FC } from 'react';\nimport { LANGUAGES, THEMES } from '@monaco-ai-editor/core';\n\nexport interface ToolbarProps {\n language?: string;\n theme?: string;\n onLanguageChange?: (lang: string) => void;\n onThemeChange?: (theme: string) => void;\n onFormat?: () => void;\n onToggleAiChat?: () => void;\n aiChatVisible?: boolean;\n className?: string;\n}\n\nexport const Toolbar: FC<ToolbarProps> = ({\n language,\n theme,\n onLanguageChange,\n onThemeChange,\n onFormat,\n onToggleAiChat,\n aiChatVisible,\n className,\n}) => {\n return (\n <div\n className={className}\n style={toolbarStyle}\n >\n <div style={labelStyle}>语言</div>\n <select\n value={language ?? 'typescript'}\n onChange={(e) => onLanguageChange?.(e.target.value)}\n style={selectStyle}\n >\n {LANGUAGES.map((lang) => (\n <option key={lang} value={lang}>\n {lang}\n </option>\n ))}\n </select>\n\n <div style={{ ...labelStyle, marginLeft: 16 }}>主题</div>\n <select\n value={theme ?? 'vs-dark'}\n onChange={(e) => onThemeChange?.(e.target.value)}\n style={selectStyle}\n >\n {THEMES.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n\n <div style={{ flex: 1 }} />\n\n {onToggleAiChat && (\n <button\n onClick={onToggleAiChat}\n style={{\n ...buttonStyle,\n background: aiChatVisible ? 'rgb(37,99,235)' : 'rgb(55,65,81)',\n }}\n >\n <svg\n style={{ width: 16, height: 16, marginRight: 4 }}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path d=\"M2 5a2 2 0 012-2h7a2 2 0 012 2v4a2 2 0 01-2 2H9l-3 3v-3H4a2 2 0 01-2-2V5z\" />\n <path d=\"M15 7v2a4 4 0 01-4 4H9.828l-1.766 1.767c.28.149.599.233.938.233h2l3 3v-3h2a2 2 0 002-2V9a2 2 0 00-2-2h-1z\" />\n </svg>\n AI\n </button>\n )}\n\n {onFormat && (\n <button onClick={onFormat} style={{ ...buttonStyle, marginLeft: 8 }}>\n 格式化\n </button>\n )}\n </div>\n );\n};\n\nconst toolbarStyle: React.CSSProperties = {\n display: 'flex', alignItems: 'center', padding: '8px 16px',\n background: 'rgb(31,41,55)', borderBottom: '1px solid rgb(55,65,81)',\n};\n\nconst labelStyle: React.CSSProperties = {\n fontSize: 13, color: 'rgb(156,163,175)',\n};\n\nconst selectStyle: React.CSSProperties = {\n marginLeft: 8, padding: '4px 8px', fontSize: 13,\n background: 'rgb(55,65,81)', color: 'rgb(229,231,235)',\n border: '1px solid rgb(75,85,99)', borderRadius: 4,\n outline: 'none',\n};\n\nconst buttonStyle: React.CSSProperties = {\n padding: '4px 12px', fontSize: 13, color: '#fff',\n background: 'rgb(55,65,81)', border: 'none', borderRadius: 4,\n cursor: 'pointer', display: 'flex', alignItems: 'center',\n};\n\nexport default Toolbar;\n","import { type FC } from 'react';\n\nexport interface StatusBarProps {\n language?: string;\n lineCount?: number;\n charCount?: number;\n cursorLine?: number;\n cursorColumn?: number;\n className?: string;\n}\n\nexport const StatusBar: FC<StatusBarProps> = ({\n language,\n lineCount = 0,\n charCount = 0,\n cursorLine = 1,\n cursorColumn = 1,\n className,\n}) => {\n return (\n <div className={className} style={statusBarStyle}>\n <span style={itemStyle}>Ln {cursorLine}, Col {cursorColumn}</span>\n <span style={dividerStyle}>|</span>\n <span style={itemStyle}>{lineCount} 行</span>\n <span style={dividerStyle}>|</span>\n <span style={itemStyle}>{charCount} 字符</span>\n <div style={{ flex: 1 }} />\n <span style={itemStyle}>{language?.toUpperCase() ?? ''}</span>\n <span style={dividerStyle}>|</span>\n <span style={itemStyle}>UTF-8</span>\n </div>\n );\n};\n\nconst statusBarStyle: React.CSSProperties = {\n display: 'flex', alignItems: 'center', gap: 12,\n padding: '0 16px', height: 22,\n fontSize: 11, color: '#fff',\n background: 'rgb(29,78,216)',\n};\n\nconst itemStyle: React.CSSProperties = {\n display: 'flex', alignItems: 'center',\n};\n\nconst dividerStyle: React.CSSProperties = {\n color: 'rgba(255,255,255,0.5)',\n};\n\nexport default StatusBar;\n","import { type FC, useCallback, useState } from 'react';\nimport type { ApiConfig, SqlSchema, CompletionProvider, EditorController } from '@monaco-ai-editor/core';\nimport { EditorCoordinator } from '../context/EditorCoordinator';\nimport { EditorPanel } from './EditorPanel';\nimport { AiChatPanel } from './AiChatPanel';\nimport { Toolbar } from './Toolbar';\nimport { StatusBar } from './StatusBar';\nimport { useEditorCoordinator } from '../context/EditorCoordinator';\n\nexport interface MonacoAiEditorProps {\n language?: string;\n theme?: string;\n value?: string;\n onChange?: (value: string) => void;\n apiConfig?: ApiConfig;\n onApiConfigChange?: (config: ApiConfig) => void;\n sqlSchema?: SqlSchema;\n completionProviders?: CompletionProvider[];\n vsPath?: string;\n showToolbar?: boolean;\n showStatusBar?: boolean;\n showAiChat?: boolean;\n className?: string;\n}\n\n/**\n * 预组合组件:编辑器 + 工具栏 + 状态栏 + AI 聊天面板,一行接入。\n * 内部自动用 EditorCoordinator 包裹,实现联动。\n */\nexport const MonacoAiEditor: FC<MonacoAiEditorProps> = ({\n language = 'typescript',\n theme = 'vs-dark',\n apiConfig,\n onApiConfigChange,\n sqlSchema,\n completionProviders,\n showAiChat: showAiChatProp = true,\n ...rest\n}) => {\n return (\n <EditorCoordinator\n language={language}\n theme={theme}\n apiConfig={apiConfig}\n sqlSchema={sqlSchema}\n completionProviders={completionProviders}\n onApiConfigChange={onApiConfigChange}\n >\n <MonacoAiEditorInner {...rest} showAiChat={showAiChatProp} />\n </EditorCoordinator>\n );\n};\n\nconst MonacoAiEditorInner: FC<{\n value?: string;\n onChange?: (v: string) => void;\n vsPath?: string;\n showToolbar?: boolean;\n showStatusBar?: boolean;\n showAiChat?: boolean;\n className?: string;\n}> = ({ value, onChange, vsPath, showToolbar = true, showStatusBar = true, showAiChat = true, className }) => {\n const coordinator = useEditorCoordinator();\n const [aiVisible, setAiVisible] = useState(showAiChat);\n\n const onLangChange = useCallback((lang: string) => {\n coordinator.editor?.setLanguage(lang);\n coordinator.patchEditorState({ language: lang });\n }, [coordinator]);\n\n const onThemeChange = useCallback((theme: string) => {\n coordinator.editor?.setTheme(theme);\n coordinator.patchEditorState({ theme });\n }, [coordinator]);\n\n const onFormat = useCallback(() => coordinator.editor?.format(), [coordinator]);\n\n const onEditorMount = useCallback((controller: EditorController) => {\n coordinator.setEditor(controller);\n }, [coordinator]);\n\n return (\n <div\n className={className}\n style={{ display: 'flex', flexDirection: 'column', height: '100%', background: 'rgb(17,24,39)' }}\n >\n {showToolbar && (\n <Toolbar\n language={coordinator.editorState.language}\n theme={coordinator.editorState.theme}\n onLanguageChange={onLangChange}\n onThemeChange={onThemeChange}\n onFormat={onFormat}\n onToggleAiChat={() => setAiVisible((v) => !v)}\n aiChatVisible={aiVisible}\n />\n )}\n <div style={{ flex: 1, display: 'flex', overflow: 'hidden' }}>\n <EditorPanel\n value={value}\n onChange={(v) => {\n onChange?.(v);\n coordinator.patchEditorState({ value: v });\n }}\n language={coordinator.editorState.language}\n theme={coordinator.editorState.theme}\n vsPath={vsPath}\n onMount={onEditorMount}\n />\n {aiVisible && <AiChatPanel onClose={() => setAiVisible(false)} />}\n </div>\n {showStatusBar && (\n <StatusBar\n language={coordinator.editorState.language}\n lineCount={coordinator.editorState.value.split('\\n').length}\n charCount={coordinator.editorState.value.length}\n cursorLine={coordinator.editorState.cursorLine}\n cursorColumn={coordinator.editorState.cursorColumn}\n />\n )}\n </div>\n );\n};\n\nexport default MonacoAiEditor;","import { type ReactNode, useContext, useCallback, useMemo, useRef, useState } from 'react';\nimport type { EditorSnapshot, ApiConfig, SqlSchema, CompletionProvider } from '@monaco-ai-editor/core';\nimport { EditorBus } from '@monaco-ai-editor/core';\nimport type { EditorController, AiChatController } from '@monaco-ai-editor/core';\nimport { EditorCoordinatorContext } from './internal';\n\nexport interface EditorCoordinatorValue {\n editor: EditorController | null;\n chat: AiChatController | null;\n editorState: EditorSnapshot;\n patchEditorState: (patch: Partial<EditorSnapshot>) => void;\n setEditor: (controller: EditorController | null) => void;\n setChat: (controller: AiChatController | null) => void;\n bus: EditorBus;\n apiConfig: ApiConfig | null;\n sqlSchema: SqlSchema;\n completionProviders: CompletionProvider[];\n onApiConfigChange?: (config: ApiConfig) => void;\n}\n\nexport interface EditorCoordinatorProps {\n children: ReactNode;\n language?: string;\n theme?: string;\n apiConfig?: ApiConfig;\n sqlSchema?: SqlSchema;\n completionProviders?: CompletionProvider[];\n onApiConfigChange?: (config: ApiConfig) => void;\n}\n\nexport function EditorCoordinator({\n children,\n language: initialLang,\n theme: initialTheme,\n apiConfig: initialApiConfig,\n sqlSchema,\n completionProviders = [],\n onApiConfigChange,\n}: EditorCoordinatorProps) {\n const busRef = useRef(new EditorBus());\n const [editor, setEditor] = useState<EditorController | null>(null);\n const [chat, setChat] = useState<AiChatController | null>(null);\n const [editorState, setEditorState] = useState<EditorSnapshot>({\n value: '',\n language: initialLang ?? 'typescript',\n theme: initialTheme ?? 'vs-dark',\n cursorLine: 1,\n cursorColumn: 1,\n });\n\n const patchEditorState = useCallback((patch: Partial<EditorSnapshot>) => {\n setEditorState((prev) => ({ ...prev, ...patch }));\n }, []);\n\n const value = useMemo<EditorCoordinatorValue>(\n () => ({\n editor,\n chat,\n editorState,\n patchEditorState,\n setEditor,\n setChat,\n bus: busRef.current,\n apiConfig: initialApiConfig ?? null,\n sqlSchema: sqlSchema ?? {},\n completionProviders,\n onApiConfigChange,\n }),\n [editor, chat, editorState, patchEditorState, initialApiConfig, sqlSchema, completionProviders, onApiConfigChange],\n );\n\n return (\n <EditorCoordinatorContext.Provider value={value}>\n {children}\n </EditorCoordinatorContext.Provider>\n );\n}\n\nexport function useEditorCoordinator(): EditorCoordinatorValue {\n const ctx = useContext(EditorCoordinatorContext);\n if (!ctx) throw new Error('useEditorCoordinator must be used within <EditorCoordinator>');\n return ctx;\n}","import { loader } from '@monaco-editor/react';\nimport { LOCALES, type Locale } from '@monaco-ai-editor/core';\n\nexport interface ConfigureMonacoOptions {\n /** UI 本地化语言,默认 'zh-cn'(中文) */\n locale?: Locale;\n /**\n * monaco-editor 的 vs 资源路径。\n * - 不传:自动使用 `${import.meta.env.BASE_URL}vs`(配合 monacoAssetsPlugin 插件)\n * - 传 CDN 或其他路径:覆盖默认行为\n */\n vsPath?: string;\n}\n\n/**\n * 配置 Monaco Editor 的 loader(资源路径 + UI 本地化语言)。\n *\n * 必须在 EditorPanel 首次渲染前调用(模块顶层或应用初始化时)。\n *\n * 默认使用本地 vs 路径,需在 vite.config.ts 中注册 `monacoAssetsPlugin()`。\n * 该插件会在 dev 时 serve node_modules/monaco-editor/min/vs 文件,\n * 并处理 monaco-editor 0.55.x NLS 文件名 `.js.js` → `.js` 的重映射。\n *\n * @example\n * // 默认:本地路径 + 中文(需配合 monacoAssetsPlugin)\n * configureMonaco({ locale: LOCALES.ZH_CN });\n *\n * // 使用 CDN + 英文\n * configureMonaco({ locale: LOCALES.EN, vsPath: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs' });\n */\nexport function configureMonaco(options: ConfigureMonacoOptions = {}): void {\n const { locale = LOCALES.ZH_CN, vsPath } = options;\n\n // 默认使用本地路径(配合 monacoAssetsPlugin 插件)\n const baseUrl = (import.meta.env?.BASE_URL ?? '/').replace(/\\/$/, '');\n const effectiveVsPath = vsPath ?? `${baseUrl}/vs`;\n\n const config: Parameters<typeof loader.config>[0] = {\n paths: { vs: effectiveVsPath },\n 'vs/nls': {\n availableLanguages: { '*': locale },\n },\n };\n\n loader.config(config);\n}\n"],"mappings":"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","names":["import_react","import_react","Editor","import_react","import_core","import_jsx_runtime","import_core","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_core","import_jsx_runtime","import_jsx_runtime","import_react","import_core","import_core"]}
@@ -0,0 +1,168 @@
1
+ import * as react from 'react';
2
+ import { FC, ReactNode } from 'react';
3
+ import * as MonacoType from 'monaco-editor';
4
+ import { SqlSchema, ApiConfig, CompletionProvider, EditorController, Locale, AiChatController, EditorSnapshot, EditorBus } from '@monaco-ai-editor/core';
5
+ export { AiChatController, ApiConfig, ChatMessage, CompletionContext, CompletionProvider, EditorBus, EditorController, EditorSnapshot, LANGUAGES, LOCALES, Locale, PendingCompletion, SQL_DATA_TYPES, SQL_FUNCTIONS, SQL_KEYWORDS, SqlSchema, THEMES } from '@monaco-ai-editor/core';
6
+
7
+ interface EditorPanelProps {
8
+ /** 受控/非受控通用:初始值(独立模式下使用) */
9
+ value?: string;
10
+ onChange?: (value: string) => void;
11
+ language?: string;
12
+ theme?: string;
13
+ /** 高级:自定义 Monaco loader 路径(默认走 CDN) */
14
+ vsPath?: string;
15
+ /** SQL 表结构(启用 SQL 时) */
16
+ sqlSchema?: SqlSchema;
17
+ /**
18
+ * 需要从内置 SQL 关键字/函数补全中排除的 label(大写不敏感)。
19
+ * 用于让 completionProviders 中的自定义同名词条覆盖内置项,避免重复提示。
20
+ */
21
+ builtinSqlExcludeLabels?: string[];
22
+ /** AI 配置(用于 Ctrl+Alt+L 触发的 AI 行内补全) */
23
+ apiConfig?: ApiConfig | null;
24
+ /** 自定义补全扩展 */
25
+ completionProviders?: CompletionProvider[];
26
+ /** Monaco 实例就绪回调(拿到 controller) */
27
+ onMount?: (controller: EditorController) => void;
28
+ /**
29
+ * 右侧代码缩略图(minimap)配置。
30
+ * - 传 `true`/`false` 快捷开关
31
+ * - 传对象可细粒度自定义(仅覆盖指定字段,其余沿用默认值)
32
+ * - 默认开启
33
+ */
34
+ minimap?: boolean | MonacoType.editor.IEditorMinimapOptions;
35
+ /** 自定义 Monaco editor options */
36
+ editorOptions?: MonacoType.editor.IStandaloneEditorConstructionOptions;
37
+ /** AI 补全错误回调 */
38
+ onAiError?: (message: string) => void;
39
+ /** 容器样式类 */
40
+ className?: string;
41
+ /** 编辑器加载时的占位内容(覆盖 @monaco-editor/react 默认的 "Loading...") */
42
+ loading?: React.ReactNode;
43
+ }
44
+ /**
45
+ * Monaco 编辑器面板。
46
+ * - 独立模式:通过 props 完全控制
47
+ * - 联动模式:自动从 EditorCoordinator 继承配置,并向 bus 注册 controller
48
+ */
49
+ declare const EditorPanel: FC<EditorPanelProps>;
50
+
51
+ interface AiChatPanelProps {
52
+ /** 独立模式:编辑器当前内容 */
53
+ editorContent?: string;
54
+ /** 独立模式:当前语言 */
55
+ language?: string;
56
+ /** 独立模式:插入代码回调 */
57
+ onInsertCode?: (code: string) => void;
58
+ /** 独立模式:替换全部代码回调 */
59
+ onReplaceCode?: (code: string) => void;
60
+ /** 关闭面板 */
61
+ onClose?: () => void;
62
+ /** AI 配置 */
63
+ apiConfig?: ApiConfig;
64
+ /** 设置保存后回调 */
65
+ onApiConfigChange?: (config: ApiConfig) => void;
66
+ /** 容器宽度(默认 320) */
67
+ defaultWidth?: number;
68
+ className?: string;
69
+ }
70
+ declare const AiChatPanel: FC<AiChatPanelProps>;
71
+
72
+ interface ToolbarProps {
73
+ language?: string;
74
+ theme?: string;
75
+ onLanguageChange?: (lang: string) => void;
76
+ onThemeChange?: (theme: string) => void;
77
+ onFormat?: () => void;
78
+ onToggleAiChat?: () => void;
79
+ aiChatVisible?: boolean;
80
+ className?: string;
81
+ }
82
+ declare const Toolbar: FC<ToolbarProps>;
83
+
84
+ interface StatusBarProps {
85
+ language?: string;
86
+ lineCount?: number;
87
+ charCount?: number;
88
+ cursorLine?: number;
89
+ cursorColumn?: number;
90
+ className?: string;
91
+ }
92
+ declare const StatusBar: FC<StatusBarProps>;
93
+
94
+ interface MonacoAiEditorProps {
95
+ language?: string;
96
+ theme?: string;
97
+ value?: string;
98
+ onChange?: (value: string) => void;
99
+ apiConfig?: ApiConfig;
100
+ onApiConfigChange?: (config: ApiConfig) => void;
101
+ sqlSchema?: SqlSchema;
102
+ completionProviders?: CompletionProvider[];
103
+ vsPath?: string;
104
+ showToolbar?: boolean;
105
+ showStatusBar?: boolean;
106
+ showAiChat?: boolean;
107
+ className?: string;
108
+ }
109
+ /**
110
+ * 预组合组件:编辑器 + 工具栏 + 状态栏 + AI 聊天面板,一行接入。
111
+ * 内部自动用 EditorCoordinator 包裹,实现联动。
112
+ */
113
+ declare const MonacoAiEditor: FC<MonacoAiEditorProps>;
114
+
115
+ interface ConfigureMonacoOptions {
116
+ /** UI 本地化语言,默认 'zh-cn'(中文) */
117
+ locale?: Locale;
118
+ /**
119
+ * monaco-editor 的 vs 资源路径。
120
+ * - 不传:自动使用 `${import.meta.env.BASE_URL}vs`(配合 monacoAssetsPlugin 插件)
121
+ * - 传 CDN 或其他路径:覆盖默认行为
122
+ */
123
+ vsPath?: string;
124
+ }
125
+ /**
126
+ * 配置 Monaco Editor 的 loader(资源路径 + UI 本地化语言)。
127
+ *
128
+ * 必须在 EditorPanel 首次渲染前调用(模块顶层或应用初始化时)。
129
+ *
130
+ * 默认使用本地 vs 路径,需在 vite.config.ts 中注册 `monacoAssetsPlugin()`。
131
+ * 该插件会在 dev 时 serve node_modules/monaco-editor/min/vs 文件,
132
+ * 并处理 monaco-editor 0.55.x NLS 文件名 `.js.js` → `.js` 的重映射。
133
+ *
134
+ * @example
135
+ * // 默认:本地路径 + 中文(需配合 monacoAssetsPlugin)
136
+ * configureMonaco({ locale: LOCALES.ZH_CN });
137
+ *
138
+ * // 使用 CDN + 英文
139
+ * configureMonaco({ locale: LOCALES.EN, vsPath: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs' });
140
+ */
141
+ declare function configureMonaco(options?: ConfigureMonacoOptions): void;
142
+
143
+ interface EditorCoordinatorValue {
144
+ editor: EditorController | null;
145
+ chat: AiChatController | null;
146
+ editorState: EditorSnapshot;
147
+ patchEditorState: (patch: Partial<EditorSnapshot>) => void;
148
+ setEditor: (controller: EditorController | null) => void;
149
+ setChat: (controller: AiChatController | null) => void;
150
+ bus: EditorBus;
151
+ apiConfig: ApiConfig | null;
152
+ sqlSchema: SqlSchema;
153
+ completionProviders: CompletionProvider[];
154
+ onApiConfigChange?: (config: ApiConfig) => void;
155
+ }
156
+ interface EditorCoordinatorProps {
157
+ children: ReactNode;
158
+ language?: string;
159
+ theme?: string;
160
+ apiConfig?: ApiConfig;
161
+ sqlSchema?: SqlSchema;
162
+ completionProviders?: CompletionProvider[];
163
+ onApiConfigChange?: (config: ApiConfig) => void;
164
+ }
165
+ declare function EditorCoordinator({ children, language: initialLang, theme: initialTheme, apiConfig: initialApiConfig, sqlSchema, completionProviders, onApiConfigChange, }: EditorCoordinatorProps): react.JSX.Element;
166
+ declare function useEditorCoordinator(): EditorCoordinatorValue;
167
+
168
+ export { AiChatPanel, type AiChatPanelProps, type ConfigureMonacoOptions, EditorCoordinator, type EditorCoordinatorProps, type EditorCoordinatorValue, EditorPanel, type EditorPanelProps, MonacoAiEditor, type MonacoAiEditorProps, StatusBar, type StatusBarProps, Toolbar, type ToolbarProps, configureMonaco, useEditorCoordinator };
@@ -0,0 +1,168 @@
1
+ import * as react from 'react';
2
+ import { FC, ReactNode } from 'react';
3
+ import * as MonacoType from 'monaco-editor';
4
+ import { SqlSchema, ApiConfig, CompletionProvider, EditorController, Locale, AiChatController, EditorSnapshot, EditorBus } from '@monaco-ai-editor/core';
5
+ export { AiChatController, ApiConfig, ChatMessage, CompletionContext, CompletionProvider, EditorBus, EditorController, EditorSnapshot, LANGUAGES, LOCALES, Locale, PendingCompletion, SQL_DATA_TYPES, SQL_FUNCTIONS, SQL_KEYWORDS, SqlSchema, THEMES } from '@monaco-ai-editor/core';
6
+
7
+ interface EditorPanelProps {
8
+ /** 受控/非受控通用:初始值(独立模式下使用) */
9
+ value?: string;
10
+ onChange?: (value: string) => void;
11
+ language?: string;
12
+ theme?: string;
13
+ /** 高级:自定义 Monaco loader 路径(默认走 CDN) */
14
+ vsPath?: string;
15
+ /** SQL 表结构(启用 SQL 时) */
16
+ sqlSchema?: SqlSchema;
17
+ /**
18
+ * 需要从内置 SQL 关键字/函数补全中排除的 label(大写不敏感)。
19
+ * 用于让 completionProviders 中的自定义同名词条覆盖内置项,避免重复提示。
20
+ */
21
+ builtinSqlExcludeLabels?: string[];
22
+ /** AI 配置(用于 Ctrl+Alt+L 触发的 AI 行内补全) */
23
+ apiConfig?: ApiConfig | null;
24
+ /** 自定义补全扩展 */
25
+ completionProviders?: CompletionProvider[];
26
+ /** Monaco 实例就绪回调(拿到 controller) */
27
+ onMount?: (controller: EditorController) => void;
28
+ /**
29
+ * 右侧代码缩略图(minimap)配置。
30
+ * - 传 `true`/`false` 快捷开关
31
+ * - 传对象可细粒度自定义(仅覆盖指定字段,其余沿用默认值)
32
+ * - 默认开启
33
+ */
34
+ minimap?: boolean | MonacoType.editor.IEditorMinimapOptions;
35
+ /** 自定义 Monaco editor options */
36
+ editorOptions?: MonacoType.editor.IStandaloneEditorConstructionOptions;
37
+ /** AI 补全错误回调 */
38
+ onAiError?: (message: string) => void;
39
+ /** 容器样式类 */
40
+ className?: string;
41
+ /** 编辑器加载时的占位内容(覆盖 @monaco-editor/react 默认的 "Loading...") */
42
+ loading?: React.ReactNode;
43
+ }
44
+ /**
45
+ * Monaco 编辑器面板。
46
+ * - 独立模式:通过 props 完全控制
47
+ * - 联动模式:自动从 EditorCoordinator 继承配置,并向 bus 注册 controller
48
+ */
49
+ declare const EditorPanel: FC<EditorPanelProps>;
50
+
51
+ interface AiChatPanelProps {
52
+ /** 独立模式:编辑器当前内容 */
53
+ editorContent?: string;
54
+ /** 独立模式:当前语言 */
55
+ language?: string;
56
+ /** 独立模式:插入代码回调 */
57
+ onInsertCode?: (code: string) => void;
58
+ /** 独立模式:替换全部代码回调 */
59
+ onReplaceCode?: (code: string) => void;
60
+ /** 关闭面板 */
61
+ onClose?: () => void;
62
+ /** AI 配置 */
63
+ apiConfig?: ApiConfig;
64
+ /** 设置保存后回调 */
65
+ onApiConfigChange?: (config: ApiConfig) => void;
66
+ /** 容器宽度(默认 320) */
67
+ defaultWidth?: number;
68
+ className?: string;
69
+ }
70
+ declare const AiChatPanel: FC<AiChatPanelProps>;
71
+
72
+ interface ToolbarProps {
73
+ language?: string;
74
+ theme?: string;
75
+ onLanguageChange?: (lang: string) => void;
76
+ onThemeChange?: (theme: string) => void;
77
+ onFormat?: () => void;
78
+ onToggleAiChat?: () => void;
79
+ aiChatVisible?: boolean;
80
+ className?: string;
81
+ }
82
+ declare const Toolbar: FC<ToolbarProps>;
83
+
84
+ interface StatusBarProps {
85
+ language?: string;
86
+ lineCount?: number;
87
+ charCount?: number;
88
+ cursorLine?: number;
89
+ cursorColumn?: number;
90
+ className?: string;
91
+ }
92
+ declare const StatusBar: FC<StatusBarProps>;
93
+
94
+ interface MonacoAiEditorProps {
95
+ language?: string;
96
+ theme?: string;
97
+ value?: string;
98
+ onChange?: (value: string) => void;
99
+ apiConfig?: ApiConfig;
100
+ onApiConfigChange?: (config: ApiConfig) => void;
101
+ sqlSchema?: SqlSchema;
102
+ completionProviders?: CompletionProvider[];
103
+ vsPath?: string;
104
+ showToolbar?: boolean;
105
+ showStatusBar?: boolean;
106
+ showAiChat?: boolean;
107
+ className?: string;
108
+ }
109
+ /**
110
+ * 预组合组件:编辑器 + 工具栏 + 状态栏 + AI 聊天面板,一行接入。
111
+ * 内部自动用 EditorCoordinator 包裹,实现联动。
112
+ */
113
+ declare const MonacoAiEditor: FC<MonacoAiEditorProps>;
114
+
115
+ interface ConfigureMonacoOptions {
116
+ /** UI 本地化语言,默认 'zh-cn'(中文) */
117
+ locale?: Locale;
118
+ /**
119
+ * monaco-editor 的 vs 资源路径。
120
+ * - 不传:自动使用 `${import.meta.env.BASE_URL}vs`(配合 monacoAssetsPlugin 插件)
121
+ * - 传 CDN 或其他路径:覆盖默认行为
122
+ */
123
+ vsPath?: string;
124
+ }
125
+ /**
126
+ * 配置 Monaco Editor 的 loader(资源路径 + UI 本地化语言)。
127
+ *
128
+ * 必须在 EditorPanel 首次渲染前调用(模块顶层或应用初始化时)。
129
+ *
130
+ * 默认使用本地 vs 路径,需在 vite.config.ts 中注册 `monacoAssetsPlugin()`。
131
+ * 该插件会在 dev 时 serve node_modules/monaco-editor/min/vs 文件,
132
+ * 并处理 monaco-editor 0.55.x NLS 文件名 `.js.js` → `.js` 的重映射。
133
+ *
134
+ * @example
135
+ * // 默认:本地路径 + 中文(需配合 monacoAssetsPlugin)
136
+ * configureMonaco({ locale: LOCALES.ZH_CN });
137
+ *
138
+ * // 使用 CDN + 英文
139
+ * configureMonaco({ locale: LOCALES.EN, vsPath: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.55.1/min/vs' });
140
+ */
141
+ declare function configureMonaco(options?: ConfigureMonacoOptions): void;
142
+
143
+ interface EditorCoordinatorValue {
144
+ editor: EditorController | null;
145
+ chat: AiChatController | null;
146
+ editorState: EditorSnapshot;
147
+ patchEditorState: (patch: Partial<EditorSnapshot>) => void;
148
+ setEditor: (controller: EditorController | null) => void;
149
+ setChat: (controller: AiChatController | null) => void;
150
+ bus: EditorBus;
151
+ apiConfig: ApiConfig | null;
152
+ sqlSchema: SqlSchema;
153
+ completionProviders: CompletionProvider[];
154
+ onApiConfigChange?: (config: ApiConfig) => void;
155
+ }
156
+ interface EditorCoordinatorProps {
157
+ children: ReactNode;
158
+ language?: string;
159
+ theme?: string;
160
+ apiConfig?: ApiConfig;
161
+ sqlSchema?: SqlSchema;
162
+ completionProviders?: CompletionProvider[];
163
+ onApiConfigChange?: (config: ApiConfig) => void;
164
+ }
165
+ declare function EditorCoordinator({ children, language: initialLang, theme: initialTheme, apiConfig: initialApiConfig, sqlSchema, completionProviders, onApiConfigChange, }: EditorCoordinatorProps): react.JSX.Element;
166
+ declare function useEditorCoordinator(): EditorCoordinatorValue;
167
+
168
+ export { AiChatPanel, type AiChatPanelProps, type ConfigureMonacoOptions, EditorCoordinator, type EditorCoordinatorProps, type EditorCoordinatorValue, EditorPanel, type EditorPanelProps, MonacoAiEditor, type MonacoAiEditorProps, StatusBar, type StatusBarProps, Toolbar, type ToolbarProps, configureMonaco, useEditorCoordinator };