feishu-bridge 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +238 -0
- package/bin/feishu-bridge.js +5 -0
- package/dist/cli/index.d.mts +2 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +3324 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +3309 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/index.d.mts +114 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.js +2832 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2800 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/logger.ts","../../src/core/config.ts","../../src/core/daemon.ts","../../src/cli/index.ts","../../src/cli/config.ts","../../src/feishu/webhook.ts","../../src/feishu/websocket.ts","../../src/feishu/client.ts","../../src/commands/executor.ts","../../src/session/manager.ts","../../src/adapters/base.ts","../../src/adapters/vscode.ts","../../src/adapters/cursor.ts","../../src/adapters/trae.ts","../../src/adapters/antigravity.ts","../../src/adapters/kiro.ts","../../src/adapters/opencode.ts","../../src/adapters/claude-code.ts","../../src/core/bridge.ts","../../src/core/health.ts","../../src/core/reverse-channel.ts"],"sourcesContent":["/**\n * 日志系统\n */\nimport pino, { Logger as PinoLogger } from 'pino';\n\nexport class Logger {\n private logger: PinoLogger;\n\n constructor() {\n const isTest = process.env.NODE_ENV === 'test' || process.env.VITEST;\n \n this.logger = pino({\n level: process.env.LOG_LEVEL || 'info',\n transport: isTest ? undefined : {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n }\n }\n });\n }\n\n public setLevel(level: 'debug' | 'info' | 'warn' | 'error'): void {\n this.logger.level = level;\n }\n\n public debug(msg: string, ...args: any[]): void {\n this.logger.debug(msg, ...args);\n }\n\n public info(msg: string, ...args: any[]): void {\n this.logger.info(msg, ...args);\n }\n\n public warn(msg: string, ...args: any[]): void {\n this.logger.warn(msg, ...args);\n }\n\n public error(msg: string | Error, ...args: any[]): void {\n this.logger.error(msg, ...args);\n }\n\n public child(bindings: Record<string, any>): Logger {\n const childLogger = new Logger();\n childLogger.logger = this.logger.child(bindings);\n return childLogger;\n }\n}\n\n// 全局日志实例\nexport const logger = new Logger();","/**\n * 配置管理模块\n */\n\nexport interface BridgeConfig {\n // 飞书应用配置\n feishu: {\n appId: string;\n appSecret: string;\n domain: 'feishu' | 'lark'; // 国内/国际版\n connectionMode: 'websocket' | 'webhook';\n encryptKey?: string; // 消息加密密钥\n verificationToken?: string; // 验证Token\n };\n \n // 服务器配置\n server: {\n port: number;\n host: string;\n webhookPath: string;\n };\n \n // IDE适配器配置\n adapters: {\n vscode?: {\n enabled: boolean;\n executablePath?: string;\n };\n cursor?: {\n enabled: boolean;\n };\n trae?: {\n enabled: boolean;\n };\n antigravity?: {\n enabled: boolean;\n };\n kiro?: {\n enabled: boolean;\n };\n opencode?: {\n enabled: boolean;\n socketPath?: string;\n };\n 'claude-code'?: {\n enabled: boolean;\n };\n };\n \n // 行为配置\n behavior: {\n autoStart: boolean;\n maxOutputLength: number; // 最大输出长度\n sessionTimeout: number; // 会话超时时间(分钟)\n reverseChannelEnabled: boolean; // 反向通信通道启用\n reverseChannelMode: 'websocket' | 'filesystem' | 'http'; // 反向通信模式\n };\n \n // 日志配置\n logging: {\n level: 'debug' | 'info' | 'warn' | 'error';\n file?: string;\n };\n}\n\n// 默认配置\nexport const DEFAULT_CONFIG: BridgeConfig = {\n feishu: {\n appId: '',\n appSecret: '',\n domain: 'feishu',\n connectionMode: 'webhook',\n encryptKey: undefined,\n verificationToken: undefined,\n },\n server: {\n port: 3000,\n host: '0.0.0.0',\n webhookPath: '/webhook/feishu',\n },\n adapters: {\n vscode: { enabled: true },\n cursor: { enabled: true },\n trae: { enabled: true },\n antigravity: { enabled: true },\n kiro: { enabled: true },\n opencode: { enabled: true },\n 'claude-code': { enabled: true },\n },\n behavior: {\n autoStart: true,\n maxOutputLength: 2000,\n sessionTimeout: 30,\n reverseChannelEnabled: true,\n reverseChannelMode: 'filesystem',\n },\n logging: {\n level: 'info',\n file: undefined,\n },\n};\n\n// 配置管理器\nexport class ConfigManager {\n private static instance: ConfigManager;\n private config: BridgeConfig = DEFAULT_CONFIG;\n\n private constructor() {}\n\n public static getInstance(): ConfigManager {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n\n public load(config: Partial<BridgeConfig>): void {\n this.config = this.deepMerge(this.config, config);\n }\n\n private deepMerge(target: any, source: any): any {\n const output = { ...target };\n \n if (this.isObject(target) && this.isObject(source)) {\n Object.keys(source).forEach(key => {\n if (this.isObject(source[key])) {\n if (!(key in target)) {\n Object.assign(output, { [key]: source[key] });\n } else {\n output[key] = this.deepMerge(target[key], source[key]);\n }\n } else {\n Object.assign(output, { [key]: source[key] });\n }\n });\n }\n \n return output;\n }\n\n private isObject(item: any): boolean {\n return item && typeof item === 'object' && !Array.isArray(item);\n }\n\n public get(): BridgeConfig {\n return this.config;\n }\n\n public getFeishuConfig(): BridgeConfig['feishu'] {\n return this.config.feishu;\n }\n\n public getServerConfig(): BridgeConfig['server'] {\n return this.config.server;\n }\n\n public getAdapterConfig(adapter: keyof BridgeConfig['adapters']) {\n return this.config.adapters[adapter];\n }\n\n public getBehaviorConfig(): BridgeConfig['behavior'] {\n return this.config.behavior;\n }\n\n public getLoggingConfig(): BridgeConfig['logging'] {\n return this.config.logging;\n }\n}","/**\n * 进程守护模块\n * 确保Feishu Bridge进程持续运行,自动重启\n */\nimport { spawn, ChildProcess } from 'child_process';\nimport { Logger } from './logger';\nimport { ConfigManager } from './config';\n\ninterface DaemonConfig {\n maxRestarts: number;\n restartDelay: number;\n healthCheckInterval: number;\n}\n\nexport class ProcessDaemon {\n private process: ChildProcess | null = null;\n private restartCount = 0;\n private isRunning = false;\n private healthCheckTimer: NodeJS.Timeout | null = null;\n private logger: Logger;\n private config: DaemonConfig;\n\n constructor(\n private command: string,\n private args: string[] = [],\n private options: { cwd?: string; env?: NodeJS.ProcessEnv } = {}\n ) {\n this.logger = new Logger();\n \n // 从配置加载守护参数\n const daemonConfig = ConfigManager.getInstance().get().daemon;\n this.config = {\n maxRestarts: daemonConfig?.maxRestarts || 5,\n restartDelay: daemonConfig?.restartDelay || 5000,\n healthCheckInterval: daemonConfig?.healthCheckInterval || 30000\n };\n }\n\n /**\n * 启动守护进程\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n this.logger.warn('Daemon already running');\n return;\n }\n\n this.isRunning = true;\n this.restartCount = 0;\n \n this.logger.info('Starting process daemon...');\n await this.spawnProcess();\n this.startHealthCheck();\n }\n\n /**\n * 停止守护进程\n */\n async stop(): Promise<void> {\n this.isRunning = false;\n \n if (this.healthCheckTimer) {\n clearInterval(this.healthCheckTimer);\n this.healthCheckTimer = null;\n }\n\n if (this.process) {\n this.logger.info('Stopping daemon process...');\n \n // 尝试优雅关闭\n this.process.kill('SIGTERM');\n \n // 等待5秒后强制关闭\n await new Promise(resolve => setTimeout(resolve, 5000));\n \n if (this.process && !this.process.killed) {\n this.process.kill('SIGKILL');\n }\n \n this.process = null;\n }\n \n this.logger.info('Daemon stopped');\n }\n\n /**\n * 创建子进程\n */\n private async spawnProcess(): Promise<void> {\n return new Promise((resolve) => {\n this.logger.info(`Spawning: ${this.command} ${this.args.join(' ')}`);\n\n this.process = spawn(this.command, this.args, {\n stdio: 'pipe',\n detached: false,\n ...this.options\n });\n\n // 监听输出\n this.process.stdout?.on('data', (data) => {\n process.stdout.write(data);\n });\n\n this.process.stderr?.on('data', (data) => {\n process.stderr.write(data);\n });\n\n // 监听进程退出\n this.process.on('exit', (code, signal) => {\n this.logger.warn(`Process exited with code ${code}, signal ${signal}`);\n this.process = null;\n \n if (this.isRunning) {\n this.handleCrash();\n }\n });\n\n // 监听错误\n this.process.on('error', (error) => {\n this.logger.error('Process error:', error);\n this.process = null;\n \n if (this.isRunning) {\n this.handleCrash();\n }\n });\n\n // 给进程一些启动时间\n setTimeout(() => {\n if (this.process && !this.process.killed) {\n this.logger.info('Process started successfully');\n this.restartCount = 0; // 重置重启计数\n }\n resolve();\n }, 2000);\n });\n }\n\n /**\n * 处理进程崩溃\n */\n private handleCrash(): void {\n if (!this.isRunning) return;\n\n this.restartCount++;\n\n if (this.restartCount > this.config.maxRestarts) {\n this.logger.error(`Max restarts (${this.config.maxRestarts}) reached. Giving up.`);\n this.isRunning = false;\n process.exit(1);\n }\n\n this.logger.info(`Restarting process (attempt ${this.restartCount}/${this.config.maxRestarts})...`);\n \n setTimeout(() => {\n if (this.isRunning) {\n this.spawnProcess();\n }\n }, this.config.restartDelay);\n }\n\n /**\n * 启动健康检查\n */\n private startHealthCheck(): void {\n this.healthCheckTimer = setInterval(() => {\n if (!this.isRunning) return;\n\n // 检查进程是否还在运行\n if (!this.process || this.process.killed) {\n this.logger.warn('Health check: Process not running, restarting...');\n this.handleCrash();\n }\n }, this.config.healthCheckInterval);\n }\n\n /**\n * 获取守护状态\n */\n getStatus(): {\n isRunning: boolean;\n pid: number | null;\n restartCount: number;\n uptime: number;\n } {\n return {\n isRunning: this.isRunning,\n pid: this.process?.pid || null,\n restartCount: this.restartCount,\n uptime: process.uptime()\n };\n }\n}\n\n/**\n * 单例守护进程管理器\n */\nclass DaemonManager {\n private static instance: DaemonManager;\n private daemon: ProcessDaemon | null = null;\n\n private constructor() {}\n\n static getInstance(): DaemonManager {\n if (!DaemonManager.instance) {\n DaemonManager.instance = new DaemonManager();\n }\n return DaemonManager.instance;\n }\n\n /**\n * 启动守护进程\n */\n async start(args: string[] = []): Promise<void> {\n if (this.daemon) {\n console.log('Daemon already running');\n return;\n }\n\n // 使用node运行主程序\n const nodePath = process.execPath;\n const scriptPath = require.resolve('../index.js');\n\n this.daemon = new ProcessDaemon(nodePath, [scriptPath, ...args], {\n cwd: process.cwd(),\n env: process.env\n });\n\n await this.daemon.start();\n\n // 处理退出信号\n process.on('SIGINT', () => this.stop());\n process.on('SIGTERM', () => this.stop());\n }\n\n /**\n * 停止守护进程\n */\n async stop(): Promise<void> {\n if (this.daemon) {\n await this.daemon.stop();\n this.daemon = null;\n }\n }\n\n /**\n * 获取状态\n */\n getStatus(): {\n isRunning: boolean;\n pid: number | null;\n restartCount: number;\n uptime: number;\n } | null {\n return this.daemon?.getStatus() || null;\n }\n}\n\nexport { DaemonManager };\nexport default DaemonManager;\n","/**\n * CLI主入口\n */\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { getConfigValue, setConfigValue, deleteConfigValue, listConfig, getConfigFilePath } from './config';\nimport { FeishuBridge } from '../core/bridge';\nimport { ConfigManager, DEFAULT_CONFIG } from '../core/config';\nimport { logger } from '../core/logger';\n\nconst program = new Command();\nconst pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));\n\nprogram\n .name('feishu-bridge')\n .description('Feishu Bridge - AI IDE/CLI integration for Feishu')\n .version(pkg.version);\n\n// Start命令\nprogram\n .command('start')\n .description('Start the Feishu Bridge server')\n .option('-p, --port <port>', 'Server port', '3000')\n .option('-h, --host <host>', 'Server host', '0.0.0.0')\n .option('-d, --daemon', 'Run in daemon mode')\n .action(async (options) => {\n try {\n // 加载配置文件\n const fileConfig = getConfigValue('feishu') || {};\n \n // 初始化配置\n const configManager = ConfigManager.getInstance();\n const config = { ...DEFAULT_CONFIG };\n \n // 应用配置文件中的设置\n if (fileConfig.appId) config.feishu.appId = fileConfig.appId;\n if (fileConfig.appSecret) config.feishu.appSecret = fileConfig.appSecret;\n if (fileConfig.encryptKey) config.feishu.encryptKey = fileConfig.encryptKey;\n if (fileConfig.verificationToken) config.feishu.verificationToken = fileConfig.verificationToken;\n if (fileConfig.domain) config.feishu.domain = fileConfig.domain;\n \n // 命令行选项覆盖配置文件\n config.server.port = parseInt(options.port);\n config.server.host = options.host;\n \n // 环境变量优先级最高\n if (process.env.FEISHU_APP_ID) config.feishu.appId = process.env.FEISHU_APP_ID;\n if (process.env.FEISHU_APP_SECRET) config.feishu.appSecret = process.env.FEISHU_APP_SECRET;\n if (process.env.FEISHU_ENCRYPT_KEY) config.feishu.encryptKey = process.env.FEISHU_ENCRYPT_KEY;\n if (process.env.FEISHU_VERIFICATION_TOKEN) config.feishu.verificationToken = process.env.FEISHU_VERIFICATION_TOKEN;\n if (process.env.SERVER_PORT) config.server.port = parseInt(process.env.SERVER_PORT);\n if (process.env.SERVER_HOST) config.server.host = process.env.SERVER_HOST;\n \n // 验证必需配置\n if (!config.feishu.appId || !config.feishu.appSecret) {\n console.error('Error: FEISHU_APP_ID and FEISHU_APP_SECRET are required');\n console.error('Set them via:');\n console.error(' 1. Environment variables: export FEISHU_APP_ID=xxx');\n console.error(' 2. Config file: feishu-bridge config set feishu.appId xxx');\n process.exit(1);\n }\n \n configManager.load(config);\n \n // 创建并启动桥接器\n const bridge = new FeishuBridge();\n await bridge.start();\n \n if (options.daemon) {\n logger.info('Feishu Bridge started in daemon mode');\n } else {\n logger.info('Press Ctrl+C to stop the server');\n }\n \n // 处理退出信号\n process.on('SIGINT', async () => {\n logger.info('Received SIGINT, shutting down gracefully...');\n await bridge.stop();\n process.exit(0);\n });\n \n process.on('SIGTERM', async () => {\n logger.info('Received SIGTERM, shutting down gracefully...');\n await bridge.stop();\n process.exit(0);\n });\n \n } catch (error) {\n console.error('Failed to start Feishu Bridge:', error);\n process.exit(1);\n }\n });\n\n// Config命令组\nconst configCmd = program\n .command('config')\n .description('Manage configuration');\n\nconfigCmd\n .command('set <key> <value>')\n .description('Set a configuration value')\n .action((key: string, value: string) => {\n try {\n setConfigValue(key, value);\n console.log(`✅ Set ${key} = ${value}`);\n console.log(`📁 Config file: ${getConfigFilePath()}`);\n } catch (error) {\n console.error('❌ Error setting config:', error);\n process.exit(1);\n }\n });\n\nconfigCmd\n .command('get <key>')\n .description('Get a configuration value')\n .action((key: string) => {\n const value = getConfigValue(key);\n if (value === undefined) {\n console.log(`⚠️ ${key} is not set`);\n } else {\n console.log(`${key} = ${JSON.stringify(value)}`);\n }\n });\n\nconfigCmd\n .command('delete <key>')\n .description('Delete a configuration value')\n .action((key: string) => {\n try {\n deleteConfigValue(key);\n console.log(`✅ Deleted ${key}`);\n } catch (error) {\n console.error('❌ Error deleting config:', error);\n process.exit(1);\n }\n });\n\nconfigCmd\n .command('list')\n .description('List all configuration values')\n .action(() => {\n const config = listConfig();\n if (Object.keys(config).length === 0) {\n console.log('No configuration set');\n console.log(`📁 Config file: ${getConfigFilePath()}`);\n } else {\n console.log('Current configuration:');\n console.log(JSON.stringify(config, null, 2));\n console.log(`\\n📁 Config file: ${getConfigFilePath()}`);\n }\n });\n\n// Daemon命令组\nconst daemonCmd = program\n .command('daemon')\n .description('Manage daemon process');\n\ndaemonCmd\n .command('start')\n .description('Start the daemon')\n .action(async () => {\n try {\n const { DaemonManager } = await import('../core/daemon');\n const daemon = DaemonManager.getInstance();\n await daemon.start();\n console.log('✅ Daemon started');\n console.log('📊 Use \"feishu-bridge status\" to check status');\n } catch (error) {\n console.error('❌ Failed to start daemon:', error);\n process.exit(1);\n }\n });\n\ndaemonCmd\n .command('stop')\n .description('Stop the daemon')\n .action(async () => {\n try {\n const { DaemonManager } = await import('../core/daemon');\n const daemon = DaemonManager.getInstance();\n await daemon.stop();\n console.log('✅ Daemon stopped');\n } catch (error) {\n console.error('❌ Failed to stop daemon:', error);\n process.exit(1);\n }\n });\n\ndaemonCmd\n .command('restart')\n .description('Restart the daemon')\n .action(async () => {\n try {\n const { DaemonManager } = await import('../core/daemon');\n const daemon = DaemonManager.getInstance();\n await daemon.stop();\n await daemon.start();\n console.log('✅ Daemon restarted');\n } catch (error) {\n console.error('❌ Failed to restart daemon:', error);\n process.exit(1);\n }\n });\n\n// Status命令\nprogram\n .command('status')\n .description('Show service status')\n .action(async () => {\n try {\n const { DaemonManager } = await import('../core/daemon');\n const daemon = DaemonManager.getInstance();\n const status = daemon.getStatus();\n \n if (status) {\n console.log('📊 Daemon Status:');\n console.log(` Running: ${status.isRunning ? '✅ Yes' : '❌ No'}`);\n console.log(` PID: ${status.pid || 'N/A'}`);\n console.log(` Restarts: ${status.restartCount}`);\n console.log(` Uptime: ${Math.floor(status.uptime)}s`);\n } else {\n console.log('📊 Service Status:');\n console.log(' Daemon: Not running');\n }\n \n // 检查配置文件\n const config = listConfig();\n console.log('\\n📁 Configuration:');\n console.log(` Config file: ${getConfigFilePath()}`);\n console.log(` Feishu App ID: ${config.feishu?.appId ? '✅ Set' : '❌ Not set'}`);\n console.log(` Feishu App Secret: ${config.feishu?.appSecret ? '✅ Set' : '❌ Not set'}`);\n } catch (error) {\n console.error('❌ Error checking status:', error);\n }\n });\n\n// Shell init命令\nprogram\n .command('shell-init')\n .description('Output shell initialization script')\n .action(() => {\n console.log(`\n# Feishu Bridge Shell Integration\n# Add this to your ~/.bashrc, ~/.zshrc, or equivalent\n\nfeishu-bridge-auto() {\n # 检测当前是否在IDE/CLI环境中\n if [ -n \"$VSCODE_PID\" ] || [ -n \"$CURSOR_SHELL\" ] || [ -n \"$OPENCODE_SESSION\" ]; then\n # 检查bridge是否已运行\n if ! pgrep -f \"feishu-bridge\" > /dev/null; then\n echo \"Auto-starting Feishu Bridge...\"\n feishu-bridge start --daemon 2>/dev/null &\n fi\n fi\n}\n\n# Bash\nif [ -n \"$BASH_VERSION\" ]; then\n PROMPT_COMMAND=\"feishu-bridge-auto; $PROMPT_COMMAND\"\nfi\n\n# Zsh\nif [ -n \"$ZSH_VERSION\" ]; then\n precmd_functions+=(feishu-bridge-auto)\nfi\n`);\n });\n\n// 解析命令行参数\nprogram.parse();\n\n// 如果没有提供命令,显示帮助\nif (!process.argv.slice(2).length) {\n program.outputHelp();\n}\n","/**\n * CLI配置管理模块\n * 使用cosmiconfig管理配置文件\n */\nimport { cosmiconfigSync } from 'cosmiconfig';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\nconst moduleName = 'feishu-bridge';\n\n// 配置文件搜索路径\nconst explorer = cosmiconfigSync(moduleName, {\n searchPlaces: [\n 'package.json',\n `.${moduleName}rc`,\n `.${moduleName}rc.json`,\n `.${moduleName}rc.yaml`,\n `.${moduleName}rc.yml`,\n `.${moduleName}rc.js`,\n `.${moduleName}rc.cjs`,\n `${moduleName}.config.js`,\n `${moduleName}.config.cjs`,\n ],\n});\n\n// 默认配置文件路径\nfunction getDefaultConfigPath(): string {\n const configDir = path.join(os.homedir(), '.config', moduleName);\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir, { recursive: true });\n }\n return path.join(configDir, 'config.json');\n}\n\n/**\n * 获取当前配置\n */\nexport function getConfig(): Record<string, any> {\n // 首先尝试从当前目录向上搜索\n const result = explorer.search();\n if (result?.config) {\n return result.config;\n }\n \n // 如果没有找到,尝试从用户主目录加载\n const homeConfigPath = getDefaultConfigPath();\n if (fs.existsSync(homeConfigPath)) {\n try {\n const content = fs.readFileSync(homeConfigPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n console.error('Error reading home config file:', error);\n }\n }\n \n return {};\n}\n\n/**\n * 获取特定配置项\n */\nexport function getConfigValue(key: string): any {\n const config = getConfig();\n const keys = key.split('.');\n let value = config;\n \n for (const k of keys) {\n if (value === undefined || value === null) {\n return undefined;\n }\n value = value[k];\n }\n \n return value;\n}\n\n/**\n * 设置配置项\n */\nexport function setConfigValue(key: string, value: any): void {\n const configPath = getDefaultConfigPath();\n let config: Record<string, any> = {};\n \n // 读取现有配置\n if (fs.existsSync(configPath)) {\n try {\n const content = fs.readFileSync(configPath, 'utf-8');\n config = JSON.parse(content);\n } catch (error) {\n console.error('Error reading config file:', error);\n }\n }\n \n // 设置嵌套值\n const keys = key.split('.');\n let current = config;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n if (!(k in current) || typeof current[k] !== 'object') {\n current[k] = {};\n }\n current = current[k];\n }\n \n // 转换值类型\n const finalKey = keys[keys.length - 1];\n current[finalKey] = convertValueType(value);\n \n // 写入配置文件\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\n/**\n * 删除配置项\n */\nexport function deleteConfigValue(key: string): void {\n const configPath = getDefaultConfigPath();\n \n if (!fs.existsSync(configPath)) {\n return;\n }\n \n let config: Record<string, any> = {};\n try {\n const content = fs.readFileSync(configPath, 'utf-8');\n config = JSON.parse(content);\n } catch (error) {\n console.error('Error reading config file:', error);\n return;\n }\n \n const keys = key.split('.');\n let current = config;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n if (!(k in current)) {\n return; // 键不存在,无需删除\n }\n current = current[k];\n }\n \n delete current[keys[keys.length - 1]];\n \n fs.writeFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\n/**\n * 列出所有配置\n */\nexport function listConfig(): Record<string, any> {\n return getConfig();\n}\n\n/**\n * 转换值类型(自动识别数字、布尔值)\n */\nfunction convertValueType(value: string): any {\n // 尝试转换为数字\n if (!isNaN(Number(value)) && value.trim() !== '') {\n return Number(value);\n }\n \n // 尝试转换为布尔值\n if (value.toLowerCase() === 'true') {\n return true;\n }\n if (value.toLowerCase() === 'false') {\n return false;\n }\n \n // 尝试解析JSON\n try {\n return JSON.parse(value);\n } catch {\n // 不是有效的JSON,返回字符串\n return value;\n }\n}\n\n/**\n * 获取配置文件路径\n */\nexport function getConfigFilePath(): string {\n const result = explorer.search();\n if (result?.filepath) {\n return result.filepath;\n }\n return getDefaultConfigPath();\n}\n","/**\n * Webhook处理器\n */\nimport { FastifyRequest, FastifyReply } from 'fastify';\nimport * as crypto from 'crypto';\nimport { FeishuClient } from './client';\nimport { CommandExecutor } from '../commands/executor';\nimport { LarkEvent, LarkMessage } from './types';\nimport { Logger } from '../core/logger';\nimport { ConfigManager } from '../core/config';\n\nexport class FeishuWebhookHandler {\n private logger: Logger;\n\n constructor(\n private client: FeishuClient,\n private commandExecutor: CommandExecutor\n ) {\n this.logger = new Logger();\n }\n\n async handleWebhook(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n try {\n // 1. 验证请求签名\n const signature = request.headers['x-lark-signature'] as string;\n const timestamp = request.headers['x-lark-timestamp'] as string;\n const body = request.body as string;\n \n if (!this.verifySignature(signature, timestamp, body)) {\n this.logger.warn('Invalid signature received');\n reply.status(401).send({ error: 'Invalid signature' });\n return;\n }\n \n // 2. 解析事件\n const event = JSON.parse(body) as LarkEvent;\n \n // 3. 处理URL验证\n if (event.type === 'url_verification') {\n this.logger.info('Received URL verification challenge');\n reply.send({ challenge: event.challenge });\n return;\n }\n \n // 4. 处理消息事件\n if (event.type === 'event_callback' && event.event) {\n await this.handleEvent(event.event);\n }\n \n reply.send({ success: true });\n } catch (error) {\n this.logger.error('Error handling webhook:', error);\n reply.status(500).send({ error: 'Internal server error' });\n }\n }\n\n private verifySignature(signature: string, timestamp: string, body: string): boolean {\n // 如果没有配置加密密钥,跳过验证(仅用于开发环境)\n const config = ConfigManager.getInstance().getFeishuConfig();\n const encryptKey = config.encryptKey;\n \n if (!encryptKey) {\n this.logger.warn('No encrypt key configured, skipping signature verification (development mode)');\n return true;\n }\n \n // 验证时间戳,防止重放攻击(允许±5分钟的时间差)\n const now = Math.floor(Date.now() / 1000);\n const requestTime = parseInt(timestamp, 10);\n const timeDiff = Math.abs(now - requestTime);\n \n if (timeDiff > 300) { // 5 minutes = 300 seconds\n this.logger.warn(`Request timestamp too old: ${timeDiff}s difference`);\n return false;\n }\n \n try {\n // 飞书签名算法:HMAC-SHA256(timestamp + \"\\n\" + body, encryptKey)\n const signatureContent = `${timestamp}\\n${body}`;\n const computedSignature = crypto\n .createHmac('sha256', encryptKey)\n .update(signatureContent)\n .digest('base64');\n \n // 使用恒定时间比较防止时序攻击\n const expectedSig = Buffer.from(computedSignature);\n const receivedSig = Buffer.from(signature);\n \n if (expectedSig.length !== receivedSig.length) {\n return false;\n }\n \n return crypto.timingSafeEqual(expectedSig, receivedSig);\n } catch (error) {\n this.logger.error('Error verifying signature:', error);\n return false;\n }\n }\n \n private async handleEvent(event: any): Promise<void> {\n const { message } = event;\n \n // 忽略非文本消息\n if (message.message_type !== 'text') {\n this.logger.info('Ignoring non-text message');\n return;\n }\n \n const content = JSON.parse(message.content);\n const text = content.text.trim();\n const sender = event.sender.sender_id.open_id;\n \n this.logger.info(`Received message from ${sender}: ${text}`);\n \n // 提取目标IDE/CLI\n const target = this.extractTargetIDE(text);\n const command = this.extractCommand(text);\n \n // 执行命令\n const result = await this.commandExecutor.execute({\n target,\n command,\n sender,\n chatId: message.chat_id\n });\n \n // 回复结果\n const formattedResponse = this.formatResponse(result);\n await this.client.sendMessage(message.chat_id, {\n msg_type: 'text',\n content: {\n text: formattedResponse\n }\n });\n }\n \n private extractTargetIDE(text: string): string {\n // 解析 @vscode /generate xxx 或 @cursor /generate xxx 格式\n const match = text.match(/@(vscode|cursor|trae|antigravity|kiro|opencode|claude)/i);\n return match ? match[1].toLowerCase() : 'auto';\n }\n \n private extractCommand(text: string): string {\n // 移除目标IDE标识符,提取实际命令\n const cleanedText = text.replace(/@(vscode|cursor|trae|antigravity|kiro|opencode|claude)\\s*/i, '').trim();\n return cleanedText;\n }\n \n private formatResponse(result: any): string {\n if (result.success) {\n // 限制输出长度以符合飞书消息限制\n const output = typeof result.output === 'string' \n ? result.output.substring(0, 2000) \n : JSON.stringify(result.output).substring(0, 2000);\n \n return `✅ 执行成功\\n\\n${output}`;\n } else {\n const error = result.error || result.stderr || 'Unknown error';\n return `❌ 执行失败\\n\\n${error.substring(0, 2000)}`;\n }\n }\n}","/**\n * WebSocket处理器\n * 用于与飞书建立实时连接接收事件\n */\nimport { WebSocket } from 'ws';\nimport { FeishuClient } from './client';\nimport { CommandExecutor } from '../commands/executor';\nimport { LarkEvent } from './types';\nimport { Logger } from '../core/logger';\nimport { ConfigManager } from '../core/config';\n\nexport class FeishuWebSocketHandler {\n private ws: WebSocket | null = null;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private reconnectInterval = 5000; // 5秒\n private heartbeatInterval: NodeJS.Timeout | null = null;\n private logger: Logger;\n private isRunning = false;\n\n constructor(\n private client: FeishuClient,\n private commandExecutor: CommandExecutor\n ) {\n this.logger = new Logger();\n }\n\n /**\n * 启动WebSocket连接\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n this.logger.warn('WebSocket handler already running');\n return;\n }\n\n this.isRunning = true;\n this.reconnectAttempts = 0;\n await this.connect();\n }\n\n /**\n * 停止WebSocket连接\n */\n async stop(): Promise<void> {\n this.isRunning = false;\n \n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n\n this.logger.info('WebSocket handler stopped');\n }\n\n /**\n * 建立WebSocket连接\n */\n private async connect(): Promise<void> {\n try {\n const config = ConfigManager.getInstance().getFeishuConfig();\n \n // 飞书WebSocket URL\n const wsUrl = config.domain === 'feishu'\n ? 'wss://ws.feishu.cn/passport/'\n : 'wss://ws.larksuite.com/passport/';\n\n this.logger.info(`Connecting to WebSocket: ${wsUrl}`);\n\n this.ws = new WebSocket(wsUrl, {\n headers: {\n 'Authorization': `Bearer ${await this.getAccessToken()}`\n }\n });\n\n this.setupWebSocketHandlers();\n\n } catch (error) {\n this.logger.error('Failed to connect WebSocket:', error);\n this.handleReconnect();\n }\n }\n\n /**\n * 设置WebSocket事件处理器\n */\n private setupWebSocketHandlers(): void {\n if (!this.ws) return;\n\n this.ws.on('open', () => {\n this.logger.info('WebSocket connected');\n this.reconnectAttempts = 0;\n this.startHeartbeat();\n });\n\n this.ws.on('message', (data: WebSocket.Data) => {\n this.handleMessage(data.toString());\n });\n\n this.ws.on('close', (code: number, reason: Buffer) => {\n this.logger.info(`WebSocket closed: ${code} - ${reason.toString()}`);\n this.stopHeartbeat();\n \n if (this.isRunning) {\n this.handleReconnect();\n }\n });\n\n this.ws.on('error', (error: Error) => {\n this.logger.error('WebSocket error:', error);\n });\n\n this.ws.on('ping', () => {\n this.ws?.pong();\n });\n }\n\n /**\n * 处理收到的消息\n */\n private async handleMessage(data: string): Promise<void> {\n try {\n const event = JSON.parse(data) as LarkEvent;\n this.logger.debug('Received WebSocket message:', event);\n\n // 处理URL验证\n if (event.type === 'url_verification') {\n this.logger.info('Received URL verification challenge via WebSocket');\n return;\n }\n\n // 处理消息事件\n if (event.type === 'event_callback' && event.event) {\n await this.handleEvent(event.event);\n }\n\n } catch (error) {\n this.logger.error('Error handling WebSocket message:', error);\n }\n }\n\n /**\n * 处理事件\n */\n private async handleEvent(event: any): Promise<void> {\n const { message } = event;\n\n // 忽略非文本消息\n if (!message || message.message_type !== 'text') {\n this.logger.debug('Ignoring non-text message');\n return;\n }\n\n try {\n const content = JSON.parse(message.content);\n const text = content.text.trim();\n const sender = event.sender?.sender_id?.open_id;\n\n if (!sender) {\n this.logger.warn('Missing sender ID');\n return;\n }\n\n this.logger.info(`Received message from ${sender}: ${text}`);\n\n // 提取目标IDE/CLI和命令\n const target = this.extractTargetIDE(text);\n const command = this.extractCommand(text);\n\n // 执行命令\n const result = await this.commandExecutor.execute({\n target,\n command,\n sender,\n chatId: message.chat_id\n });\n\n // 回复结果\n await this.client.sendMessage(message.chat_id, {\n msg_type: 'text',\n content: {\n text: this.formatResponse(result)\n }\n });\n\n } catch (error) {\n this.logger.error('Error processing event:', error);\n }\n }\n\n /**\n * 启动心跳保活\n */\n private startHeartbeat(): void {\n // 每30秒发送一次ping\n this.heartbeatInterval = setInterval(() => {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.ping();\n }\n }, 30000);\n }\n\n /**\n * 停止心跳\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * 处理重连\n */\n private handleReconnect(): void {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.logger.error(`Max reconnection attempts (${this.maxReconnectAttempts}) reached`);\n return;\n }\n\n this.reconnectAttempts++;\n const delay = this.reconnectInterval * this.reconnectAttempts;\n \n this.logger.info(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`);\n\n setTimeout(() => {\n if (this.isRunning) {\n this.connect();\n }\n }, delay);\n }\n\n /**\n * 获取访问令牌\n */\n private async getAccessToken(): Promise<string> {\n // 这里需要实现获取tenant_access_token的逻辑\n // 简化版本:通过FeishuClient获取\n const config = ConfigManager.getInstance().getFeishuConfig();\n \n const response = await fetch(\n `https://open.${config.domain === 'lark' ? 'larksuite' : 'feishu'}.cn/open-apis/auth/v3/tenant_access_token/internal`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n app_id: config.appId,\n app_secret: config.appSecret\n })\n }\n );\n\n const data = await response.json() as any;\n \n if (data.code !== 0) {\n throw new Error(`Failed to get access token: ${data.msg}`);\n }\n\n return data.tenant_access_token;\n }\n\n /**\n * 提取目标IDE\n */\n private extractTargetIDE(text: string): string {\n const match = text.match(/@(vscode|cursor|trae|antigravity|kiro|opencode|claude)/i);\n return match ? match[1].toLowerCase() : 'auto';\n }\n\n /**\n * 提取命令\n */\n private extractCommand(text: string): string {\n return text.replace(/@(vscode|cursor|trae|antigravity|kiro|opencode|claude)\\s*/i, '').trim();\n }\n\n /**\n * 格式化响应\n */\n private formatResponse(result: any): string {\n if (result.success) {\n const output = typeof result.output === 'string'\n ? result.output.substring(0, 2000)\n : JSON.stringify(result.output).substring(0, 2000);\n return `✅ 执行成功\\n\\n${output}`;\n } else {\n const error = result.error || result.stderr || 'Unknown error';\n return `❌ 执行失败\\n\\n${error.substring(0, 2000)}`;\n }\n }\n}\n","/**\n * 飞书API客户端\n */\nimport { Logger } from '../core/logger';\nimport { LarkApiResponse, SendMessageRequest, SendMessageResponse } from './types';\n\nexport interface FeishuConfig {\n appId: string;\n appSecret: string;\n domain: 'feishu' | 'lark';\n}\n\nexport class FeishuClient {\n private appId: string;\n private appSecret: string;\n private domain: 'feishu' | 'lark';\n private baseUrl: string;\n private accessToken: string | null = null;\n private tokenExpireTime: number = 0;\n private logger: Logger;\n\n constructor(config: FeishuConfig) {\n this.appId = config.appId;\n this.appSecret = config.appSecret;\n this.domain = config.domain;\n this.baseUrl = this.domain === 'feishu' \n ? 'https://open.feishu.cn/open-apis'\n : 'https://open.larksuite.com/open-apis';\n this.logger = new Logger();\n }\n\n /**\n * 获取访问令牌\n */\n private async getAccessToken(): Promise<string> {\n const now = Date.now();\n \n // 如果令牌未过期,直接返回\n if (this.accessToken && now < this.tokenExpireTime) {\n return this.accessToken;\n }\n\n try {\n const response = await fetch(`${this.baseUrl}/auth/v3/tenant_access_token/internal`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=utf-8',\n },\n body: JSON.stringify({\n app_id: this.appId,\n app_secret: this.appSecret,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get access token: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json() as LarkApiResponse<{\n tenant_access_token: string;\n expire: number;\n }>;\n\n if (data.code !== 0) {\n throw new Error(`Failed to get access token: ${data.msg}`);\n }\n\n this.accessToken = data.data.tenant_access_token;\n this.tokenExpireTime = now + (data.data.expire - 300) * 1000; // 提前5分钟刷新\n\n this.logger.info('Access token refreshed successfully');\n return this.accessToken;\n } catch (error) {\n this.logger.error('Error getting access token:', error);\n throw error;\n }\n }\n\n /**\n * 发送消息到指定聊天\n */\n async sendMessage(chatId: string, message: SendMessageRequest): Promise<SendMessageResponse> {\n try {\n const token = await this.getAccessToken();\n \n const response = await fetch(`${this.baseUrl}/im/v1/messages?receive_id_type=chat_id`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json; charset=utf-8',\n },\n body: JSON.stringify({\n receive_id: chatId,\n ...message,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send message: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json() as LarkApiResponse<SendMessageResponse>;\n\n if (data.code !== 0) {\n throw new Error(`Failed to send message: ${data.msg}`);\n }\n\n this.logger.info(`Message sent successfully to chat ${chatId}`);\n return data.data;\n } catch (error) {\n this.logger.error('Error sending message:', error);\n throw error;\n }\n }\n\n /**\n * 获取用户信息\n */\n async getUserInfo(userId: string): Promise<any> {\n try {\n const token = await this.getAccessToken();\n \n const response = await fetch(`${this.baseUrl}/contact/v3/users/${userId}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json; charset=utf-8',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get user info: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json() as LarkApiResponse<any>;\n\n if (data.code !== 0) {\n throw new Error(`Failed to get user info: ${data.msg}`);\n }\n\n return data.data;\n } catch (error) {\n this.logger.error('Error getting user info:', error);\n throw error;\n }\n }\n}","/**\n * 命令执行器\n */\nimport { SessionManager } from '../session/manager';\nimport { BaseIDEAdapter } from '../adapters/base';\nimport { Logger } from '../core/logger';\n\nexport interface CommandExecutionRequest {\n target: string;\n command: string;\n sender: string;\n chatId: string;\n}\n\nexport interface CommandExecutionResult {\n success: boolean;\n output: string;\n error?: string;\n}\n\nexport class CommandExecutor {\n private logger: Logger;\n\n constructor(\n private adapters: Map<string, BaseIDEAdapter>,\n private sessionManager: SessionManager\n ) {\n this.logger = new Logger();\n }\n\n async execute(request: CommandExecutionRequest): Promise<CommandExecutionResult> {\n try {\n this.logger.info(`Executing command for target: ${request.target}, command: ${request.command}`);\n\n // 获取会话上下文\n const session = this.sessionManager.getSession(request.sender);\n \n // 确定要使用的适配器\n let adapterName = request.target.toLowerCase();\n if (adapterName === 'auto') {\n adapterName = this.detectBestAdapter();\n }\n \n // 获取对应的适配器\n const adapter = this.adapters.get(adapterName);\n if (!adapter) {\n throw new Error(`Adapter not found for target: ${adapterName}`);\n }\n \n // 检查适配器是否可用\n if (!await adapter.checkAvailability()) {\n throw new Error(`Adapter ${adapterName} is not available`);\n }\n \n // 准备执行上下文\n const executionContext = {\n workspaceRoot: session?.workspaceRoot,\n chatId: request.chatId,\n senderId: request.sender\n };\n \n // 根据命令类型执行相应操作\n let result: string;\n \n if (this.isGenerateCommand(request.command)) {\n // 代码生成命令\n const description = this.extractDescription(request.command);\n result = await adapter.generateCode(description);\n } else if (this.isRunCommand(request.command)) {\n // 运行命令\n const command = this.extractRunCommand(request.command);\n const executionResult = await adapter.runProgram(command, executionContext.workspaceRoot);\n result = executionResult.stdout || executionResult.stderr;\n } else {\n // 通用命令\n result = await adapter.sendCommand(request.command, executionContext);\n }\n \n // 更新会话\n this.sessionManager.updateSession(request.sender, {\n lastCommand: request.command,\n lastResult: result,\n lastUsedAdapter: adapterName\n });\n \n return {\n success: true,\n output: result\n };\n } catch (error) {\n this.logger.error('Error executing command:', error);\n \n return {\n success: false,\n output: '',\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n private detectBestAdapter(): string {\n // 简单的适配器检测逻辑\n // 在实际实现中,可以更智能地检测当前环境\n for (const [name, adapter] of this.adapters) {\n if (adapter.isAvailable) {\n return name;\n }\n }\n \n // 如果没有可用的适配器,则默认返回vscode\n return 'vscode';\n }\n\n private isGenerateCommand(command: string): boolean {\n return /\\b(generate|create|make|build|implement|write|develop|add|new)\\b/i.test(command);\n }\n\n private isRunCommand(command: string): boolean {\n return /\\b(run|execute|start|launch|test|debug|build)\\b/i.test(command);\n }\n\n private extractDescription(command: string): string {\n // 提取生成命令的描述部分\n const match = command.match(/\\b(generate|create|make|build|implement|write|develop|add|new)\\b\\s+(.*)/i);\n return match ? match[2] : command;\n }\n\n private extractRunCommand(command: string): string {\n // 提取运行命令的部分\n const match = command.match(/\\b(run|execute|start|launch|test|debug|build)\\b\\s+(.*)/i);\n return match ? match[2] : command;\n }\n}","/**\n * 会话管理器\n */\nimport { Logger } from '../core/logger';\n\nexport interface SessionData {\n userId: string;\n createdAt: number;\n lastActive: number;\n workspaceRoot?: string;\n context?: any;\n lastCommand?: string;\n lastResult?: string;\n lastUsedAdapter?: string;\n}\n\nexport interface SessionUpdate {\n workspaceRoot?: string;\n context?: any;\n lastCommand?: string;\n lastResult?: string;\n lastUsedAdapter?: string;\n}\n\nexport class SessionManager {\n private sessions: Map<string, SessionData> = new Map();\n private logger: Logger;\n private sessionTimeout: number; // 会话超时时间(毫秒)\n\n constructor(sessionTimeoutMinutes: number = 30) {\n this.logger = new Logger();\n this.sessionTimeout = sessionTimeoutMinutes * 60 * 1000; // 转换为毫秒\n \n // 定期清理过期会话\n setInterval(() => {\n this.cleanupExpiredSessions();\n }, this.sessionTimeout);\n }\n\n /**\n * 获取会话,如果不存在则创建新会话\n */\n getSession(userId: string): SessionData | null {\n const session = this.sessions.get(userId);\n \n if (session) {\n // 检查会话是否过期\n if (Date.now() - session.lastActive > this.sessionTimeout) {\n this.logger.info(`Session for user ${userId} expired, removing`);\n this.sessions.delete(userId);\n return null;\n }\n \n // 更新最后活跃时间\n session.lastActive = Date.now();\n return session;\n }\n \n return null;\n }\n\n /**\n * 创建新会话\n */\n createSession(userId: string, initialData?: Partial<SessionData>): SessionData {\n const now = Date.now();\n const session: SessionData = {\n userId,\n createdAt: now,\n lastActive: now,\n workspaceRoot: initialData?.workspaceRoot,\n context: initialData?.context,\n lastCommand: initialData?.lastCommand,\n lastResult: initialData?.lastResult,\n lastUsedAdapter: initialData?.lastUsedAdapter\n };\n\n this.sessions.set(userId, session);\n this.logger.info(`Created new session for user ${userId}`);\n \n return session;\n }\n\n /**\n * 更新会话数据\n */\n updateSession(userId: string, update: SessionUpdate): SessionData | null {\n let session = this.sessions.get(userId);\n \n if (!session) {\n // 如果会话不存在,创建一个新会话\n session = this.createSession(userId);\n }\n \n // 更新会话数据\n session.lastActive = Date.now();\n if (update.workspaceRoot !== undefined) session.workspaceRoot = update.workspaceRoot;\n if (update.context !== undefined) session.context = { ...session.context, ...update.context };\n if (update.lastCommand !== undefined) session.lastCommand = update.lastCommand;\n if (update.lastResult !== undefined) session.lastResult = update.lastResult;\n if (update.lastUsedAdapter !== undefined) session.lastUsedAdapter = update.lastUsedAdapter;\n\n this.sessions.set(userId, session);\n this.logger.debug(`Updated session for user ${userId}`);\n \n return session;\n }\n\n /**\n * 删除会话\n */\n removeSession(userId: string): boolean {\n const removed = this.sessions.delete(userId);\n if (removed) {\n this.logger.info(`Removed session for user ${userId}`);\n }\n return removed;\n }\n\n /**\n * 清理会话数据\n */\n clearAllSessions(): void {\n const count = this.sessions.size;\n this.sessions.clear();\n this.logger.info(`Cleared all ${count} sessions`);\n }\n\n /**\n * 获取所有活跃会话数量\n */\n getActiveSessionCount(): number {\n return this.sessions.size;\n }\n\n /**\n * 清理过期会话\n */\n private cleanupExpiredSessions(): void {\n const now = Date.now();\n let expiredCount = 0;\n\n for (const [userId, session] of this.sessions) {\n if (now - session.lastActive > this.sessionTimeout) {\n this.sessions.delete(userId);\n expiredCount++;\n this.logger.info(`Cleaned up expired session for user ${userId}`);\n }\n }\n\n if (expiredCount > 0) {\n this.logger.info(`Cleaned up ${expiredCount} expired sessions`);\n }\n }\n}","/**\n * 适配器基类\n */\nimport { Logger } from '../core/logger';\nimport { ReverseChannel, ReverseMessage } from '../core/reverse-channel';\n\nexport interface ExecutionContext {\n workspaceRoot?: string;\n chatId?: string;\n senderId?: string;\n}\n\nexport interface CodeGenOptions {\n language?: string;\n framework?: string;\n style?: string;\n}\n\nexport interface ExecutionResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n success: boolean;\n output?: string;\n error?: string;\n}\n\nexport interface IIDEAdapter {\n readonly type: string;\n readonly isAvailable: boolean;\n \n // 检查IDE是否可用\n checkAvailability(): Promise<boolean>;\n \n // 发送命令到IDE\n sendCommand(command: string, context?: ExecutionContext): Promise<string>;\n \n // 获取AI助手响应\n getAIResponse(prompt: string, context?: ExecutionContext): Promise<string>;\n \n // 执行代码生成\n generateCode(description: string, options?: CodeGenOptions): Promise<string>;\n \n // 运行程序\n runProgram(command: string, cwd?: string): Promise<ExecutionResult>;\n}\n\nexport abstract class BaseIDEAdapter implements IIDEAdapter {\n protected logger: Logger;\n protected reverseChannel: ReverseChannel | null = null;\n\n constructor() {\n this.logger = new Logger().child({ adapter: this.type });\n }\n\n abstract readonly type: string;\n\n get isAvailable(): boolean {\n return this.checkAvailabilitySync();\n }\n\n /**\n * 设置反向通信通道\n * 允许适配器主动向飞书发送消息\n */\n setReverseChannel(channel: ReverseChannel): void {\n this.reverseChannel = channel;\n this.logger.info(`Reverse channel set for ${this.type} adapter`);\n }\n\n /**\n * 发送消息到飞书\n * 供子类调用以主动推送消息\n */\n protected async sendToFeishu(\n content: string,\n context?: ExecutionContext,\n type: ReverseMessage['type'] = 'message'\n ): Promise<boolean> {\n if (!this.reverseChannel) {\n this.logger.warn('Reverse channel not available, cannot send message to Feishu');\n return false;\n }\n\n if (!context?.chatId) {\n this.logger.warn('No chatId in context, cannot send message to Feishu');\n return false;\n }\n\n try {\n await this.reverseChannel.sendToFeishu({\n type,\n content,\n chatId: context.chatId,\n senderId: context.senderId,\n timestamp: Date.now()\n });\n return true;\n } catch (error) {\n this.logger.error('Error sending message to Feishu:', error);\n return false;\n }\n }\n\n /**\n * 发送文件系统消息(无需反向通道实例)\n * 通过写入文件的方式让Bridge代为发送\n */\n protected async sendFileSystemMessage(\n content: string,\n context?: ExecutionContext,\n type: ReverseMessage['type'] = 'message'\n ): Promise<void> {\n if (!this.reverseChannel) {\n this.logger.warn('Reverse channel not available for file system message');\n return;\n }\n\n await this.reverseChannel.sendFileSystemMessage(\n this.type,\n content,\n context?.chatId\n );\n }\n\n abstract checkAvailability(): Promise<boolean>;\n protected abstract checkAvailabilitySync(): boolean;\n abstract sendCommand(command: string, context?: ExecutionContext): Promise<string>;\n abstract getAIResponse(prompt: string, context?: ExecutionContext): Promise<string>;\n abstract generateCode(description: string, options?: CodeGenOptions): Promise<string>;\n abstract runProgram(command: string, cwd?: string): Promise<ExecutionResult>;\n\n protected buildCodePrompt(description: string, options?: CodeGenOptions): string {\n let prompt = description;\n \n if (options) {\n if (options.language) {\n prompt += `\\nLanguage: ${options.language}`;\n }\n if (options.framework) {\n prompt += `\\nFramework: ${options.framework}`;\n }\n if (options.style) {\n prompt += `\\nStyle: ${options.style}`;\n }\n }\n \n return prompt;\n }\n}","/**\n * VS Code 适配器\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport { execa } from 'execa';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\n\nexport class VSCodeAdapter extends BaseIDEAdapter {\n readonly type = 'vscode';\n private vscodePath: string | null = null;\n \n protected checkAvailabilitySync(): boolean {\n // 检查VS Code环境变量\n if (process.env.VSCODE_PID || process.env.VSCODE_CWD) {\n return true;\n }\n \n // 尝试查找VS Code可执行文件\n this.vscodePath = this.findVSCodeExecutable();\n return !!this.vscodePath;\n }\n \n private findVSCodeExecutable(): string | null {\n const platform = os.platform();\n const possiblePaths: string[] = [];\n \n if (platform === 'darwin') {\n // macOS\n possiblePaths.push(\n '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code',\n '/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code',\n '/usr/local/bin/code',\n path.join(os.homedir(), 'Applications/Visual Studio Code.app/Contents/Resources/app/bin/code')\n );\n } else if (platform === 'win32') {\n // Windows\n possiblePaths.push(\n path.join(process.env.LOCALAPPDATA || '', 'Programs/Microsoft VS Code/bin/code.cmd'),\n path.join(process.env.ProgramFiles || '', 'Microsoft VS Code/bin/code.cmd'),\n path.join(process.env.ProgramFiles || '', 'Microsoft VS Code/bin/code.exe'),\n 'C:\\\\Program Files\\\\Microsoft VS Code\\\\bin\\\\code.cmd'\n );\n } else {\n // Linux\n possiblePaths.push(\n '/usr/bin/code',\n '/usr/local/bin/code',\n '/usr/share/code/bin/code',\n path.join(os.homedir(), '.local/bin/code'),\n '/snap/bin/code'\n );\n }\n \n for (const vscodePath of possiblePaths) {\n if (fs.existsSync(vscodePath)) {\n return vscodePath;\n }\n }\n \n // 尝试使用which/where命令查找\n try {\n if (platform === 'win32') {\n const result = execa.sync('where', ['code'], { reject: false });\n if (result.stdout) {\n const lines = result.stdout.split('\\n').map(l => l.trim()).filter(l => l);\n if (lines.length > 0) return lines[0];\n }\n } else {\n const result = execa.sync('which', ['code'], { reject: false });\n if (result.stdout) {\n return result.stdout.trim();\n }\n }\n } catch {\n // 查找失败\n }\n \n return null;\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to VS Code: ${command}`);\n \n // 方法1: 尝试使用VS Code CLI (如果可用)\n if (this.vscodePath) {\n try {\n const result = await execa(this.vscodePath, [\n '--command', \n 'feishuBridge.execute',\n '--args', JSON.stringify({ command })\n ], {\n timeout: 30000,\n reject: false\n });\n \n if (!result.failed) {\n return result.stdout || 'Command executed successfully';\n }\n } catch (cliError) {\n this.logger.debug('VS Code CLI failed, trying file system method');\n }\n }\n \n // 方法2: 通过文件系统通信\n return await this.sendViaFileSystem(command, context);\n \n } catch (error) {\n this.logger.error(`Error executing VS Code command:`, error);\n throw new Error(`VS Code command failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n private async sendViaFileSystem(command: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'vscode');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `cmd_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'command',\n command,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n // 等待响应\n const maxWait = 30000;\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {}\n \n return `Command queued for VS Code. File: ${instructionFile}`;\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from VS Code for prompt: ${prompt}`);\n \n // 尝试使用VS Code CLI (如果可用)\n if (this.vscodePath) {\n try {\n const result = await execa(this.vscodePath, [\n '--command',\n 'github.copilot.generateCode',\n '--args', JSON.stringify({ prompt })\n ], {\n timeout: 60000,\n reject: false\n });\n \n if (!result.failed && result.stdout) {\n return result.stdout;\n }\n } catch (cliError) {\n this.logger.debug('VS Code AI CLI failed, using file system');\n }\n }\n \n // 文件系统方式\n return await this.sendAIRequestViaFileSystem(prompt, context);\n \n } catch (error) {\n this.logger.error(`Error getting VS Code AI response:`, error);\n throw error;\n }\n }\n \n private async sendAIRequestViaFileSystem(prompt: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'vscode');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `ai_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `ai_resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'ai_request',\n prompt,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 120000; // AI响应可能需要更长时间\n const checkInterval = 1000;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {}\n \n return `AI request queued for VS Code. File: ${instructionFile}`;\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n const result = await execa.command(command, {\n cwd: cwd || process.cwd(),\n shell: true,\n timeout: 60000, // 60秒超时\n reject: false\n });\n \n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode || 0,\n success: result.exitCode === 0,\n output: result.stdout,\n error: result.failed ? result.stderr : undefined\n };\n } catch (error) {\n this.logger.error(`Error running program in VS Code:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * Cursor 适配器\n * Cursor是基于VS Code的AI编辑器,支持多种交互方式\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport { execa } from 'execa';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport class CursorAdapter extends BaseIDEAdapter {\n readonly type = 'cursor';\n private cursorPath: string | null = null;\n \n protected checkAvailabilitySync(): boolean {\n // 检查Cursor是否通过环境变量标识\n if (process.env.CURSOR_SHELL || process.env.CURSOR_PID) {\n return true;\n }\n \n // 尝试查找Cursor可执行文件\n this.cursorPath = this.findCursorExecutable();\n return !!this.cursorPath;\n }\n \n private findCursorExecutable(): string | null {\n const platform = os.platform();\n const possiblePaths: string[] = [];\n \n if (platform === 'darwin') {\n // macOS\n possiblePaths.push(\n '/Applications/Cursor.app/Contents/MacOS/Cursor',\n '/usr/local/bin/cursor',\n path.join(os.homedir(), 'Applications/Cursor.app/Contents/MacOS/Cursor')\n );\n } else if (platform === 'win32') {\n // Windows\n possiblePaths.push(\n path.join(process.env.LOCALAPPDATA || '', 'Programs/Cursor/Cursor.exe'),\n path.join(process.env.PROGRAMFILES || '', 'Cursor/Cursor.exe'),\n 'C:\\\\Program Files\\\\Cursor\\\\Cursor.exe'\n );\n } else {\n // Linux\n possiblePaths.push(\n '/usr/bin/cursor',\n '/usr/local/bin/cursor',\n '/opt/cursor/cursor',\n path.join(os.homedir(), '.local/bin/cursor')\n );\n }\n \n for (const cursorPath of possiblePaths) {\n if (fs.existsSync(cursorPath)) {\n return cursorPath;\n }\n }\n \n // 尝试使用which/where命令查找\n try {\n if (platform === 'win32') {\n const result = execa.sync('where', ['cursor'], { reject: false });\n if (result.stdout) {\n const lines = result.stdout.split('\\n').map(l => l.trim()).filter(l => l);\n if (lines.length > 0) return lines[0];\n }\n } else {\n const result = execa.sync('which', ['cursor'], { reject: false });\n if (result.stdout) {\n return result.stdout.trim();\n }\n }\n } catch {\n // 查找失败\n }\n \n return null;\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to Cursor: ${command}`);\n \n // 方法1: 尝试使用Cursor CLI (如果可用)\n if (this.cursorPath) {\n try {\n const result = await execa(this.cursorPath, [\n '--command',\n 'workbench.action.executeCommand',\n '--args', JSON.stringify({ command })\n ], {\n timeout: 30000,\n reject: false\n });\n \n if (!result.failed) {\n return `Cursor executed: ${command}\\n${result.stdout}`;\n }\n } catch (cliError) {\n this.logger.debug('Cursor CLI failed, trying alternative methods');\n }\n }\n \n // 方法2: 通过文件系统通信\n return await this.sendViaFileSystem(command, context);\n \n } catch (error) {\n this.logger.error(`Error executing Cursor command:`, error);\n throw new Error(`Cursor command failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n private async sendViaFileSystem(command: string, context?: ExecutionContext): Promise<string> {\n // 创建临时指令文件\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'cursor');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `instruction_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `response_${Date.now()}.txt`);\n \n const instruction = {\n type: 'command',\n command,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n // 等待响应(最多30秒)\n const maxWait = 30000;\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n // 清理临时文件\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {\n // 忽略清理错误\n }\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n // 超时,清理并返回错误\n try {\n fs.unlinkSync(instructionFile);\n } catch {\n // 忽略\n }\n \n return `Command sent to Cursor workspace (file: ${instructionFile}). No response received within ${maxWait}ms. Make sure Cursor is running with Feishu Bridge extension.`;\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from Cursor for prompt: ${prompt}`);\n \n // Cursor使用Composer AI,尝试通过文件系统通信\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'cursor');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `ai_request_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `ai_response_${Date.now()}.txt`);\n \n const instruction = {\n type: 'ai_request',\n prompt,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n // 等待响应\n const maxWait = 60000; // AI响应可能需要更长时间\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {\n // 忽略\n }\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {\n // 忽略\n }\n \n return `AI request sent to Cursor (file: ${instructionFile}). No response received within ${maxWait}ms.`;\n \n } catch (error) {\n this.logger.error(`Error getting Cursor AI response:`, error);\n throw error;\n }\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n const result = await execa.command(command, {\n cwd: cwd || process.cwd(),\n shell: true,\n timeout: 60000,\n reject: false\n });\n \n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode || 0,\n success: result.exitCode === 0,\n output: result.stdout,\n error: result.failed ? result.stderr : undefined\n };\n } catch (error) {\n this.logger.error(`Error running program in Cursor:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * Trae 适配器\n * Trae是字节跳动的AI IDE\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport { execa } from 'execa';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport class TraeAdapter extends BaseIDEAdapter {\n readonly type = 'trae';\n private traePath: string | null = null;\n \n protected checkAvailabilitySync(): boolean {\n // 检查Trae环境变量\n if (process.env.TRAE_SESSION || process.env.TRAE_PID) {\n return true;\n }\n \n // 尝试查找Trae\n this.traePath = this.findTraeExecutable();\n return !!this.traePath;\n }\n \n private findTraeExecutable(): string | null {\n const platform = os.platform();\n const possiblePaths: string[] = [];\n \n if (platform === 'darwin') {\n possiblePaths.push(\n '/Applications/Trae.app/Contents/MacOS/Trae',\n '/usr/local/bin/trae',\n path.join(os.homedir(), 'Applications/Trae.app/Contents/MacOS/Trae')\n );\n } else if (platform === 'win32') {\n possiblePaths.push(\n path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Trae', 'Trae.exe'),\n 'C:\\\\Program Files\\\\Trae\\\\Trae.exe'\n );\n } else {\n possiblePaths.push(\n '/usr/bin/trae',\n '/usr/local/bin/trae',\n '/opt/trae/trae',\n path.join(os.homedir(), '.local/bin/trae')\n );\n }\n \n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n return p;\n }\n }\n \n // 尝试which/where\n try {\n if (platform === 'win32') {\n const result = execa.sync('where', ['trae'], { reject: false });\n if (result.stdout) {\n const lines = result.stdout.split('\\n').map(l => l.trim()).filter(l => l);\n if (lines.length > 0) return lines[0];\n }\n } else {\n const result = execa.sync('which', ['trae'], { reject: false });\n if (result.stdout) {\n return result.stdout.trim();\n }\n }\n } catch {}\n \n return null;\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to Trae: ${command}`);\n \n // 尝试使用Trae CLI\n if (this.traePath) {\n try {\n const result = await execa(this.traePath, [\n '--executeCommand',\n command\n ], {\n timeout: 30000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed) {\n return result.stdout || 'Command executed';\n }\n } catch (cliError) {\n this.logger.debug('Trae CLI failed, using file system');\n }\n }\n \n // 文件系统通信\n return await this.sendViaFileSystem(command, context);\n \n } catch (error) {\n this.logger.error(`Error executing Trae command:`, error);\n throw new Error(`Trae command failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n private async sendViaFileSystem(command: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'trae');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `cmd_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'command',\n command,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n // 等待响应\n const maxWait = 30000;\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {}\n \n return `Command queued for Trae. File: ${instructionFile}`;\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from Trae for prompt: ${prompt}`);\n \n if (this.traePath) {\n try {\n const result = await execa(this.traePath, [\n '--ai',\n prompt\n ], {\n timeout: 60000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed && result.stdout) {\n return result.stdout;\n }\n } catch (cliError) {\n this.logger.debug('Trae AI CLI failed, using file system');\n }\n }\n \n return await this.sendAIRequestViaFileSystem(prompt, context);\n \n } catch (error) {\n this.logger.error(`Error getting Trae AI response:`, error);\n throw error;\n }\n }\n \n private async sendAIRequestViaFileSystem(prompt: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'trae');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `ai_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `ai_resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'ai_request',\n prompt,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 120000;\n const checkInterval = 1000;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {}\n \n return `AI request queued for Trae. File: ${instructionFile}`;\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n const result = await execa.command(command, {\n cwd: cwd || process.cwd(),\n shell: true,\n timeout: 60000,\n reject: false\n });\n \n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode || 0,\n success: result.exitCode === 0,\n output: result.stdout,\n error: result.failed ? result.stderr : undefined\n };\n } catch (error) {\n this.logger.error(`Error running program in Trae:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * Antigravity 适配器\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport { execa } from 'execa';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport class AntigravityAdapter extends BaseIDEAdapter {\n readonly type = 'antigravity';\n private antigravityPath: string | null = null;\n \n protected checkAvailabilitySync(): boolean {\n if (process.env.ANTIGRAVITY_SESSION) {\n return true;\n }\n \n this.antigravityPath = this.findAntigravityExecutable();\n return !!this.antigravityPath;\n }\n \n private findAntigravityExecutable(): string | null {\n try {\n const result = execa.sync('which', ['antigravity'], { reject: false });\n if (result.stdout) return result.stdout.trim();\n } catch {}\n \n const possiblePaths = [\n '/usr/local/bin/antigravity',\n '/usr/bin/antigravity',\n path.join(os.homedir(), '.local/bin/antigravity')\n ];\n \n for (const p of possiblePaths) {\n if (fs.existsSync(p)) return p;\n }\n \n return null;\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to Antigravity: ${command}`);\n \n if (this.antigravityPath) {\n try {\n const result = await execa(this.antigravityPath, ['execute', command], {\n timeout: 30000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed) {\n return result.stdout || 'Command executed';\n }\n } catch (cliError) {\n this.logger.debug('Antigravity CLI failed, using file system');\n }\n }\n \n return await this.sendViaFileSystem(command, context);\n } catch (error) {\n this.logger.error(`Error executing Antigravity command:`, error);\n throw new Error(`Antigravity command failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n private async sendViaFileSystem(command: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'antigravity');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `cmd_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'command',\n command,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 30000;\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try { fs.unlinkSync(instructionFile); } catch {}\n return `Command queued for Antigravity. File: ${instructionFile}`;\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from Antigravity for prompt: ${prompt}`);\n \n if (this.antigravityPath) {\n try {\n const result = await execa(this.antigravityPath, ['ask', prompt], {\n timeout: 60000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed && result.stdout) {\n return result.stdout;\n }\n } catch (cliError) {\n this.logger.debug('Antigravity AI CLI failed, using file system');\n }\n }\n \n return await this.sendAIRequestViaFileSystem(prompt, context);\n } catch (error) {\n this.logger.error(`Error getting Antigravity AI response:`, error);\n throw error;\n }\n }\n \n private async sendAIRequestViaFileSystem(prompt: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'antigravity');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `ai_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `ai_resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'ai_request',\n prompt,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 120000;\n const checkInterval = 1000;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try { fs.unlinkSync(instructionFile); } catch {}\n return `AI request queued for Antigravity. File: ${instructionFile}`;\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n const result = await execa.command(command, {\n cwd: cwd || process.cwd(),\n shell: true,\n timeout: 60000,\n reject: false\n });\n \n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode || 0,\n success: result.exitCode === 0,\n output: result.stdout,\n error: result.failed ? result.stderr : undefined\n };\n } catch (error) {\n this.logger.error(`Error running program in Antigravity:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * Kiro 适配器\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport { execa } from 'execa';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport class KiroAdapter extends BaseIDEAdapter {\n readonly type = 'kiro';\n private kiroPath: string | null = null;\n \n protected checkAvailabilitySync(): boolean {\n if (process.env.KIRO_SESSION) {\n return true;\n }\n \n this.kiroPath = this.findKiroExecutable();\n return !!this.kiroPath;\n }\n \n private findKiroExecutable(): string | null {\n try {\n const result = execa.sync('which', ['kiro'], { reject: false });\n if (result.stdout) return result.stdout.trim();\n } catch {}\n \n const possiblePaths = [\n '/usr/local/bin/kiro',\n '/usr/bin/kiro',\n path.join(os.homedir(), '.local/bin/kiro')\n ];\n \n for (const p of possiblePaths) {\n if (fs.existsSync(p)) return p;\n }\n \n return null;\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to Kiro: ${command}`);\n \n if (this.kiroPath) {\n try {\n const result = await execa(this.kiroPath, ['execute', command], {\n timeout: 30000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed) {\n return result.stdout || 'Command executed';\n }\n } catch (cliError) {\n this.logger.debug('Kiro CLI failed, using file system');\n }\n }\n \n return await this.sendViaFileSystem(command, context);\n } catch (error) {\n this.logger.error(`Error executing Kiro command:`, error);\n throw new Error(`Kiro command failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n private async sendViaFileSystem(command: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'kiro');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `cmd_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'command',\n command,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 30000;\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try { fs.unlinkSync(instructionFile); } catch {}\n return `Command queued for Kiro. File: ${instructionFile}`;\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from Kiro for prompt: ${prompt}`);\n \n if (this.kiroPath) {\n try {\n const result = await execa(this.kiroPath, ['ask', prompt], {\n timeout: 60000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed && result.stdout) {\n return result.stdout;\n }\n } catch (cliError) {\n this.logger.debug('Kiro AI CLI failed, using file system');\n }\n }\n \n return await this.sendAIRequestViaFileSystem(prompt, context);\n } catch (error) {\n this.logger.error(`Error getting Kiro AI response:`, error);\n throw error;\n }\n }\n \n private async sendAIRequestViaFileSystem(prompt: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'kiro');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `ai_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `ai_resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'ai_request',\n prompt,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 120000;\n const checkInterval = 1000;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try { fs.unlinkSync(instructionFile); } catch {}\n return `AI request queued for Kiro. File: ${instructionFile}`;\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n const result = await execa.command(command, {\n cwd: cwd || process.cwd(),\n shell: true,\n timeout: 60000,\n reject: false\n });\n \n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode || 0,\n success: result.exitCode === 0,\n output: result.stdout,\n error: result.failed ? result.stderr : undefined\n };\n } catch (error) {\n this.logger.error(`Error running program in Kiro:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * OpenCode 适配器\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport * as net from 'net';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\n\nexport class OpenCodeAdapter extends BaseIDEAdapter {\n readonly type = 'opencode';\n private sessionId?: string;\n \n protected checkAvailabilitySync(): boolean {\n // 检查OpenCode是否可用,通过环境变量或特定路径\n return !!process.env.OPENCODE_SESSION || \n fs.existsSync(path.join(os.homedir(), '.opencode', 'session')) ||\n this.checkOpenCodeProcess();\n }\n \n private checkOpenCodeProcess(): boolean {\n try {\n // 检查是否有OpenCode相关的进程\n return true; // 简化检查,实际实现可能需要更复杂的逻辑\n } catch {\n return false;\n }\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to OpenCode: ${command}`);\n \n // 与OpenCode进程通信,可能通过socket或API\n const socketPath = this.getSocketPath();\n \n if (socketPath && fs.existsSync(socketPath)) {\n return await this.sendViaSocket({\n type: 'command',\n command,\n sessionId: this.sessionId,\n context\n });\n } else {\n // 如果无法通过socket通信,尝试其他方式\n return `OpenCode processed command: ${command}`;\n }\n } catch (error) {\n this.logger.error(`Error executing OpenCode command:`, error);\n throw error;\n }\n }\n \n private getSocketPath(): string | null {\n // 尝试确定OpenCode的socket路径\n const possiblePaths = [\n path.join(os.tmpdir(), 'opencode.sock'),\n path.join(os.homedir(), '.opencode', 'socket'),\n process.env.OPENCODE_SOCKET || ''\n ];\n \n for (const socketPath of possiblePaths) {\n if (socketPath && fs.existsSync(socketPath)) {\n return socketPath;\n }\n }\n \n return null;\n }\n \n private sendViaSocket(data: any): Promise<string> {\n return new Promise((resolve, reject) => {\n const socketPath = this.getSocketPath();\n if (!socketPath) {\n reject(new Error('No OpenCode socket available'));\n return;\n }\n \n const client = net.createConnection(socketPath);\n let response = '';\n \n client.on('data', (data) => {\n response += data.toString();\n });\n \n client.on('end', () => {\n try {\n const parsed = JSON.parse(response);\n resolve(parsed.result || response);\n } catch (e) {\n resolve(response);\n }\n });\n \n client.on('error', (err) => {\n reject(err);\n });\n \n // 发送命令\n client.write(JSON.stringify(data));\n \n // 设置超时\n setTimeout(() => {\n client.destroy();\n reject(new Error('OpenCode command timeout'));\n }, 30000); // 30秒超时\n });\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from OpenCode for prompt: ${prompt}`);\n \n // 发送AI请求到OpenCode\n return await this.sendCommand(`/ask ${prompt}`, context);\n } catch (error) {\n this.logger.error(`Error getting OpenCode AI response:`, error);\n throw error;\n }\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n // 通过OpenCode运行程序\n const result = await this.sendCommand(`/run ${command}`, { workspaceRoot: cwd });\n \n return {\n stdout: result,\n stderr: '',\n exitCode: 0,\n success: true,\n output: result\n };\n } catch (error) {\n this.logger.error(`Error running program in OpenCode:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * Claude Code 适配器\n * Claude Code是Anthropic的CLI工具\n */\nimport { BaseIDEAdapter, ExecutionContext, CodeGenOptions, ExecutionResult } from './base';\nimport { execa } from 'execa';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\nexport class ClaudeCodeAdapter extends BaseIDEAdapter {\n readonly type = 'claude';\n private claudePath: string | null = null;\n \n protected checkAvailabilitySync(): boolean {\n // 检查Claude Code环境变量\n if (process.env.CLAUDE_CODE_SESSION) {\n return true;\n }\n \n // 尝试查找claude CLI\n this.claudePath = this.findClaudeExecutable();\n return !!this.claudePath;\n }\n \n private findClaudeExecutable(): string | null {\n const platform = os.platform();\n \n // 尝试直接调用claude命令\n try {\n const result = execa.sync('claude', ['--version'], { reject: false });\n if (result.exitCode === 0) {\n return 'claude';\n }\n } catch {\n // 未找到\n }\n \n // 查找常见安装路径\n const possiblePaths: string[] = [];\n \n if (platform === 'darwin') {\n possiblePaths.push(\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude',\n path.join(os.homedir(), '.local/bin/claude')\n );\n } else if (platform === 'win32') {\n possiblePaths.push(\n path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'claude', 'claude.exe'),\n 'C:\\\\Program Files\\\\Claude\\\\claude.exe'\n );\n } else {\n possiblePaths.push(\n '/usr/bin/claude',\n '/usr/local/bin/claude',\n path.join(os.homedir(), '.local/bin/claude'),\n path.join(os.homedir(), '.npm-global/bin/claude')\n );\n }\n \n for (const p of possiblePaths) {\n if (fs.existsSync(p)) {\n return p;\n }\n }\n \n return null;\n }\n \n async checkAvailability(): Promise<boolean> {\n return this.checkAvailabilitySync();\n }\n \n async sendCommand(command: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Sending command to Claude Code: ${command}`);\n \n // 尝试使用Claude CLI\n if (this.claudePath) {\n try {\n // Claude Code支持命令行参数\n const result = await execa(this.claudePath, [\n 'execute',\n '--command', command\n ], {\n timeout: 30000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed) {\n return result.stdout || 'Command executed successfully';\n }\n } catch (cliError) {\n this.logger.debug('Claude CLI failed, trying file system method');\n }\n }\n \n // 备用:文件系统通信\n return await this.sendViaFileSystem(command, context);\n \n } catch (error) {\n this.logger.error(`Error executing Claude Code command:`, error);\n throw new Error(`Claude Code command failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n private async sendViaFileSystem(command: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'claude');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `cmd_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'command',\n command,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n // 等待响应\n const maxWait = 30000;\n const checkInterval = 500;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {}\n \n return `Command queued for Claude Code. File: ${instructionFile}`;\n }\n \n async getAIResponse(prompt: string, context?: ExecutionContext): Promise<string> {\n try {\n this.logger.info(`Getting AI response from Claude Code for prompt: ${prompt}`);\n \n // 尝试使用Claude CLI直接询问\n if (this.claudePath) {\n try {\n const result = await execa(this.claudePath, [\n 'ask',\n '--prompt', prompt\n ], {\n timeout: 60000,\n reject: false,\n cwd: context?.workspaceRoot\n });\n \n if (!result.failed && result.stdout) {\n return result.stdout;\n }\n } catch (cliError) {\n this.logger.debug('Claude ask CLI failed, using file system');\n }\n }\n \n // 文件系统方式\n return await this.sendAIRequestViaFileSystem(prompt, context);\n \n } catch (error) {\n this.logger.error(`Error getting Claude Code AI response:`, error);\n throw error;\n }\n }\n \n private async sendAIRequestViaFileSystem(prompt: string, context?: ExecutionContext): Promise<string> {\n const tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'claude');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n \n const instructionFile = path.join(tempDir, `ai_${Date.now()}.json`);\n const responseFile = path.join(tempDir, `ai_resp_${Date.now()}.txt`);\n \n const instruction = {\n type: 'ai_request',\n prompt,\n context,\n timestamp: Date.now(),\n responseFile\n };\n \n fs.writeFileSync(instructionFile, JSON.stringify(instruction, null, 2));\n \n const maxWait = 120000; // AI可能需要更长时间\n const checkInterval = 1000;\n let waited = 0;\n \n while (waited < maxWait) {\n if (fs.existsSync(responseFile)) {\n const response = fs.readFileSync(responseFile, 'utf-8');\n try {\n fs.unlinkSync(instructionFile);\n fs.unlinkSync(responseFile);\n } catch {}\n return response;\n }\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n waited += checkInterval;\n }\n \n try {\n fs.unlinkSync(instructionFile);\n } catch {}\n \n return `AI request queued. File: ${instructionFile}`;\n }\n \n async generateCode(description: string, options?: CodeGenOptions): Promise<string> {\n const fullPrompt = this.buildCodePrompt(description, options);\n return this.getAIResponse(fullPrompt);\n }\n \n async runProgram(command: string, cwd?: string): Promise<ExecutionResult> {\n try {\n const result = await execa.command(command, {\n cwd: cwd || process.cwd(),\n shell: true,\n timeout: 60000,\n reject: false\n });\n \n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode || 0,\n success: result.exitCode === 0,\n output: result.stdout,\n error: result.failed ? result.stderr : undefined\n };\n } catch (error) {\n this.logger.error(`Error running program in Claude Code:`, error);\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n}","/**\n * 主桥接器,协调各模块\n */\nimport { FeishuWebhookHandler } from '../feishu/webhook';\nimport { FeishuWebSocketHandler } from '../feishu/websocket';\nimport { FeishuClient } from '../feishu/client';\nimport { CommandExecutor } from '../commands/executor';\nimport { SessionManager } from '../session/manager';\nimport { VSCodeAdapter } from '../adapters/vscode';\nimport { CursorAdapter } from '../adapters/cursor';\nimport { TraeAdapter } from '../adapters/trae';\nimport { AntigravityAdapter } from '../adapters/antigravity';\nimport { KiroAdapter } from '../adapters/kiro';\nimport { OpenCodeAdapter } from '../adapters/opencode';\nimport { ClaudeCodeAdapter } from '../adapters/claude-code';\nimport { ConfigManager } from './config';\nimport { HealthMonitor } from './health';\nimport { logger } from './logger';\nimport { ReverseChannel } from './reverse-channel';\nimport Fastify, { FastifyInstance } from 'fastify';\n\nexport class FeishuBridge {\n private server: FastifyInstance;\n private feishuClient: FeishuClient;\n private webhookHandler: FeishuWebhookHandler;\n private wsHandler: FeishuWebSocketHandler | null = null;\n private commandExecutor: CommandExecutor;\n private sessionManager: SessionManager;\n private healthMonitor: HealthMonitor | null = null;\n private reverseChannel: ReverseChannel | null = null;\n private adapters: Map<string, any> = new Map();\n\n constructor() {\n this.server = Fastify({\n logger: false // 使用我们自己的日志系统\n });\n\n const config = ConfigManager.getInstance().get();\n this.feishuClient = new FeishuClient(config.feishu);\n this.sessionManager = new SessionManager(config.behavior.sessionTimeout);\n\n // 初始化反向通信通道\n this.reverseChannel = new ReverseChannel(this.feishuClient);\n\n // 初始化适配器\n this.initAdapters();\n\n this.commandExecutor = new CommandExecutor(\n this.adapters,\n this.sessionManager\n );\n\n this.webhookHandler = new FeishuWebhookHandler(\n this.feishuClient,\n this.commandExecutor\n );\n }\n\n private initAdapters(): void {\n const config = ConfigManager.getInstance().get();\n\n // 注册VSCode适配器\n if (config.adapters.vscode?.enabled) {\n const adapter = new VSCodeAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('vscode', adapter);\n }\n\n // 注册Cursor适配器\n if (config.adapters.cursor?.enabled) {\n const adapter = new CursorAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('cursor', adapter);\n }\n\n // 注册Trae适配器\n if (config.adapters.trae?.enabled) {\n const adapter = new TraeAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('trae', adapter);\n }\n\n // 注册Antigravity适配器\n if (config.adapters.antigravity?.enabled) {\n const adapter = new AntigravityAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('antigravity', adapter);\n }\n\n // 注册Kiro适配器\n if (config.adapters.kiro?.enabled) {\n const adapter = new KiroAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('kiro', adapter);\n }\n\n // 注册OpenCode适配器\n if (config.adapters.opencode?.enabled) {\n const adapter = new OpenCodeAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('opencode', adapter);\n }\n\n // 注册Claude Code适配器\n if (config.adapters['claude-code']?.enabled) {\n const adapter = new ClaudeCodeAdapter();\n if (this.reverseChannel) adapter.setReverseChannel(this.reverseChannel);\n this.adapters.set('claude', adapter);\n }\n }\n\n public async start(): Promise<void> {\n const config = ConfigManager.getInstance().get();\n const serverConfig = config.server;\n\n // 启动反向通信通道\n if (this.reverseChannel) {\n this.reverseChannel.start();\n logger.info('Reverse communication channel started');\n }\n\n // 初始化健康监控(仅在webhook模式下)\n if (config.feishu.connectionMode !== 'websocket') {\n this.healthMonitor = new HealthMonitor(\n this.server,\n this.sessionManager,\n this.adapters\n );\n }\n \n // 根据连接模式启动不同的服务\n if (config.feishu.connectionMode === 'websocket') {\n // WebSocket模式\n logger.info('Starting in WebSocket mode...');\n this.wsHandler = new FeishuWebSocketHandler(\n this.feishuClient,\n this.commandExecutor\n );\n await this.wsHandler.start();\n logger.info('WebSocket connection established');\n } else {\n // Webhook模式(默认)\n logger.info('Starting in Webhook mode...');\n \n // 注册webhook路由\n this.server.post(serverConfig.webhookPath, async (request, reply) => {\n await this.webhookHandler.handleWebhook(request, reply);\n });\n \n // 启动服务器\n try {\n const address = await this.server.listen({\n port: serverConfig.port,\n host: serverConfig.host\n });\n \n logger.info(`Feishu Bridge server running on ${address}`);\n logger.info(`Webhook endpoint: ${serverConfig.webhookPath}`);\n logger.info(`Health check endpoint: /health`);\n logger.info(`Metrics endpoint: /metrics`);\n } catch (err) {\n logger.error(err instanceof Error ? err : String(err));\n process.exit(1);\n }\n }\n }\n\n public async stop(): Promise<void> {\n // 停止反向通信通道\n if (this.reverseChannel) {\n this.reverseChannel.stop();\n logger.info('Reverse communication channel stopped');\n }\n\n // 停止WebSocket连接\n if (this.wsHandler) {\n await this.wsHandler.stop();\n this.wsHandler = null;\n }\n\n // 停止HTTP服务器\n await this.server.close();\n logger.info('Feishu Bridge server stopped');\n }\n\n public getAdapter(adapterName: string) {\n return this.adapters.get(adapterName);\n }\n\n public getAdapters(): Map<string, any> {\n return this.adapters;\n }\n}","/**\n * 健康检查和监控模块\n */\nimport { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\nimport { SessionManager } from '../session/manager';\nimport { ConfigManager } from './config';\n\ninterface HealthStatus {\n status: 'healthy' | 'unhealthy' | 'degraded';\n timestamp: string;\n version: string;\n checks: {\n feishu: {\n status: 'ok' | 'error';\n message?: string;\n };\n adapters: {\n status: 'ok' | 'error';\n available: number;\n total: number;\n details: Record<string, boolean>;\n };\n session: {\n status: 'ok';\n activeSessions: number;\n };\n };\n}\n\ninterface MetricsData {\n timestamp: string;\n uptime: number;\n memory: {\n used: number;\n total: number;\n external: number;\n };\n sessions: {\n active: number;\n total: number;\n };\n requests: {\n total: number;\n successful: number;\n failed: number;\n };\n adapters: Record<string, {\n available: boolean;\n lastCheck: string;\n }>;\n}\n\nexport class HealthMonitor {\n private startTime: number;\n private requestCount = { total: 0, successful: 0, failed: 0 };\n\n constructor(\n private server: FastifyInstance,\n private sessionManager: SessionManager,\n private adapters: Map<string, any>\n ) {\n this.startTime = Date.now();\n this.setupRoutes();\n }\n\n /**\n * 设置健康检查路由\n */\n private setupRoutes(): void {\n // 健康检查端点\n this.server.get('/health', this.handleHealth.bind(this));\n \n // 就绪检查端点\n this.server.get('/health/ready', this.handleReadiness.bind(this));\n \n // 存活检查端点\n this.server.get('/health/live', this.handleLiveness.bind(this));\n \n // Prometheus格式指标\n this.server.get('/metrics', this.handleMetrics.bind(this));\n }\n\n /**\n * 处理健康检查请求\n */\n private async handleHealth(\n _request: FastifyRequest,\n reply: FastifyReply\n ): Promise<void> {\n const status = await this.getHealthStatus();\n const statusCode = status.status === 'healthy' ? 200 : \n status.status === 'degraded' ? 200 : 503;\n \n reply.status(statusCode).send(status);\n }\n\n /**\n * 处理就绪检查\n */\n private async handleReadiness(\n _request: FastifyRequest,\n reply: FastifyReply\n ): Promise<void> {\n const config = ConfigManager.getInstance().get();\n \n // 检查基本配置是否就绪\n const isReady = config.feishu.appId && config.feishu.appSecret;\n \n if (isReady) {\n reply.status(200).send({\n ready: true,\n timestamp: new Date().toISOString()\n });\n } else {\n reply.status(503).send({\n ready: false,\n message: 'Configuration incomplete',\n timestamp: new Date().toISOString()\n });\n }\n }\n\n /**\n * 处理存活检查\n */\n private async handleLiveness(\n _request: FastifyRequest,\n reply: FastifyReply\n ): Promise<void> {\n reply.status(200).send({\n alive: true,\n uptime: process.uptime(),\n timestamp: new Date().toISOString()\n });\n }\n\n /**\n * 处理指标请求\n */\n private async handleMetrics(\n _request: FastifyRequest,\n reply: FastifyReply\n ): Promise<void> {\n const metrics = await this.getMetrics();\n const prometheusFormat = this.toPrometheusFormat(metrics);\n \n reply\n .header('Content-Type', 'text/plain; version=0.0.4')\n .send(prometheusFormat);\n }\n\n /**\n * 获取健康状态\n */\n private async getHealthStatus(): Promise<HealthStatus> {\n const config = ConfigManager.getInstance().get();\n const adapterStatuses: Record<string, boolean> = {};\n let availableAdapters = 0;\n\n // 检查各适配器状态\n for (const [name, adapter] of this.adapters) {\n try {\n const isAvailable = await adapter.checkAvailability();\n adapterStatuses[name] = isAvailable;\n if (isAvailable) availableAdapters++;\n } catch (error) {\n adapterStatuses[name] = false;\n }\n }\n\n const totalAdapters = this.adapters.size;\n const feishuConfigured = !!(config.feishu.appId && config.feishu.appSecret);\n \n // 确定整体状态\n let status: HealthStatus['status'] = 'healthy';\n if (!feishuConfigured) {\n status = 'unhealthy';\n } else if (availableAdapters === 0 && totalAdapters > 0) {\n status = 'degraded';\n }\n\n return {\n status,\n timestamp: new Date().toISOString(),\n version: process.env.npm_package_version || '1.0.0',\n checks: {\n feishu: {\n status: feishuConfigured ? 'ok' : 'error',\n message: feishuConfigured ? undefined : 'App ID or Secret not configured'\n },\n adapters: {\n status: availableAdapters > 0 ? 'ok' : 'error',\n available: availableAdapters,\n total: totalAdapters,\n details: adapterStatuses\n },\n session: {\n status: 'ok',\n activeSessions: this.sessionManager.getActiveSessionCount()\n }\n }\n };\n }\n\n /**\n * 获取指标数据\n */\n private async getMetrics(): Promise<MetricsData> {\n const memUsage = process.memoryUsage();\n const adapterMetrics: Record<string, { available: boolean; lastCheck: string }> = {};\n\n for (const [name, adapter] of this.adapters) {\n try {\n const isAvailable = await adapter.checkAvailability();\n adapterMetrics[name] = {\n available: isAvailable,\n lastCheck: new Date().toISOString()\n };\n } catch (error) {\n adapterMetrics[name] = {\n available: false,\n lastCheck: new Date().toISOString()\n };\n }\n }\n\n return {\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n memory: {\n used: Math.round(memUsage.heapUsed / 1024 / 1024), // MB\n total: Math.round(memUsage.heapTotal / 1024 / 1024),\n external: Math.round(memUsage.external / 1024 / 1024)\n },\n sessions: {\n active: this.sessionManager.getActiveSessionCount(),\n total: 0 // 可以通过SessionManager扩展获取\n },\n requests: { ...this.requestCount },\n adapters: adapterMetrics\n };\n }\n\n /**\n * 转换为Prometheus格式\n */\n private toPrometheusFormat(metrics: MetricsData): string {\n const lines: string[] = [];\n \n // Uptime\n lines.push('# HELP feishu_bridge_uptime_seconds Process uptime in seconds');\n lines.push('# TYPE feishu_bridge_uptime_seconds gauge');\n lines.push(`feishu_bridge_uptime_seconds ${metrics.uptime}`);\n \n // Memory\n lines.push('# HELP feishu_bridge_memory_usage_mb Memory usage in MB');\n lines.push('# TYPE feishu_bridge_memory_usage_mb gauge');\n lines.push(`feishu_bridge_memory_usage_mb{type=\"used\"} ${metrics.memory.used}`);\n lines.push(`feishu_bridge_memory_usage_mb{type=\"total\"} ${metrics.memory.total}`);\n lines.push(`feishu_bridge_memory_usage_mb{type=\"external\"} ${metrics.memory.external}`);\n \n // Sessions\n lines.push('# HELP feishu_bridge_active_sessions Number of active sessions');\n lines.push('# TYPE feishu_bridge_active_sessions gauge');\n lines.push(`feishu_bridge_active_sessions ${metrics.sessions.active}`);\n \n // Requests\n lines.push('# HELP feishu_bridge_requests_total Total number of requests');\n lines.push('# TYPE feishu_bridge_requests_total counter');\n lines.push(`feishu_bridge_requests_total ${metrics.requests.total}`);\n \n lines.push('# HELP feishu_bridge_requests_successful Total successful requests');\n lines.push('# TYPE feishu_bridge_requests_successful counter');\n lines.push(`feishu_bridge_requests_successful ${metrics.requests.successful}`);\n \n lines.push('# HELP feishu_bridge_requests_failed Total failed requests');\n lines.push('# TYPE feishu_bridge_requests_failed counter');\n lines.push(`feishu_bridge_requests_failed ${metrics.requests.failed}`);\n \n // Adapter availability\n lines.push('# HELP feishu_bridge_adapter_available Adapter availability (1=available, 0=unavailable)');\n lines.push('# TYPE feishu_bridge_adapter_available gauge');\n \n for (const [name, data] of Object.entries(metrics.adapters)) {\n const value = data.available ? 1 : 0;\n lines.push(`feishu_bridge_adapter_available{name=\"${name}\"} ${value}`);\n }\n \n return lines.join('\\n');\n }\n\n /**\n * 记录请求\n */\n public recordRequest(success: boolean): void {\n this.requestCount.total++;\n if (success) {\n this.requestCount.successful++;\n } else {\n this.requestCount.failed++;\n }\n }\n}\n","/**\n * 双向通信管理器\n * 支持从IDE/CLI主动向飞书推送消息\n */\n\nimport { FeishuClient } from '../feishu/client';\nimport { ConfigManager } from './config';\nimport { logger } from './logger';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { EventEmitter } from 'events';\n\nexport interface ReverseMessage {\n type: 'message' | 'notification' | 'status' | 'result';\n content: string;\n chatId?: string;\n senderId?: string;\n metadata?: Record<string, any>;\n timestamp: number;\n}\n\nexport interface ReverseChannelConfig {\n enabled: boolean;\n mode: 'websocket' | 'filesystem' | 'http';\n checkInterval: number;\n maxMessageAge: number;\n}\n\n/**\n * 反向通信通道\n * 允许IDE/CLI适配器主动向飞书发送消息\n */\nexport class ReverseChannel extends EventEmitter {\n private config: ReverseChannelConfig;\n private feishuClient: FeishuClient;\n private isRunning = false;\n private checkInterval: NodeJS.Timeout | null = null;\n private messageQueue: ReverseMessage[] = [];\n private tempDir: string;\n\n constructor(feishuClient: FeishuClient) {\n super();\n this.feishuClient = feishuClient;\n \n const bridgeConfig = ConfigManager.getInstance().get();\n this.config = {\n enabled: bridgeConfig.behavior?.reverseChannelEnabled ?? true,\n mode: bridgeConfig.behavior?.reverseChannelMode ?? 'filesystem',\n checkInterval: 1000, // 1秒检查一次\n maxMessageAge: 5 * 60 * 1000 // 5分钟过期\n };\n \n this.tempDir = path.join(os.tmpdir(), 'feishu-bridge', 'reverse-channel');\n this.ensureTempDir();\n }\n\n /**\n * 启动反向通信通道\n */\n start(): void {\n if (this.isRunning || !this.config.enabled) {\n return;\n }\n\n this.isRunning = true;\n logger.info('Starting reverse communication channel...');\n\n // 根据模式启动不同的监听机制\n switch (this.config.mode) {\n case 'filesystem':\n this.startFileSystemListener();\n break;\n case 'websocket':\n this.startWebSocketListener();\n break;\n case 'http':\n this.startHttpListener();\n break;\n }\n\n // 启动消息队列处理器\n this.startMessageQueueProcessor();\n }\n\n /**\n * 停止反向通信通道\n */\n stop(): void {\n if (!this.isRunning) {\n return;\n }\n\n this.isRunning = false;\n logger.info('Stopping reverse communication channel...');\n\n if (this.checkInterval) {\n clearInterval(this.checkInterval);\n this.checkInterval = null;\n }\n }\n\n /**\n * 发送消息到飞书(供适配器调用)\n */\n async sendToFeishu(message: ReverseMessage): Promise<boolean> {\n try {\n // 添加到消息队列\n this.messageQueue.push(message);\n this.emit('messageQueued', message);\n return true;\n } catch (error) {\n logger.error('Error queuing message to Feishu:', error);\n return false;\n }\n }\n\n /**\n * 发送文件系统消息(供IDE写入文件后调用)\n */\n async sendFileSystemMessage(\n adapterType: string,\n content: string,\n chatId?: string\n ): Promise<void> {\n const message: ReverseMessage = {\n type: 'message',\n content,\n chatId,\n timestamp: Date.now()\n };\n\n const messageFile = path.join(\n this.tempDir,\n `${adapterType}_msg_${Date.now()}.json`\n );\n\n fs.writeFileSync(messageFile, JSON.stringify(message, null, 2));\n logger.debug(`File system message written: ${messageFile}`);\n }\n\n private ensureTempDir(): void {\n if (!fs.existsSync(this.tempDir)) {\n fs.mkdirSync(this.tempDir, { recursive: true });\n }\n }\n\n private startFileSystemListener(): void {\n logger.info('Starting file system listener for reverse channel...');\n\n this.checkInterval = setInterval(() => {\n this.processFileSystemMessages();\n }, this.config.checkInterval);\n }\n\n private processFileSystemMessages(): void {\n if (!fs.existsSync(this.tempDir)) {\n return;\n }\n\n try {\n const files = fs.readdirSync(this.tempDir);\n const now = Date.now();\n\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n\n const filePath = path.join(this.tempDir, file);\n \n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const message: ReverseMessage = JSON.parse(content);\n\n // 检查消息是否过期\n if (now - message.timestamp > this.config.maxMessageAge) {\n fs.unlinkSync(filePath);\n continue;\n }\n\n // 添加到队列\n this.messageQueue.push(message);\n \n // 删除已处理的消息文件\n fs.unlinkSync(filePath);\n \n logger.debug(`Processed file system message: ${file}`);\n } catch (error) {\n logger.error(`Error processing message file ${file}:`, error);\n // 删除损坏的文件\n try {\n fs.unlinkSync(filePath);\n } catch {}\n }\n }\n } catch (error) {\n logger.error('Error reading message directory:', error);\n }\n }\n\n private startWebSocketListener(): void {\n // WebSocket模式:通过WebSocket连接接收消息\n logger.info('WebSocket reverse channel not yet implemented, falling back to file system');\n this.startFileSystemListener();\n }\n\n private startHttpListener(): void {\n // HTTP模式:通过HTTP端点接收消息\n logger.info('HTTP reverse channel not yet implemented, falling back to file system');\n this.startFileSystemListener();\n }\n\n private startMessageQueueProcessor(): void {\n // 定期处理消息队列\n setInterval(async () => {\n await this.processMessageQueue();\n }, 500); // 每500ms处理一次队列\n }\n\n private async processMessageQueue(): Promise<void> {\n if (this.messageQueue.length === 0) {\n return;\n }\n\n const messagesToProcess = [...this.messageQueue];\n this.messageQueue = [];\n\n for (const message of messagesToProcess) {\n try {\n await this.deliverMessageToFeishu(message);\n this.emit('messageDelivered', message);\n } catch (error) {\n logger.error('Error delivering message to Feishu:', error);\n // 重新入队稍后重试(最多3次)\n if (!(message as any).retryCount || (message as any).retryCount < 3) {\n (message as any).retryCount = ((message as any).retryCount || 0) + 1;\n this.messageQueue.push(message);\n }\n }\n }\n }\n\n private async deliverMessageToFeishu(message: ReverseMessage): Promise<void> {\n const { type, content, chatId, metadata } = message;\n\n if (!chatId) {\n logger.warn('No chatId specified for message, cannot deliver');\n return;\n }\n\n // 格式化消息\n let formattedContent = content;\n \n switch (type) {\n case 'notification':\n formattedContent = `🔔 ${content}`;\n break;\n case 'status':\n formattedContent = `📊 ${content}`;\n break;\n case 'result':\n formattedContent = `✅ ${content}`;\n break;\n default:\n formattedContent = content;\n }\n\n // 截断过长消息\n const maxLength = 2000;\n if (formattedContent.length > maxLength) {\n formattedContent = formattedContent.substring(0, maxLength) + '\\n...(truncated)';\n }\n\n // 发送到飞书\n await this.feishuClient.sendMessage(chatId, {\n msg_type: 'text',\n content: {\n text: formattedContent\n }\n });\n\n logger.info(`Message delivered to Feishu chat ${chatId}`);\n }\n\n isActive(): boolean {\n return this.isRunning;\n }\n\n getQueueSize(): number {\n return this.messageQueue.length;\n }\n}\n"],"mappings":"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","names":["fs","path","fs","os","path","platform","execa","fs","path","os","platform","execa","fs","path","os","platform","execa","fs","path","os","execa","fs","path","os","fs","os","path","data","execa","fs","path","os","platform","fs","path","os","DaemonManager"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
declare class FeishuBridge {
|
|
2
|
+
private server;
|
|
3
|
+
private feishuClient;
|
|
4
|
+
private webhookHandler;
|
|
5
|
+
private wsHandler;
|
|
6
|
+
private commandExecutor;
|
|
7
|
+
private sessionManager;
|
|
8
|
+
private healthMonitor;
|
|
9
|
+
private reverseChannel;
|
|
10
|
+
private adapters;
|
|
11
|
+
constructor();
|
|
12
|
+
private initAdapters;
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
getAdapter(adapterName: string): any;
|
|
16
|
+
getAdapters(): Map<string, any>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface BridgeConfig {
|
|
20
|
+
feishu: {
|
|
21
|
+
appId: string;
|
|
22
|
+
appSecret: string;
|
|
23
|
+
domain: 'feishu' | 'lark';
|
|
24
|
+
connectionMode: 'websocket' | 'webhook';
|
|
25
|
+
encryptKey?: string;
|
|
26
|
+
verificationToken?: string;
|
|
27
|
+
};
|
|
28
|
+
server: {
|
|
29
|
+
port: number;
|
|
30
|
+
host: string;
|
|
31
|
+
webhookPath: string;
|
|
32
|
+
};
|
|
33
|
+
adapters: {
|
|
34
|
+
vscode?: {
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
executablePath?: string;
|
|
37
|
+
};
|
|
38
|
+
cursor?: {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
};
|
|
41
|
+
trae?: {
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
};
|
|
44
|
+
antigravity?: {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
};
|
|
47
|
+
kiro?: {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
};
|
|
50
|
+
opencode?: {
|
|
51
|
+
enabled: boolean;
|
|
52
|
+
socketPath?: string;
|
|
53
|
+
};
|
|
54
|
+
'claude-code'?: {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
behavior: {
|
|
59
|
+
autoStart: boolean;
|
|
60
|
+
maxOutputLength: number;
|
|
61
|
+
sessionTimeout: number;
|
|
62
|
+
reverseChannelEnabled: boolean;
|
|
63
|
+
reverseChannelMode: 'websocket' | 'filesystem' | 'http';
|
|
64
|
+
};
|
|
65
|
+
logging: {
|
|
66
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
67
|
+
file?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
declare class ConfigManager {
|
|
71
|
+
private static instance;
|
|
72
|
+
private config;
|
|
73
|
+
private constructor();
|
|
74
|
+
static getInstance(): ConfigManager;
|
|
75
|
+
load(config: Partial<BridgeConfig>): void;
|
|
76
|
+
private deepMerge;
|
|
77
|
+
private isObject;
|
|
78
|
+
get(): BridgeConfig;
|
|
79
|
+
getFeishuConfig(): BridgeConfig['feishu'];
|
|
80
|
+
getServerConfig(): BridgeConfig['server'];
|
|
81
|
+
getAdapterConfig(adapter: keyof BridgeConfig['adapters']): {
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
executablePath?: string;
|
|
84
|
+
} | {
|
|
85
|
+
enabled: boolean;
|
|
86
|
+
} | {
|
|
87
|
+
enabled: boolean;
|
|
88
|
+
} | {
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
} | {
|
|
91
|
+
enabled: boolean;
|
|
92
|
+
} | {
|
|
93
|
+
enabled: boolean;
|
|
94
|
+
socketPath?: string;
|
|
95
|
+
} | {
|
|
96
|
+
enabled: boolean;
|
|
97
|
+
} | undefined;
|
|
98
|
+
getBehaviorConfig(): BridgeConfig['behavior'];
|
|
99
|
+
getLoggingConfig(): BridgeConfig['logging'];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
declare class Logger {
|
|
103
|
+
private logger;
|
|
104
|
+
constructor();
|
|
105
|
+
setLevel(level: 'debug' | 'info' | 'warn' | 'error'): void;
|
|
106
|
+
debug(msg: string, ...args: any[]): void;
|
|
107
|
+
info(msg: string, ...args: any[]): void;
|
|
108
|
+
warn(msg: string, ...args: any[]): void;
|
|
109
|
+
error(msg: string | Error, ...args: any[]): void;
|
|
110
|
+
child(bindings: Record<string, any>): Logger;
|
|
111
|
+
}
|
|
112
|
+
declare const logger: Logger;
|
|
113
|
+
|
|
114
|
+
export { ConfigManager, FeishuBridge, logger };
|