// 工作台 config.json 读取工具(唯一入口 + 默认值唯一来源) // 所有工作台脚本(server.js / dsh-data.js / *.cjs)统一通过它读配置, // 调整端口 / DB 名 / 目录只需改 config.json 一处;config 缺失或损坏时回退下方默认值。 'use strict'; const fs = require('node:fs'); const path = require('node:path'); const DEFAULTS = { port: 8900, dbName: 'mcn-plugin.db', outputRoot: 'MCNSkill项目', businessDataDir: ['MCNSkill项目', '三方数据', '红狐数据', '抖音榜单'], extraRoots: [], // 10-08:工作台提交的 AI 任务会话归属哪个工作区 —— 侧边栏分组按会话 cwd 聚合, // cwd 不是已打开过的工作区就会落到「未分组任务」。 // 留空 → 用工作台自身目录(ROOT);填绝对路径 → 会话归到那个工作区(改分组只改这里,不动代码)。 sessionCwd: '', // 09-29 AI 通路配置:backend 决定走哪条链路 // "cli" 本地 CodeBuddy CLI 进程(stdio,无端口;需自备 CODEBUDDY_API_KEY) // "dify" Dify chat-messages(原链路,保留兜底) ai: { backend: 'dify', cli: { path: '', // 留空 → 自动探测(环境变量 CODEBUDDY_CLI_PATH > WorkBuddy 自带 CLI > PATH) model: 'custom:doubao-seed-2-1-pro-260628', apiKey: '', // 一般留空:config.json 是 git 跟踪文件,key 别写这里 authToken: '', // 同上 // 凭据文件(JSON:{"apiKey":"..."} 或 {"authToken":"..."})。 // 留空 → 默认 ~/.workbuddy/mcn-workshop/ai-cli.json(刻意放仓库外,不会被技能同步复制) credentialFile: '', internetEnvironment: 'internal', // 中国版=internal,iOA=ioa,国际版留空 permissionMode: '', timeoutMs: 300000, // 推理开销档位:minimal|low|medium|high|xhigh|max(留空=模型默认)。 // 这是首字延迟的第一大杠杆:reasoning 模型默认档位会让首字等到 60s+。 effort: 'low', // 联网搜索:true → 工具面收敛为 WebSearch+WebFetch(启动快,且模型碰不到文件系统) search: true, tools: '', // 显式覆盖工具白名单:'' = 按 search 推导;'none' = 全禁 strictMcp: true, // 屏蔽宿主 MCP(weixinpay/sheetagent 等) appendSystemPrompt: '', // 追加系统提示 maxTurns: 6, // agent 轮数硬上限(防搜索/工具调用失控跑飞) }, }, }; // 深合并 ai 子对象(浅合并会把缺省子字段整体顶掉) function mergeConfig(base, over) { const out = Object.assign({}, base, over); if (over && typeof over.ai === 'object' && over.ai) { out.ai = Object.assign({}, base.ai, over.ai); if (over.ai.cli && typeof over.ai.cli === 'object') { out.ai.cli = Object.assign({}, base.ai.cli, over.ai.cli); } } return out; } function loadConfig() { try { const p = path.join(__dirname, 'config.json'); if (fs.existsSync(p)) return mergeConfig(DEFAULTS, JSON.parse(fs.readFileSync(p, 'utf8'))); } catch (e) { /* 配置损坏回退默认 */ } return Object.assign({}, DEFAULTS); } module.exports = { DEFAULTS, loadConfig };