/** * PromptX 系统常量配置 * 统一管理命令格式、路径等配置信息 */ const PromptXConfig = require('./lib/utils/promptxConfig') // 缓存配置实例和命令前缀 let _config = null let _cachedPrefix = null /** * 获取配置实例 */ function getConfig() { if (!_config) { _config = new PromptXConfig() } return _config } /** * 动态检测命令前缀 * 优先级:环境变量 > npm环境变量检测 > 配置文件 > 默认值 */ function detectCommandPrefix() { // 在 init 过程中,优先使用实时检测而不是缓存 const isInitProcess = process.argv.includes('init') // 如果不是 init 过程且有缓存,返回缓存结果 if (!isInitProcess && _cachedPrefix) { return _cachedPrefix } // 1. 环境变量优先(用于测试和自定义) if (process.env.DPML_COMMAND_PREFIX) { _cachedPrefix = process.env.DPML_COMMAND_PREFIX return _cachedPrefix } // 2. npm环境变量检测(实时检测,优先级提高) if (process.env.npm_execpath?.includes('npx') || process.env.npm_config_user_agent?.includes('npx')) { _cachedPrefix = 'npx -y dpml-prompt' return _cachedPrefix } // 3. 如果不是 init 过程,尝试读取配置文件 if (!isInitProcess) { try { const config = getConfig() const configPath = config.getPath('command-prefix') const fs = require('fs') if (fs.existsSync(configPath)) { const savedPrefix = fs.readFileSync(configPath, 'utf8').trim() if (savedPrefix) { _cachedPrefix = savedPrefix return _cachedPrefix } } } catch (error) { // 忽略读取错误,继续下一步检测 } } // 4. 默认值 _cachedPrefix = 'npx -y dpml-prompt' return _cachedPrefix } /** * 智能推测用户使用的命令前缀 * 从 process.argv 中提取 init 之前的所有部分作为命令前缀 */ function reconstructCommandPrefix() { try { // 优先检查环境变量,因为通过 npx 执行时环境变量是最可靠的 if (process.env.npm_execpath?.includes('npx') || process.env.npm_config_user_agent?.includes('npx')) { return 'npx -y dpml-prompt' } // 从 process.argv 中找到 init 命令的位置 const initIndex = process.argv.findIndex(arg => arg === 'init') if (initIndex > 0) { // 提取 init 之前的所有参数,跳过 node 可执行文件路径 const prefixParts = process.argv.slice(1, initIndex) if (prefixParts.length > 0) { // 检查脚本路径是否包含典型的开发模式特征 const firstPart = prefixParts[0] if (firstPart.includes('promptx.js') || firstPart.includes('cli.js') || firstPart.includes('bin/') || firstPart.includes('src/bin/')) { // 开发模式,使用包名 return 'dpml-prompt' } // 直接使用检测到的前缀 return prefixParts.join(' ') } } // 如果找不到 init 或解析失败,使用环境变量判断 if (process.env.npm_execpath && process.env.npm_execpath.includes('npx')) { return 'npx -y dpml-prompt' } return 'dpml-prompt' } catch (error) { // 解析失败时的回退逻辑 return 'dpml-prompt' } } /** * 保存命令前缀到配置文件 * 在init命令中调用 */ async function saveCommandPrefix() { try { // 先清除缓存,确保使用最新的检测结果 _cachedPrefix = null // 直接使用检测到的前缀,不再通过 reconstructCommandPrefix const actualPrefix = detectCommandPrefix() const config = getConfig() await config.writeText('command-prefix', actualPrefix) // 保存后更新缓存 _cachedPrefix = actualPrefix return actualPrefix } catch (error) { console.warn('保存命令前缀失败:', error.message) return null } } // 动态生成命令常量(函数式) function getCommands() { const prefix = detectCommandPrefix() return { INIT: `${prefix} init`, HELLO: `${prefix} hello`, ACTION: `${prefix} action`, LEARN: `${prefix} learn`, RECALL: `${prefix} recall`, REMEMBER: `${prefix} remember`, HELP: `${prefix} help` } } // 带参数的命令构建函数 function getBuildCommand() { const prefix = detectCommandPrefix() return { action: (roleId) => `${prefix} action ${roleId}`, learn: (resource) => `${prefix} learn ${resource}`, recall: (query = '') => `${prefix} recall${query ? ' ' + query : ''}`, remember: (content = '') => `${prefix} remember${content !== '' ? ' "' + content + '"' : ' '}` } } // 为了向后兼容,保留原有的静态导出方式 // 但实际上是动态计算的 const COMMANDS = new Proxy({}, { get(target, prop) { return getCommands()[prop] } }) const buildCommand = new Proxy({}, { get(target, prop) { return getBuildCommand()[prop] } }) // 系统路径配置(静态) const PATHS = { POUCH_DIR: '.promptx', MEMORY_DIR: '.promptx/memory', STATE_FILE: '.promptx/pouch.json', MEMORY_FILE: '.promptx/memory/declarative.md' } // 版本信息 const VERSION = '0.0.1' // 系统状态 const STATES = { INITIALIZED: 'initialized', ROLE_DISCOVERY: 'role_discovery', ACTION_PLAN_GENERATED: 'action_plan_generated', LEARNED_ROLE: 'learned_role', MEMORY_SAVED: 'memory_saved', RECALL_WAITING: 'recall-waiting' } /** * 清除缓存(主要用于测试) */ function clearCache() { _cachedPrefix = null _config = null } // 导出 module.exports = { // 新的函数式API(推荐) getCommands, getBuildCommand, detectCommandPrefix, reconstructCommandPrefix, saveCommandPrefix, clearCache, // 向后兼容的静态API COMMANDS, buildCommand, // 其他静态常量 PATHS, VERSION, STATES }