mirror of
https://github.com/adnaan-worker/adnify.git
synced 2026-09-01 15:12:10 +08:00
refactor: 消除硬编码,扩展语言支持,优化性能
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
* text=auto eol=lf
|
||||
*.ts text eol=lf
|
||||
*.tsx text eol=lf
|
||||
*.js text eol=lf
|
||||
*.jsx text eol=lf
|
||||
*.json text eol=lf
|
||||
*.css text eol=lf
|
||||
*.html text eol=lf
|
||||
*.md text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.yaml text eol=lf
|
||||
+63
-62
@@ -11,6 +11,31 @@ import { registerAllHandlers, cleanupAllHandlers, updateLLMServiceWindow } from
|
||||
import { lspManager } from './lspManager'
|
||||
import { securityManager, updateWhitelist } from './security'
|
||||
|
||||
// 共享安全常量(与 renderer 保持一致)
|
||||
const SECURITY_DEFAULTS = {
|
||||
SHELL_COMMANDS: [
|
||||
// 包管理器
|
||||
'npm', 'yarn', 'pnpm', 'bun',
|
||||
// 运行时
|
||||
'node', 'npx', 'deno',
|
||||
// 版本控制
|
||||
'git',
|
||||
// 编程语言
|
||||
'python', 'python3', 'pip', 'pip3',
|
||||
'java', 'javac', 'mvn', 'gradle',
|
||||
'go', 'rust', 'cargo',
|
||||
// 构建工具
|
||||
'make', 'gcc', 'clang', 'cmake',
|
||||
// 常用命令
|
||||
'pwd', 'ls', 'dir', 'cat', 'type', 'echo', 'mkdir', 'touch', 'rm', 'mv', 'cp', 'cd',
|
||||
],
|
||||
GIT_SUBCOMMANDS: [
|
||||
'status', 'log', 'diff', 'add', 'commit', 'push', 'pull',
|
||||
'branch', 'checkout', 'merge', 'rebase', 'clone', 'remote',
|
||||
'fetch', 'show', 'rev-parse', 'init', 'stash', 'tag',
|
||||
],
|
||||
} as const
|
||||
|
||||
// ==========================================
|
||||
// Store 初始化
|
||||
// ==========================================
|
||||
@@ -29,41 +54,37 @@ function initStore() {
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化 store
|
||||
initStore()
|
||||
|
||||
// ==========================================
|
||||
// 全局状态
|
||||
// 窗口管理
|
||||
// ==========================================
|
||||
|
||||
const windows = new Map<number, BrowserWindow>()
|
||||
let lastActiveWindow: BrowserWindow | null = null
|
||||
let isQuitting = false
|
||||
const windows = new Set<BrowserWindow>()
|
||||
let mainWindow: BrowserWindow | null = null
|
||||
|
||||
function getMainWindow() {
|
||||
return lastActiveWindow || Array.from(windows.values())[0] || null
|
||||
function getMainWindow(): BrowserWindow | null {
|
||||
return mainWindow
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 窗口创建
|
||||
// ==========================================
|
||||
|
||||
function createWindow(isEmpty: boolean = false) {
|
||||
// 图标路径:开发环境用 public,生产环境用 resources
|
||||
const iconPath = app.isPackaged
|
||||
? path.join(process.resourcesPath, 'icon.png')
|
||||
: path.join(__dirname, '../../public/icon.png')
|
||||
// 单例锁定
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
if (!gotTheLock) {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
function createWindow(isEmpty = true): BrowserWindow {
|
||||
const win = new BrowserWindow({
|
||||
width: 1600,
|
||||
height: 1000,
|
||||
minWidth: 1200,
|
||||
minHeight: 700,
|
||||
frame: false,
|
||||
titleBarStyle: 'hidden',
|
||||
icon: iconPath,
|
||||
trafficLightPosition: { x: 15, y: 15 },
|
||||
backgroundColor: '#09090b',
|
||||
show: false,
|
||||
show: false, // 等待渲染完成后显示
|
||||
titleBarStyle: 'hidden',
|
||||
titleBarOverlay: false,
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, '../preload/preload.js'),
|
||||
contextIsolation: true,
|
||||
@@ -71,51 +92,30 @@ function createWindow(isEmpty: boolean = false) {
|
||||
},
|
||||
})
|
||||
|
||||
const windowId = win.id
|
||||
windows.set(windowId, win)
|
||||
lastActiveWindow = win
|
||||
windows.add(win)
|
||||
if (!mainWindow) {
|
||||
mainWindow = win
|
||||
}
|
||||
|
||||
win.on('focus', () => {
|
||||
lastActiveWindow = win
|
||||
updateLLMServiceWindow(win)
|
||||
})
|
||||
// 每个窗口都需要更新 LLM service 的引用
|
||||
updateLLMServiceWindow(win)
|
||||
|
||||
win.once('ready-to-show', () => {
|
||||
win.show()
|
||||
console.log(`[Main] Window ${windowId} shown`)
|
||||
if (!app.isPackaged) {
|
||||
win.webContents.openDevTools({ mode: 'detach' })
|
||||
}
|
||||
})
|
||||
|
||||
win.on('close', async (e) => {
|
||||
if (windows.size === 1 && !isQuitting) {
|
||||
// 最后一个窗口关闭时,执行全局清理
|
||||
isQuitting = true
|
||||
e.preventDefault()
|
||||
console.log('[Main] Last window closing, starting cleanup...')
|
||||
try {
|
||||
cleanupAllHandlers()
|
||||
await lspManager.stopAllServers()
|
||||
console.log('[Main] Cleanup completed')
|
||||
} catch (err) {
|
||||
console.error('[Main] Cleanup error:', err)
|
||||
}
|
||||
win.destroy()
|
||||
app.quit()
|
||||
win.on('closed', () => {
|
||||
windows.delete(win)
|
||||
if (windows.size === 0) {
|
||||
mainWindow = null
|
||||
cleanupAllHandlers()
|
||||
lspManager.stopAllServers()
|
||||
} else {
|
||||
// 非最后一个窗口,直接移除引用
|
||||
windows.delete(windowId)
|
||||
if (lastActiveWindow === win) {
|
||||
lastActiveWindow = Array.from(windows.values())[0] || null
|
||||
// 如果关闭的是 mainWindow,选择一个新的
|
||||
if (mainWindow === win) {
|
||||
mainWindow = windows.values().next().value ?? null
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 加载页面
|
||||
const query = isEmpty ? '?empty=1' : ''
|
||||
if (!app.isPackaged) {
|
||||
win.loadURL(`http://localhost:5173${query}`)
|
||||
if (process.env.NODE_ENV === 'development' || !app.isPackaged) {
|
||||
win.loadURL(`http://localhost:5173${isEmpty ? '?empty=1' : ''}`)
|
||||
} else {
|
||||
win.loadFile(path.join(__dirname, '../renderer/index.html'), { query: isEmpty ? { empty: '1' } : undefined })
|
||||
}
|
||||
@@ -130,19 +130,20 @@ function createWindow(isEmpty: boolean = false) {
|
||||
app.whenReady().then(() => {
|
||||
console.log('[Security] 🔒 初始化安全模块...')
|
||||
|
||||
// 使用共享常量作为默认值
|
||||
const securityConfig = mainStore.get('securitySettings', {
|
||||
enablePermissionConfirm: true,
|
||||
enableAuditLog: true,
|
||||
strictWorkspaceMode: true,
|
||||
allowedShellCommands: ['npm', 'yarn', 'pnpm', 'node', 'npx', 'git', 'python', 'python3', 'java', 'go', 'rust', 'cargo', 'make', 'gcc', 'clang', 'pwd', 'ls', 'cat', 'echo', 'mkdir', 'touch', 'rm', 'mv', 'cd'],
|
||||
allowedGitSubcommands: ['status', 'log', 'diff', 'add', 'commit', 'push', 'pull', 'branch', 'checkout', 'merge', 'rebase', 'clone', 'remote', 'fetch', 'show', 'rev-parse', 'init'],
|
||||
allowedShellCommands: [...SECURITY_DEFAULTS.SHELL_COMMANDS],
|
||||
allowedGitSubcommands: [...SECURITY_DEFAULTS.GIT_SUBCOMMANDS],
|
||||
}) as any
|
||||
|
||||
securityManager.updateConfig(securityConfig)
|
||||
|
||||
// 初始化白名单
|
||||
const shellCommands = securityConfig.allowedShellCommands || ['npm', 'yarn', 'pnpm', 'node', 'npx', 'git']
|
||||
const gitCommands = securityConfig.allowedGitSubcommands || ['status', 'log', 'diff', 'add', 'commit', 'push', 'pull', 'branch', 'checkout', 'merge', 'rebase', 'clone', 'remote', 'fetch', 'show', 'rev-parse', 'init']
|
||||
const shellCommands = securityConfig.allowedShellCommands || [...SECURITY_DEFAULTS.SHELL_COMMANDS]
|
||||
const gitCommands = securityConfig.allowedGitSubcommands || [...SECURITY_DEFAULTS.GIT_SUBCOMMANDS]
|
||||
updateWhitelist(shellCommands, gitCommands)
|
||||
|
||||
console.log('[Security] ✅ 安全模块已初始化')
|
||||
|
||||
+16
-9
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState, useCallback } from 'react'
|
||||
import { useEffect, useState, useCallback, lazy, Suspense } from 'react'
|
||||
import { useStore } from './store'
|
||||
import TitleBar from './components/TitleBar'
|
||||
import Sidebar from './components/Sidebar'
|
||||
@@ -11,8 +11,6 @@ import KeyboardShortcuts from './components/KeyboardShortcuts'
|
||||
import QuickOpen from './components/QuickOpen'
|
||||
import ActivityBar from './components/ActivityBar'
|
||||
import StatusBar from './components/StatusBar'
|
||||
import ComposerPanel from './components/ComposerPanel'
|
||||
import OnboardingWizard from './components/OnboardingWizard'
|
||||
import { ToastProvider, useToast, setGlobalToast } from './components/Toast'
|
||||
import { GlobalConfirmDialog } from './components/ConfirmDialog'
|
||||
import { ErrorBoundary } from './components/ErrorBoundary'
|
||||
@@ -26,8 +24,13 @@ import { checkpointService } from './agent/checkpointService'
|
||||
import { useAgentStore } from './agent/core/AgentStore'
|
||||
import { keybindingService } from './services/keybindingService'
|
||||
import { registerCoreCommands } from './config/commands'
|
||||
import { LAYOUT_LIMITS } from '../shared/constants'
|
||||
import noiseSvg from './assets/images/noise.svg'
|
||||
|
||||
// 懒加载大组件以优化首屏性能
|
||||
const ComposerPanel = lazy(() => import('./components/ComposerPanel'))
|
||||
const OnboardingWizard = lazy(() => import('./components/OnboardingWizard'))
|
||||
|
||||
// 暴露 store 给插件系统
|
||||
; (window as any).__ADNIFY_STORE__ = { getState: () => useStore.getState() }
|
||||
|
||||
@@ -195,20 +198,20 @@ function AppContent() {
|
||||
return cleanup
|
||||
}, [])
|
||||
|
||||
// Resize Logic
|
||||
// Resize Logic - 使用共享常量
|
||||
useEffect(() => {
|
||||
if (!isResizingSidebar && !isResizingChat) return
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
if (isResizingSidebar) {
|
||||
const newWidth = e.clientX - 48 // 48 is ActivityBar width
|
||||
if (newWidth > 150 && newWidth < 600) {
|
||||
const newWidth = e.clientX - LAYOUT_LIMITS.ACTIVITY_BAR_WIDTH
|
||||
if (newWidth > LAYOUT_LIMITS.SIDEBAR_MIN_WIDTH && newWidth < LAYOUT_LIMITS.SIDEBAR_MAX_WIDTH) {
|
||||
setSidebarWidth(newWidth)
|
||||
}
|
||||
}
|
||||
if (isResizingChat) {
|
||||
const newWidth = window.innerWidth - e.clientX
|
||||
if (newWidth > 300 && newWidth < 800) {
|
||||
if (newWidth > LAYOUT_LIMITS.CHAT_MIN_WIDTH && newWidth < LAYOUT_LIMITS.CHAT_MAX_WIDTH) {
|
||||
setChatWidth(newWidth)
|
||||
}
|
||||
}
|
||||
@@ -355,10 +358,14 @@ function AppContent() {
|
||||
<QuickOpen onClose={() => setShowQuickOpen(false)} />
|
||||
)}
|
||||
{showComposer && (
|
||||
<ComposerPanel onClose={() => setShowComposer(false)} />
|
||||
<Suspense fallback={null}>
|
||||
<ComposerPanel onClose={() => setShowComposer(false)} />
|
||||
</Suspense>
|
||||
)}
|
||||
{showOnboarding && isInitialized && (
|
||||
<OnboardingWizard onComplete={() => setShowOnboarding(false)} />
|
||||
<Suspense fallback={null}>
|
||||
<OnboardingWizard onComplete={() => setShowOnboarding(false)} />
|
||||
</Suspense>
|
||||
)}
|
||||
{showAbout && <AboutDialog onClose={() => setShowAbout(false)} />}
|
||||
<GlobalConfirmDialog />
|
||||
|
||||
@@ -5,18 +5,19 @@
|
||||
|
||||
import { ChatMode } from '../store'
|
||||
import { rulesService } from './rulesService'
|
||||
import { FILE_LIMITS } from '../../shared/constants'
|
||||
|
||||
// Search/Replace 块格式 (Git 风格,LLM 更熟悉)
|
||||
export const ORIGINAL = '<<<<<<< SEARCH'
|
||||
export const DIVIDER = '======='
|
||||
export const FINAL = '>>>>>>> REPLACE'
|
||||
|
||||
// 限制常量(与 editorConfig.ts 保持一致)
|
||||
export const MAX_FILE_CHARS = 60000
|
||||
export const MAX_DIR_ITEMS = 150
|
||||
export const MAX_SEARCH_RESULTS = 30
|
||||
export const MAX_TERMINAL_OUTPUT = 3000
|
||||
export const MAX_CONTEXT_CHARS = 30000
|
||||
// 限制常量(从共享配置导入)
|
||||
export const MAX_FILE_CHARS = FILE_LIMITS.MAX_FILE_CHARS
|
||||
export const MAX_DIR_ITEMS = FILE_LIMITS.MAX_DIR_ITEMS
|
||||
export const MAX_SEARCH_RESULTS = FILE_LIMITS.MAX_SEARCH_RESULTS
|
||||
export const MAX_TERMINAL_OUTPUT = FILE_LIMITS.MAX_TERMINAL_OUTPUT
|
||||
export const MAX_CONTEXT_CHARS = FILE_LIMITS.MAX_CONTEXT_CHARS
|
||||
|
||||
// Search/Replace 块模板
|
||||
const searchReplaceBlockTemplate = `\
|
||||
@@ -161,7 +162,7 @@ export async function buildSystemPrompt(
|
||||
|
||||
// 获取提示词模板
|
||||
const { getPromptTemplateById, getDefaultPromptTemplate } = await import('./promptTemplates')
|
||||
const template = promptTemplateId
|
||||
const template = promptTemplateId
|
||||
? getPromptTemplateById(promptTemplateId) || getDefaultPromptTemplate()
|
||||
: getDefaultPromptTemplate()
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* 双重存储:localStorage(快速读取)+ 文件(持久化备份)
|
||||
*/
|
||||
|
||||
import { IGNORED_DIRECTORIES } from '../../shared/languages'
|
||||
|
||||
export interface EditorConfig {
|
||||
// 编辑器外观
|
||||
fontSize: number
|
||||
@@ -118,20 +120,8 @@ export const defaultEditorConfig: EditorConfig = {
|
||||
maxSingleFileChars: 6000, // 单文件最多 6000 字符
|
||||
},
|
||||
|
||||
// 忽略的目录
|
||||
ignoredDirectories: [
|
||||
'node_modules',
|
||||
'dist',
|
||||
'build',
|
||||
'.git',
|
||||
'.next',
|
||||
'coverage',
|
||||
'__pycache__',
|
||||
'.cache',
|
||||
'out',
|
||||
'.vscode',
|
||||
'.idea',
|
||||
],
|
||||
// 忽略的目录(使用共享常量)
|
||||
ignoredDirectories: [...IGNORED_DIRECTORIES],
|
||||
}
|
||||
|
||||
// 存储 key
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import { useStore } from '../store'
|
||||
import { getEditorConfig } from '../config/editorConfig'
|
||||
import { FIM_CAPABLE_MODELS, getLanguageFromPath as sharedGetLanguageFromPath } from '../../shared/languages'
|
||||
|
||||
// ============ Interfaces ============
|
||||
|
||||
@@ -69,16 +70,8 @@ export interface CompletionOptions {
|
||||
maxCandidates: number // Max candidates to generate
|
||||
}
|
||||
|
||||
// FIM-capable models
|
||||
const FIM_MODELS = [
|
||||
'deepseek-coder',
|
||||
'codellama',
|
||||
'starcoder',
|
||||
'code-llama',
|
||||
'deepseek',
|
||||
'qwen-coder',
|
||||
'yi-coder',
|
||||
]
|
||||
// FIM-capable models (from shared config)
|
||||
const FIM_MODELS = FIM_CAPABLE_MODELS
|
||||
|
||||
|
||||
// 从配置获取默认选项
|
||||
@@ -221,22 +214,8 @@ function debounce<T extends (...args: Parameters<T>) => ReturnType<T>>(
|
||||
|
||||
|
||||
// ============ Language Detection ============
|
||||
|
||||
const LANGUAGE_MAP: Record<string, string> = {
|
||||
ts: 'typescript', tsx: 'typescript',
|
||||
js: 'javascript', jsx: 'javascript', mjs: 'javascript', cjs: 'javascript',
|
||||
py: 'python', rs: 'rust', go: 'go', java: 'java',
|
||||
cpp: 'cpp', c: 'c', h: 'c', hpp: 'cpp',
|
||||
css: 'css', scss: 'scss', less: 'less',
|
||||
html: 'html', htm: 'html', vue: 'html', svelte: 'html',
|
||||
json: 'json', yaml: 'yaml', yml: 'yaml',
|
||||
md: 'markdown', sql: 'sql', sh: 'shell', bash: 'shell',
|
||||
}
|
||||
|
||||
function getLanguageFromPath(path: string): string {
|
||||
const ext = path.split('.').pop()?.toLowerCase() || ''
|
||||
return LANGUAGE_MAP[ext] || 'plaintext'
|
||||
}
|
||||
// Use shared language configuration
|
||||
const getLanguageFromPath = sharedGetLanguageFromPath
|
||||
|
||||
// ============ Import Analysis ============
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import { useStore } from '../store'
|
||||
import { EXTENSION_TO_LANGUAGE, LSP_SUPPORTED_LANGUAGES } from '../../shared/languages'
|
||||
|
||||
// 文档版本追踪
|
||||
const documentVersions = new Map<string, number>()
|
||||
@@ -37,33 +38,14 @@ export function getFileWorkspaceRoot(filePath: string): string | null {
|
||||
*/
|
||||
export function getLanguageId(filePath: string): string {
|
||||
const ext = filePath.split('.').pop()?.toLowerCase() || ''
|
||||
const languageMap: Record<string, string> = {
|
||||
ts: 'typescript',
|
||||
tsx: 'typescriptreact',
|
||||
js: 'javascript',
|
||||
jsx: 'javascriptreact',
|
||||
mjs: 'javascript',
|
||||
cjs: 'javascript',
|
||||
html: 'html',
|
||||
htm: 'html',
|
||||
css: 'css',
|
||||
scss: 'scss',
|
||||
less: 'less',
|
||||
json: 'json',
|
||||
jsonc: 'jsonc',
|
||||
}
|
||||
return languageMap[ext] || 'plaintext'
|
||||
return EXTENSION_TO_LANGUAGE[ext] || 'plaintext'
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查语言是否支持 LSP
|
||||
*/
|
||||
export function isLanguageSupported(languageId: string): boolean {
|
||||
const supported = [
|
||||
'typescript', 'typescriptreact', 'javascript', 'javascriptreact',
|
||||
'html', 'css', 'scss', 'less', 'json', 'jsonc',
|
||||
]
|
||||
return supported.includes(languageId)
|
||||
return (LSP_SUPPORTED_LANGUAGES as readonly string[]).includes(languageId)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* 设置相关状态切片
|
||||
*/
|
||||
import { StateCreator } from 'zustand'
|
||||
import { SECURITY_DEFAULTS } from '../../../shared/constants'
|
||||
|
||||
export type ProviderType = 'openai' | 'anthropic' | 'gemini' | 'deepseek' | 'groq' | 'mistral' | 'ollama' | 'custom'
|
||||
|
||||
@@ -77,11 +78,12 @@ const defaultProviderConfigs: Record<string, ProviderModelConfig> = {
|
||||
custom: { customModels: [] },
|
||||
}
|
||||
|
||||
// 使用共享常量作为默认安全设置
|
||||
const defaultSecuritySettings: SecuritySettings = {
|
||||
enablePermissionConfirm: true,
|
||||
enableAuditLog: true,
|
||||
strictWorkspaceMode: true,
|
||||
allowedShellCommands: ['npm', 'yarn', 'pnpm', 'node', 'npx', 'git', 'ls', 'cat', 'echo', 'pwd'],
|
||||
allowedShellCommands: [...SECURITY_DEFAULTS.SHELL_COMMANDS],
|
||||
showSecurityWarnings: true,
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* 共享常量配置
|
||||
* 集中管理所有硬编码值,实现定制化
|
||||
*/
|
||||
|
||||
// ==========================================
|
||||
// 文件和搜索限制(原 prompts.ts 硬编码)
|
||||
// ==========================================
|
||||
|
||||
export const FILE_LIMITS = {
|
||||
/** 单个文件最大字符数 */
|
||||
MAX_FILE_CHARS: 60000,
|
||||
/** 目录列表最大条目数 */
|
||||
MAX_DIR_ITEMS: 150,
|
||||
/** 搜索结果最大数量 */
|
||||
MAX_SEARCH_RESULTS: 30,
|
||||
/** 终端输出最大字符数 */
|
||||
MAX_TERMINAL_OUTPUT: 3000,
|
||||
/** AI 上下文最大字符数 */
|
||||
MAX_CONTEXT_CHARS: 30000,
|
||||
} as const
|
||||
|
||||
// ==========================================
|
||||
// 布局限制(原 App.tsx 硬编码)
|
||||
// ==========================================
|
||||
|
||||
export const LAYOUT_LIMITS = {
|
||||
/** ActivityBar 宽度 */
|
||||
ACTIVITY_BAR_WIDTH: 48,
|
||||
/** 侧边栏最小宽度 */
|
||||
SIDEBAR_MIN_WIDTH: 150,
|
||||
/** 侧边栏最大宽度 */
|
||||
SIDEBAR_MAX_WIDTH: 600,
|
||||
/** 聊天面板最小宽度 */
|
||||
CHAT_MIN_WIDTH: 300,
|
||||
/** 聊天面板最大宽度 */
|
||||
CHAT_MAX_WIDTH: 800,
|
||||
} as const
|
||||
|
||||
// ==========================================
|
||||
// 窗口默认值(原 main.ts 硬编码)
|
||||
// ==========================================
|
||||
|
||||
export const WINDOW_DEFAULTS = {
|
||||
WIDTH: 1600,
|
||||
HEIGHT: 1000,
|
||||
MIN_WIDTH: 1200,
|
||||
MIN_HEIGHT: 700,
|
||||
BACKGROUND_COLOR: '#09090b',
|
||||
} as const
|
||||
|
||||
// ==========================================
|
||||
// 安全设置默认值(统一 main.ts 和 settingsSlice.ts)
|
||||
// ==========================================
|
||||
|
||||
export const SECURITY_DEFAULTS = {
|
||||
/** 允许的 Shell 命令 */
|
||||
SHELL_COMMANDS: [
|
||||
// 包管理器
|
||||
'npm', 'yarn', 'pnpm', 'bun',
|
||||
// 运行时
|
||||
'node', 'npx', 'deno',
|
||||
// 版本控制
|
||||
'git',
|
||||
// 编程语言
|
||||
'python', 'python3', 'pip', 'pip3',
|
||||
'java', 'javac', 'mvn', 'gradle',
|
||||
'go', 'rust', 'cargo',
|
||||
// 构建工具
|
||||
'make', 'gcc', 'clang', 'cmake',
|
||||
// 常用命令
|
||||
'pwd', 'ls', 'dir', 'cat', 'type', 'echo', 'mkdir', 'touch', 'rm', 'mv', 'cp', 'cd',
|
||||
],
|
||||
/** 允许的 Git 子命令 */
|
||||
GIT_SUBCOMMANDS: [
|
||||
'status', 'log', 'diff', 'add', 'commit', 'push', 'pull',
|
||||
'branch', 'checkout', 'merge', 'rebase', 'clone', 'remote',
|
||||
'fetch', 'show', 'rev-parse', 'init', 'stash', 'tag',
|
||||
],
|
||||
} as const
|
||||
|
||||
// ==========================================
|
||||
// AI 相关默认值(原 editorConfig.ts 和 settingsSlice.ts)
|
||||
// ==========================================
|
||||
|
||||
export const AI_DEFAULTS = {
|
||||
/** 默认提供商 */
|
||||
DEFAULT_PROVIDER: 'openai' as const,
|
||||
/** 默认模型 */
|
||||
DEFAULT_MODEL: 'gpt-4o',
|
||||
/** 最大工具调用循环数 */
|
||||
MAX_TOOL_LOOPS: 15,
|
||||
/** 补全最大 token 数 */
|
||||
COMPLETION_MAX_TOKENS: 256,
|
||||
/** 补全温度 */
|
||||
COMPLETION_TEMPERATURE: 0.1,
|
||||
} as const
|
||||
|
||||
// ==========================================
|
||||
// 性能相关默认值
|
||||
// ==========================================
|
||||
|
||||
export const PERFORMANCE_DEFAULTS = {
|
||||
/** 文件变化防抖延迟 (ms) */
|
||||
FILE_CHANGE_DEBOUNCE_MS: 300,
|
||||
/** 代码补全防抖延迟 (ms) */
|
||||
COMPLETION_DEBOUNCE_MS: 300,
|
||||
/** 搜索防抖延迟 (ms) */
|
||||
SEARCH_DEBOUNCE_MS: 200,
|
||||
/** Git 状态刷新间隔 (ms) */
|
||||
GIT_STATUS_INTERVAL_MS: 5000,
|
||||
/** API 请求超时 (ms) */
|
||||
REQUEST_TIMEOUT_MS: 120000,
|
||||
/** 命令执行超时 (ms) */
|
||||
COMMAND_TIMEOUT_MS: 30000,
|
||||
} as const
|
||||
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
* 语言配置
|
||||
* 统一管理文件扩展名到语言 ID 的映射,避免重复定义
|
||||
*/
|
||||
|
||||
// ==========================================
|
||||
// 文件扩展名 -> 语言 ID 映射
|
||||
// ==========================================
|
||||
|
||||
export const EXTENSION_TO_LANGUAGE: Record<string, string> = {
|
||||
// JavaScript / TypeScript
|
||||
ts: 'typescript',
|
||||
tsx: 'typescriptreact',
|
||||
js: 'javascript',
|
||||
jsx: 'javascriptreact',
|
||||
mjs: 'javascript',
|
||||
cjs: 'javascript',
|
||||
|
||||
// Python
|
||||
py: 'python',
|
||||
pyw: 'python',
|
||||
pyi: 'python',
|
||||
pyx: 'python',
|
||||
|
||||
// Rust
|
||||
rs: 'rust',
|
||||
|
||||
// Go
|
||||
go: 'go',
|
||||
|
||||
// Java / Kotlin / Scala
|
||||
java: 'java',
|
||||
kt: 'kotlin',
|
||||
kts: 'kotlin',
|
||||
scala: 'scala',
|
||||
|
||||
// C / C++
|
||||
c: 'c',
|
||||
h: 'c',
|
||||
cpp: 'cpp',
|
||||
hpp: 'cpp',
|
||||
cc: 'cpp',
|
||||
cxx: 'cpp',
|
||||
hxx: 'cpp',
|
||||
|
||||
// C#
|
||||
cs: 'csharp',
|
||||
|
||||
// Web - Markup
|
||||
html: 'html',
|
||||
htm: 'html',
|
||||
vue: 'vue',
|
||||
svelte: 'svelte',
|
||||
|
||||
// Web - Styles
|
||||
css: 'css',
|
||||
scss: 'scss',
|
||||
sass: 'sass',
|
||||
less: 'less',
|
||||
styl: 'stylus',
|
||||
|
||||
// Data formats
|
||||
json: 'json',
|
||||
jsonc: 'jsonc',
|
||||
json5: 'json5',
|
||||
yaml: 'yaml',
|
||||
yml: 'yaml',
|
||||
toml: 'toml',
|
||||
xml: 'xml',
|
||||
svg: 'xml',
|
||||
|
||||
// Shell
|
||||
sh: 'shell',
|
||||
bash: 'shell',
|
||||
zsh: 'shell',
|
||||
fish: 'shell',
|
||||
ps1: 'powershell',
|
||||
psm1: 'powershell',
|
||||
bat: 'batch',
|
||||
cmd: 'batch',
|
||||
|
||||
// Markdown / Documentation
|
||||
md: 'markdown',
|
||||
mdx: 'mdx',
|
||||
rst: 'restructuredtext',
|
||||
tex: 'latex',
|
||||
|
||||
// Database
|
||||
sql: 'sql',
|
||||
mysql: 'sql',
|
||||
pgsql: 'sql',
|
||||
|
||||
// Other languages
|
||||
rb: 'ruby',
|
||||
php: 'php',
|
||||
swift: 'swift',
|
||||
dart: 'dart',
|
||||
lua: 'lua',
|
||||
r: 'r',
|
||||
R: 'r',
|
||||
jl: 'julia',
|
||||
ex: 'elixir',
|
||||
exs: 'elixir',
|
||||
erl: 'erlang',
|
||||
hrl: 'erlang',
|
||||
hs: 'haskell',
|
||||
lhs: 'haskell',
|
||||
ml: 'ocaml',
|
||||
mli: 'ocaml',
|
||||
clj: 'clojure',
|
||||
cljs: 'clojure',
|
||||
fs: 'fsharp',
|
||||
fsx: 'fsharp',
|
||||
nim: 'nim',
|
||||
zig: 'zig',
|
||||
v: 'v',
|
||||
sol: 'solidity',
|
||||
|
||||
// Config files
|
||||
dockerfile: 'dockerfile',
|
||||
makefile: 'makefile',
|
||||
cmake: 'cmake',
|
||||
gradle: 'groovy',
|
||||
groovy: 'groovy',
|
||||
|
||||
// GraphQL
|
||||
graphql: 'graphql',
|
||||
gql: 'graphql',
|
||||
|
||||
// Protocol Buffers
|
||||
proto: 'protobuf',
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// LSP 支持的语言
|
||||
// ==========================================
|
||||
|
||||
export const LSP_SUPPORTED_LANGUAGES = [
|
||||
// 完全支持(内置 LSP)
|
||||
'typescript',
|
||||
'typescriptreact',
|
||||
'javascript',
|
||||
'javascriptreact',
|
||||
'html',
|
||||
'css',
|
||||
'scss',
|
||||
'less',
|
||||
'json',
|
||||
'jsonc',
|
||||
] as const
|
||||
|
||||
// 可扩展支持(需要额外 LSP 服务器)
|
||||
export const LSP_EXTENSIBLE_LANGUAGES = [
|
||||
'python', // pylsp / pyright
|
||||
'rust', // rust-analyzer
|
||||
'go', // gopls
|
||||
'java', // jdtls
|
||||
'csharp', // omnisharp
|
||||
] as const
|
||||
|
||||
// ==========================================
|
||||
// 忽略目录(完整列表)
|
||||
// ==========================================
|
||||
|
||||
export const IGNORED_DIRECTORIES = [
|
||||
// Node.js / JavaScript
|
||||
'node_modules',
|
||||
'.npm',
|
||||
'.yarn',
|
||||
'.pnpm-store',
|
||||
'bower_components',
|
||||
|
||||
// Build outputs
|
||||
'dist',
|
||||
'build',
|
||||
'out',
|
||||
'.next',
|
||||
'.nuxt',
|
||||
'.output',
|
||||
'.svelte-kit',
|
||||
'.parcel-cache',
|
||||
'.turbo',
|
||||
|
||||
// Caches
|
||||
'.cache',
|
||||
'__pycache__',
|
||||
'.pytest_cache',
|
||||
'.mypy_cache',
|
||||
'.ruff_cache',
|
||||
'.tox',
|
||||
|
||||
// Version control
|
||||
'.git',
|
||||
'.svn',
|
||||
'.hg',
|
||||
'.bzr',
|
||||
|
||||
// IDE / Editor
|
||||
'.vscode',
|
||||
'.idea',
|
||||
'.vs',
|
||||
'.fleet',
|
||||
|
||||
// Language-specific
|
||||
'vendor', // Go, PHP, Ruby
|
||||
'target', // Rust, Java (Maven)
|
||||
'.venv', // Python
|
||||
'venv', // Python
|
||||
'env', // Python
|
||||
'.virtualenv', // Python
|
||||
'__pypackages__', // Python (PDM)
|
||||
'.gradle', // Java (Gradle)
|
||||
'.maven', // Java (Maven)
|
||||
'Pods', // iOS (CocoaPods)
|
||||
'DerivedData', // iOS (Xcode)
|
||||
'.dart_tool', // Dart
|
||||
'.pub-cache', // Dart
|
||||
'zig-cache', // Zig
|
||||
'_build', // Elixir
|
||||
'deps', // Elixir
|
||||
|
||||
// Coverage / Testing
|
||||
'coverage',
|
||||
'.nyc_output',
|
||||
'htmlcov',
|
||||
'.coverage',
|
||||
|
||||
// Misc
|
||||
'tmp',
|
||||
'temp',
|
||||
'logs',
|
||||
'.DS_Store',
|
||||
'Thumbs.db',
|
||||
] as const
|
||||
|
||||
// ==========================================
|
||||
// FIM (Fill-in-the-Middle) 支持的模型
|
||||
// ==========================================
|
||||
|
||||
export const FIM_CAPABLE_MODELS = [
|
||||
'deepseek-coder',
|
||||
'deepseek-coder-v2',
|
||||
'codellama',
|
||||
'code-llama',
|
||||
'starcoder',
|
||||
'starcoder2',
|
||||
'qwen-coder',
|
||||
'qwen2.5-coder',
|
||||
'yi-coder',
|
||||
'codestral',
|
||||
'codegemma',
|
||||
] as const
|
||||
|
||||
// ==========================================
|
||||
// 语言 ID -> LSP 语言 ID 映射 (用于 LSP 通信)
|
||||
// ==========================================
|
||||
|
||||
export const LANGUAGE_TO_LSP_ID: Record<string, string> = {
|
||||
typescript: 'typescript',
|
||||
typescriptreact: 'typescriptreact',
|
||||
javascript: 'javascript',
|
||||
javascriptreact: 'javascriptreact',
|
||||
html: 'html',
|
||||
css: 'css',
|
||||
scss: 'scss',
|
||||
less: 'less',
|
||||
json: 'json',
|
||||
jsonc: 'jsonc',
|
||||
python: 'python',
|
||||
rust: 'rust',
|
||||
go: 'go',
|
||||
java: 'java',
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 辅助函数
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* 根据文件路径获取语言 ID
|
||||
*/
|
||||
export function getLanguageFromPath(filePath: string): string {
|
||||
const ext = filePath.split('.').pop()?.toLowerCase() || ''
|
||||
return EXTENSION_TO_LANGUAGE[ext] || 'plaintext'
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查语言是否支持 LSP
|
||||
*/
|
||||
export function isLspSupported(languageId: string): boolean {
|
||||
return (LSP_SUPPORTED_LANGUAGES as readonly string[]).includes(languageId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查目录是否应被忽略
|
||||
*/
|
||||
export function shouldIgnoreDirectory(dirName: string): boolean {
|
||||
return IGNORED_DIRECTORIES.includes(dirName as any)
|
||||
}
|
||||
@@ -95,6 +95,10 @@ export default defineConfig({
|
||||
'state': ['zustand'],
|
||||
// UI 图标
|
||||
'icons': ['lucide-react'],
|
||||
// 终端相关 - 懒加载优化
|
||||
'terminal': ['@xterm/xterm', '@xterm/addon-fit', '@xterm/addon-webgl', '@xterm/addon-web-links'],
|
||||
// Markdown 渲染 - 懒加载优化
|
||||
'markdown': ['react-markdown', 'react-syntax-highlighter'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user