UNPKG

cw-ai-backlog

Version:

AI-powered tool to generate backlog items from meeting documents and output to Google Sheets

216 lines (183 loc) 6.84 kB
const fs = require('fs-extra'); const path = require('path'); const os = require('os'); const chalk = require('chalk'); /** * 顯示配置檔案位置資訊 */ async function showConfigPaths() { console.log(chalk.blue('\n📁 配置檔案位置資訊\n')); const configPaths = [ { path: './ai_backlog.config.js', description: '當前目錄配置檔案', priority: 1 }, { path: path.join(os.homedir(), '.ai_backlog.config.js'), description: '全域配置檔案(推薦)', priority: 2 }, { path: path.join(os.homedir(), '.config', 'ai-backlog', 'config.js'), description: 'XDG 標準配置檔案', priority: 3 } ]; console.log(chalk.yellow('查找順序(優先度由高到低):\n')); let activeConfigFound = false; for (const config of configPaths) { const exists = await fs.pathExists(config.path); const fullPath = path.resolve(config.path); if (exists && !activeConfigFound) { console.log(chalk.green(`✅ ${config.priority}. ${config.description}`)); console.log(chalk.green(` 路徑: ${fullPath}`)); console.log(chalk.green(` 狀態: 目前使用中\n`)); activeConfigFound = true; } else if (exists) { console.log(chalk.gray(`📄 ${config.priority}. ${config.description}`)); console.log(chalk.gray(` 路徑: ${fullPath}`)); console.log(chalk.gray(` 狀態: 存在但未使用\n`)); } else { console.log(chalk.dim(`⭕ ${config.priority}. ${config.description}`)); console.log(chalk.dim(` 路徑: ${fullPath}`)); console.log(chalk.dim(` 狀態: 不存在\n`)); } } if (!activeConfigFound) { console.log(chalk.red('❌ 未找到任何配置檔案')); console.log(chalk.yellow('💡 執行以下指令建立配置檔案:')); console.log(chalk.cyan(' ai-backlog example.txt')); console.log(''); } console.log(chalk.blue('📝 快速編輯配置檔案:')); const globalConfigPath = path.join(os.homedir(), '.ai_backlog.config.js'); console.log(chalk.cyan(` nano ${globalConfigPath}`)); console.log(chalk.cyan(` code ${globalConfigPath}`)); console.log(''); } /** * 快速編輯全域配置檔案 */ async function editGlobalConfig() { const globalConfigPath = path.join(os.homedir(), '.ai_backlog.config.js'); // 如果配置檔案不存在,先建立它 if (!(await fs.pathExists(globalConfigPath))) { console.log(chalk.yellow('全域配置檔案不存在,正在建立...')); await createExampleConfig(globalConfigPath); console.log(chalk.green(`✅ 已建立配置檔案: ${globalConfigPath}`)); } console.log(chalk.blue('\n📝 開啟配置檔案進行編輯...\n')); console.log(chalk.cyan(`檔案位置: ${globalConfigPath}`)); // 嘗試使用不同的編輯器開啟 const { spawn } = require('child_process'); // 優先使用 VS Code try { const code = spawn('code', [globalConfigPath], { stdio: 'inherit', detached: true }); code.on('error', () => { // 如果 VS Code 不存在,嘗試使用系統預設編輯器 console.log(chalk.yellow('VS Code 未找到,請手動開啟配置檔案:')); console.log(chalk.cyan(`nano ${globalConfigPath}`)); console.log(chalk.cyan(`vim ${globalConfigPath}`)); console.log(chalk.cyan(`open ${globalConfigPath}`)); }); code.unref(); console.log(chalk.green('✅ 配置檔案已在 VS Code 中開啟')); } catch (error) { console.log(chalk.yellow('請手動開啟配置檔案:')); console.log(chalk.cyan(`nano ${globalConfigPath}`)); console.log(chalk.cyan(`vim ${globalConfigPath}`)); console.log(chalk.cyan(`open ${globalConfigPath}`)); } } /** * 載入配置檔案 * @param {string} configPath 配置檔案路徑 * @returns {Object} 配置物件 */ async function loadConfig(configPath) { const defaultConfig = { apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4.1-nano', keepPhrases: [], customPrompt: [], googleCredentials: null, googleSheetUrl: null, maxTokens: 4000, temperature: 0.1 }; try { // 如果指定了明確的配置路徑,直接使用 if (configPath !== './ai_backlog.config.js') { if (await fs.pathExists(configPath)) { const userConfig = require(path.resolve(configPath)); return { ...defaultConfig, ...userConfig }; } else { throw new Error(`指定的配置檔案不存在: ${configPath}`); } } // 按優先順序查找配置檔案 const configPaths = [ './ai_backlog.config.js', // 當前目錄 path.join(os.homedir(), '.ai_backlog.config.js'), // 使用者家目錄 path.join(os.homedir(), '.config', 'ai-backlog', 'config.js') // XDG 標準目錄 ]; for (const configFile of configPaths) { if (await fs.pathExists(configFile)) { const userConfig = require(path.resolve(configFile)); // 不在這裡 console.log,讓 CLI 處理 spinner return { ...defaultConfig, ...userConfig }; } } // 如果沒有找到配置檔案,提示使用者執行互動式設定 console.log(chalk.yellow('\n⚠️ 未找到配置檔案')); console.log(chalk.blue('💡 建議執行互動式設定來建立配置檔案:')); console.log(chalk.cyan(' ai-backlog --setup')); console.log(''); throw new Error('請先執行 ai-backlog --setup 來建立配置檔案'); } catch (error) { throw error; } } /** * 創建範例配置檔案 * @param {string} configPath 配置檔案路徑 */ async function createExampleConfig(configPath) { const exampleConfig = `module.exports = { // OpenAI API Key (必填) apiKey: process.env.OPENAI_API_KEY || '你的-openai-api-key', // 使用的模型 model: 'gpt-4.1-nano', // 或 'gpt-4-turbo', 'gpt-3.5-turbo' // 保留字 - 在分析時需要特別注意的詞彙 keepPhrases: [ '使用者體驗', '效能優化', '安全性', // 新增更多保留字... ], // 自訂 prompt 指示 - 會加入到 AI 分析指令中 customPrompt: [ // '只分析紫色標記的內容', // '專注於特定標題以下的內容', // '忽略草稿或註解部分', // 新增您的自訂指示... ], // Google Docs API 憑證檔案路徑 (可選) googleCredentials: null, // './path/to/credentials.json' // Google Sheets URL (必填 - 用於輸出 backlog) googleSheetUrl: null, // 'https://docs.google.com/spreadsheets/d/your-sheet-id/edit' // AI 參數設定 maxTokens: 4000, temperature: 0.1 };`; await fs.writeFile(configPath, exampleConfig); } module.exports = { loadConfig, showConfigPaths, editGlobalConfig };