重构命令执行逻辑,增强项目状态检查功能。更新InitCommand以支持从MCP和CLI传递工作目录参数,确保路径有效性并提供用户友好的提示。重写多个命令的execute方法,整合项目状态提示,提升用户体验和输出格式的可读性。
This commit is contained in:
@ -166,7 +166,7 @@ class MCPServerCommand {
|
||||
*/
|
||||
convertMCPToCliParams(toolName, mcpArgs) {
|
||||
const paramMapping = {
|
||||
'promptx_init': () => [],
|
||||
'promptx_init': (args) => args.workingDirectory ? [args] : [],
|
||||
|
||||
'promptx_hello': () => [],
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ const { COMMANDS } = require('../../../../constants')
|
||||
const { getGlobalResourceManager } = require('../../resource')
|
||||
const DPMLContentParser = require('../../resource/DPMLContentParser')
|
||||
const SemanticRenderer = require('../../resource/SemanticRenderer')
|
||||
const CurrentProjectManager = require('../../../utils/CurrentProjectManager')
|
||||
const logger = require('../../../utils/logger')
|
||||
|
||||
/**
|
||||
@ -20,6 +21,7 @@ class ActionCommand extends BasePouchCommand {
|
||||
this.resourceManager = getGlobalResourceManager()
|
||||
this.dpmlParser = new DPMLContentParser()
|
||||
this.semanticRenderer = new SemanticRenderer()
|
||||
this.currentProjectManager = new CurrentProjectManager()
|
||||
}
|
||||
|
||||
getPurpose () {
|
||||
@ -27,6 +29,8 @@ class ActionCommand extends BasePouchCommand {
|
||||
}
|
||||
|
||||
async getContent (args) {
|
||||
// 智能提示,不阻断服务
|
||||
|
||||
const [roleId] = args
|
||||
|
||||
if (!roleId) {
|
||||
@ -477,6 +481,65 @@ ${recallContent}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写execute方法以添加项目状态检查
|
||||
*/
|
||||
async execute (args = []) {
|
||||
// 获取项目状态提示
|
||||
const projectPrompt = await this.currentProjectManager.generateTopLevelProjectPrompt('action')
|
||||
|
||||
const purpose = this.getPurpose()
|
||||
const content = await this.getContent(args)
|
||||
const pateoas = await this.getPATEOAS(args)
|
||||
|
||||
return this.formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化带有项目检查的输出
|
||||
*/
|
||||
formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt) {
|
||||
const output = {
|
||||
purpose,
|
||||
content,
|
||||
pateoas,
|
||||
context: this.context,
|
||||
format: this.outputFormat,
|
||||
projectPrompt
|
||||
}
|
||||
|
||||
if (this.outputFormat === 'json') {
|
||||
return output
|
||||
}
|
||||
|
||||
// 人类可读格式
|
||||
return {
|
||||
...output,
|
||||
toString () {
|
||||
const divider = '='.repeat(60)
|
||||
const nextSteps = (pateoas.nextActions || [])
|
||||
.map(action => ` - ${action.name}: ${action.description}\n 方式: ${action.method || action.command || '通过MCP工具'}`)
|
||||
.join('\n')
|
||||
|
||||
return `${projectPrompt}
|
||||
|
||||
${divider}
|
||||
🎯 锦囊目的:${purpose}
|
||||
${divider}
|
||||
|
||||
📜 锦囊内容:
|
||||
${content}
|
||||
|
||||
🔄 下一步行动:
|
||||
${nextSteps}
|
||||
|
||||
📍 当前状态:${pateoas.currentState}
|
||||
${divider}
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ActionCommand
|
||||
|
||||
@ -2,6 +2,7 @@ const BasePouchCommand = require('../BasePouchCommand')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const { getGlobalResourceManager } = require('../../resource')
|
||||
const CurrentProjectManager = require('../../../utils/CurrentProjectManager')
|
||||
const logger = require('../../../utils/logger')
|
||||
|
||||
/**
|
||||
@ -13,6 +14,7 @@ class HelloCommand extends BasePouchCommand {
|
||||
super()
|
||||
// 使用全局单例 ResourceManager
|
||||
this.resourceManager = getGlobalResourceManager()
|
||||
this.currentProjectManager = new CurrentProjectManager()
|
||||
}
|
||||
|
||||
getPurpose () {
|
||||
@ -170,7 +172,7 @@ class HelloCommand extends BasePouchCommand {
|
||||
|
||||
let content = `🤖 **AI专业角色服务清单** (共 ${totalRoles} 个专业角色可供选择)
|
||||
|
||||
> 💡 **重要说明**:以下是可激活的AI专业角色。每个角色都有唯一的ID,可通过MCP工具激活。
|
||||
> 💡 **使用说明**:以下是可激活的AI专业角色。每个角色都有唯一的ID,可通过MCP工具激活。
|
||||
|
||||
|
||||
## 📋 可用角色列表
|
||||
@ -337,6 +339,65 @@ class HelloCommand extends BasePouchCommand {
|
||||
logger.info('❌ RegistryData 不可用')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写execute方法以添加项目状态检查
|
||||
*/
|
||||
async execute (args = []) {
|
||||
// 获取项目状态提示
|
||||
const projectPrompt = await this.currentProjectManager.generateTopLevelProjectPrompt('list')
|
||||
|
||||
const purpose = this.getPurpose()
|
||||
const content = await this.getContent(args)
|
||||
const pateoas = await this.getPATEOAS(args)
|
||||
|
||||
return this.formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化带有项目检查的输出
|
||||
*/
|
||||
formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt) {
|
||||
const output = {
|
||||
purpose,
|
||||
content,
|
||||
pateoas,
|
||||
context: this.context,
|
||||
format: this.outputFormat,
|
||||
projectPrompt
|
||||
}
|
||||
|
||||
if (this.outputFormat === 'json') {
|
||||
return output
|
||||
}
|
||||
|
||||
// 人类可读格式
|
||||
return {
|
||||
...output,
|
||||
toString () {
|
||||
const divider = '='.repeat(60)
|
||||
const nextSteps = (pateoas.nextActions || [])
|
||||
.map(action => ` - ${action.name}: ${action.description}\n 方式: ${action.method || action.command || '通过MCP工具'}`)
|
||||
.join('\n')
|
||||
|
||||
return `${projectPrompt}
|
||||
|
||||
${divider}
|
||||
🎯 锦囊目的:${purpose}
|
||||
${divider}
|
||||
|
||||
📜 锦囊内容:
|
||||
${content}
|
||||
|
||||
🔄 下一步行动:
|
||||
${nextSteps}
|
||||
|
||||
📍 当前状态:${pateoas.currentState}
|
||||
${divider}
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HelloCommand
|
||||
|
||||
@ -4,6 +4,7 @@ const { COMMANDS } = require('../../../../constants')
|
||||
const { getDirectoryService } = require('../../../utils/DirectoryService')
|
||||
const RegistryData = require('../../resource/RegistryData')
|
||||
const ProjectDiscovery = require('../../resource/discovery/ProjectDiscovery')
|
||||
const CurrentProjectManager = require('../../../utils/CurrentProjectManager')
|
||||
const logger = require('../../../utils/logger')
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
@ -19,6 +20,7 @@ class InitCommand extends BasePouchCommand {
|
||||
this.resourceManager = getGlobalResourceManager()
|
||||
this.projectDiscovery = new ProjectDiscovery()
|
||||
this.directoryService = getDirectoryService()
|
||||
this.currentProjectManager = new CurrentProjectManager()
|
||||
}
|
||||
|
||||
getPurpose () {
|
||||
@ -26,18 +28,70 @@ class InitCommand extends BasePouchCommand {
|
||||
}
|
||||
|
||||
async getContent (args) {
|
||||
const [workspacePath = '.'] = args
|
||||
// 获取工作目录参数,支持两种格式:
|
||||
// 1. 来自MCP的对象格式:{ workingDirectory: "path" }
|
||||
// 2. 来自CLI的字符串格式:["path"]
|
||||
let workingDirectory
|
||||
|
||||
if (args && typeof args[0] === 'object' && args[0].workingDirectory) {
|
||||
// MCP格式
|
||||
workingDirectory = args[0].workingDirectory
|
||||
} else if (args && typeof args[0] === 'string') {
|
||||
// CLI格式
|
||||
workingDirectory = args[0]
|
||||
} else if (args && args.length > 0 && args[0]) {
|
||||
// 兜底:直接取第一个参数
|
||||
workingDirectory = args[0]
|
||||
}
|
||||
|
||||
let projectPath
|
||||
|
||||
if (workingDirectory) {
|
||||
// AI提供了工作目录,使用AI提供的路径
|
||||
projectPath = path.resolve(workingDirectory)
|
||||
|
||||
// 验证AI提供的路径是否有效
|
||||
if (!await this.currentProjectManager.validateProjectPath(projectPath)) {
|
||||
return `❌ 提供的工作目录无效: ${projectPath}
|
||||
|
||||
请确保:
|
||||
1. 路径存在且为目录
|
||||
2. 不是用户主目录
|
||||
3. 具有适当的访问权限
|
||||
|
||||
// 构建统一的查找上下文
|
||||
// 对于init命令,我们优先使用当前目录,不向上查找现有.promptx
|
||||
💡 请提供一个有效的项目目录路径。`
|
||||
}
|
||||
|
||||
// 保存AI提供的项目路径
|
||||
await this.currentProjectManager.setCurrentProject(projectPath)
|
||||
|
||||
} else {
|
||||
// AI没有提供工作目录,检查是否已有保存的项目
|
||||
const savedProject = await this.currentProjectManager.getCurrentProject()
|
||||
|
||||
if (savedProject) {
|
||||
// 使用之前保存的项目路径
|
||||
projectPath = savedProject
|
||||
} else {
|
||||
// 没有保存的项目,要求AI提供
|
||||
return `🎯 PromptX需要知道当前项目的工作目录。
|
||||
|
||||
请在调用此工具时提供 workingDirectory 参数,例如:
|
||||
- workingDirectory: "/Users/sean/WorkSpaces/DeepracticeProjects/PromptX"
|
||||
|
||||
💡 你当前工作在哪个项目目录?请提供完整的绝对路径。`
|
||||
}
|
||||
}
|
||||
|
||||
// 构建统一的查找上下文,使用确定的项目路径
|
||||
const context = {
|
||||
startDir: workspacePath === '.' ? process.cwd() : path.resolve(workspacePath),
|
||||
startDir: projectPath,
|
||||
platform: process.platform,
|
||||
avoidUserHome: true, // 特别是Windows环境下避免用户家目录
|
||||
avoidUserHome: true,
|
||||
// init命令特有:优先当前目录,不查找现有.promptx
|
||||
strategies: [
|
||||
'currentWorkingDirectoryIfHasMarkers',
|
||||
'currentWorkingDirectory' // 如果当前目录没有项目标识,就直接使用当前目录
|
||||
'currentWorkingDirectory'
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ const BasePouchCommand = require('../BasePouchCommand')
|
||||
const { getGlobalResourceManager } = require('../../resource')
|
||||
const DPMLContentParser = require('../../resource/DPMLContentParser')
|
||||
const SemanticRenderer = require('../../resource/SemanticRenderer')
|
||||
const CurrentProjectManager = require('../../../utils/CurrentProjectManager')
|
||||
const { COMMANDS } = require('../../../../constants')
|
||||
|
||||
/**
|
||||
@ -16,6 +17,7 @@ class LearnCommand extends BasePouchCommand {
|
||||
this.resourceManager = getGlobalResourceManager()
|
||||
this.dpmlParser = new DPMLContentParser()
|
||||
this.semanticRenderer = new SemanticRenderer()
|
||||
this.currentProjectManager = new CurrentProjectManager()
|
||||
}
|
||||
|
||||
getPurpose () {
|
||||
@ -66,7 +68,7 @@ class LearnCommand extends BasePouchCommand {
|
||||
}
|
||||
}
|
||||
|
||||
return this.formatSuccessResponse(protocol, resourceId, finalContent)
|
||||
return await this.formatSuccessResponse(protocol, resourceId, finalContent)
|
||||
} catch (error) {
|
||||
return this.formatErrorResponse(resourceUrl, error.message)
|
||||
}
|
||||
@ -97,7 +99,7 @@ class LearnCommand extends BasePouchCommand {
|
||||
/**
|
||||
* 格式化成功响应
|
||||
*/
|
||||
formatSuccessResponse (protocol, resourceId, content) {
|
||||
async formatSuccessResponse (protocol, resourceId, content) {
|
||||
const protocolLabels = {
|
||||
thought: '🧠 思维模式',
|
||||
execution: '⚡ 执行模式',
|
||||
@ -274,6 +276,65 @@ ${errorMessage}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写execute方法以添加项目状态检查
|
||||
*/
|
||||
async execute (args = []) {
|
||||
// 获取项目状态提示
|
||||
const projectPrompt = await this.currentProjectManager.generateTopLevelProjectPrompt('learn')
|
||||
|
||||
const purpose = this.getPurpose()
|
||||
const content = await this.getContent(args)
|
||||
const pateoas = await this.getPATEOAS(args)
|
||||
|
||||
return this.formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化带有项目检查的输出
|
||||
*/
|
||||
formatOutputWithProjectCheck(purpose, content, pateoas, projectPrompt) {
|
||||
const output = {
|
||||
purpose,
|
||||
content,
|
||||
pateoas,
|
||||
context: this.context,
|
||||
format: this.outputFormat,
|
||||
projectPrompt
|
||||
}
|
||||
|
||||
if (this.outputFormat === 'json') {
|
||||
return output
|
||||
}
|
||||
|
||||
// 人类可读格式
|
||||
return {
|
||||
...output,
|
||||
toString () {
|
||||
const divider = '='.repeat(60)
|
||||
const nextSteps = (pateoas.nextActions || [])
|
||||
.map(action => ` - ${action.name}: ${action.description}\n 方式: ${action.method || action.command || '通过MCP工具'}`)
|
||||
.join('\n')
|
||||
|
||||
return `${projectPrompt}
|
||||
|
||||
${divider}
|
||||
🎯 锦囊目的:${purpose}
|
||||
${divider}
|
||||
|
||||
📜 锦囊内容:
|
||||
${content}
|
||||
|
||||
🔄 下一步行动:
|
||||
${nextSteps}
|
||||
|
||||
📍 当前状态:${pateoas.currentState}
|
||||
${divider}
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LearnCommand
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const BasePouchCommand = require('../BasePouchCommand')
|
||||
const ResourceManager = require('../../resource/resourceManager')
|
||||
const DPMLContentParser = require('../../resource/DPMLContentParser')
|
||||
const DPMLContentParser = require('../../dpml/DPMLContentParser')
|
||||
const SemanticRenderer = require('../../resource/SemanticRenderer')
|
||||
const { COMMANDS } = require('../../../../constants')
|
||||
|
||||
|
||||
@ -11,12 +11,19 @@ const { z } = require('zod');
|
||||
const TOOL_DEFINITIONS = [
|
||||
{
|
||||
name: 'promptx_init',
|
||||
description: '🎯 [AI专业能力启动器] ⚡ 让你瞬间拥有任何领域的专家级思维和技能 - 一键激活丰富的专业角色库(产品经理/开发者/设计师/营销专家等),获得跨对话记忆能力,30秒内从普通AI变身行业专家。**必须使用场景**:1️⃣系统首次使用时;2️⃣创建新角色后刷新注册表;3️⃣角色激活(action)出错时重新发现角色;4️⃣查看当前版本号。每次需要专业服务时都应该先用这个',
|
||||
description: '🎯 [AI专业能力启动器] ⚡ 让你瞬间拥有任何领域的专家级思维和技能 - 一键激活丰富的专业角色库(产品经理/开发者/设计师/营销专家等),获得跨对话记忆能力,30秒内从普通AI变身行业专家。**必须使用场景**:1️⃣系统首次使用时;2️⃣创建新角色后刷新注册表;3️⃣角色激活(action)出错时重新发现角色;4️⃣查看当前版本号;5️⃣项目路径发生变化时。每次需要专业服务时都应该先用这个',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {}
|
||||
properties: {
|
||||
workingDirectory: {
|
||||
type: 'string',
|
||||
description: '当前项目的工作目录绝对路径。AI应该知道当前工作的项目路径,请提供此参数。'
|
||||
}
|
||||
}
|
||||
},
|
||||
zodSchema: z.object({})
|
||||
zodSchema: z.object({
|
||||
workingDirectory: z.string().optional().describe('当前项目的工作目录绝对路径。AI应该知道当前工作的项目路径,请提供此参数。')
|
||||
})
|
||||
},
|
||||
{
|
||||
name: 'promptx_hello',
|
||||
|
||||
252
src/lib/utils/CurrentProjectManager.js
Normal file
252
src/lib/utils/CurrentProjectManager.js
Normal file
@ -0,0 +1,252 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
/**
|
||||
* 当前项目管理器
|
||||
* 负责管理 ~/.promptx/current-project 文件,持久化当前项目路径
|
||||
*/
|
||||
class CurrentProjectManager {
|
||||
constructor() {
|
||||
this.promptxHomeDir = path.join(os.homedir(), '.promptx')
|
||||
this.currentProjectFile = path.join(this.promptxHomeDir, 'current-project')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前保存的项目路径
|
||||
* @returns {Promise<string|null>} 项目路径或null
|
||||
*/
|
||||
async getCurrentProject() {
|
||||
try {
|
||||
if (await fs.pathExists(this.currentProjectFile)) {
|
||||
const content = await fs.readFile(this.currentProjectFile, 'utf-8')
|
||||
return content.trim()
|
||||
}
|
||||
} catch (error) {
|
||||
// 文件不存在或读取失败,返回null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前项目路径
|
||||
* @param {string} projectPath - 项目绝对路径
|
||||
*/
|
||||
async setCurrentProject(projectPath) {
|
||||
// 确保目录存在
|
||||
await fs.ensureDir(this.promptxHomeDir)
|
||||
|
||||
// 保存项目路径
|
||||
await fs.writeFile(this.currentProjectFile, projectPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查项目一致性,生成AI提示信息
|
||||
* @returns {Promise<Object>} 项目状态和AI提示信息
|
||||
*/
|
||||
async checkProjectConsistency() {
|
||||
const savedProject = await this.getCurrentProject()
|
||||
|
||||
if (savedProject) {
|
||||
return {
|
||||
hasSaved: true,
|
||||
savedPath: savedProject,
|
||||
aiMessage: `📍 PromptX当前设置的项目路径: ${savedProject}`,
|
||||
aiInstruction: '如果这不是你当前工作的项目路径,请调用 promptx_init 工具并提供正确的 workingDirectory 参数来更新。'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
hasSaved: false,
|
||||
savedPath: null,
|
||||
aiMessage: '🎯 PromptX尚未设置项目路径',
|
||||
aiInstruction: '请先调用 promptx_init 工具并提供 workingDirectory 参数来设置当前项目路径。'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成顶层项目状态提示信息(用于分隔线后的独立层级显示)
|
||||
* @param {string} contextType - 上下文类型:'list'(角色列表), 'action'(角色激活), 'learn'(学习资源)
|
||||
* @returns {string} 格式化的顶层项目状态提示
|
||||
*/
|
||||
async generateTopLevelProjectPrompt(contextType = 'list') {
|
||||
const projectCheck = await this.checkProjectConsistency()
|
||||
|
||||
if (projectCheck.hasSaved) {
|
||||
// 已设置项目路径的提示
|
||||
switch (contextType) {
|
||||
case 'action':
|
||||
return `🛑 **项目环境强制验证** 🛑
|
||||
${projectCheck.aiMessage}
|
||||
|
||||
⚠️ **执行前必须确认**:
|
||||
1. 上述路径是否为你当前工作的项目?
|
||||
2. 如不一致,立即停止所有操作
|
||||
3. 使用 \`promptx_init\` 更新正确路径
|
||||
4. 验证通过后才能继续角色激活
|
||||
|
||||
💥 **严重警告**:在错误项目路径下操作将导致不可预知的错误!`
|
||||
|
||||
case 'learn':
|
||||
return `🛑 **学习环境强制验证** 🛑
|
||||
${projectCheck.aiMessage}
|
||||
|
||||
⚠️ **学习前必须确认**:
|
||||
1. 确保在正确的项目环境中学习
|
||||
2. 错误环境将导致知识关联失效
|
||||
3. 如需切换项目,立即停止并更新
|
||||
|
||||
💥 **严重警告**:项目环境不匹配将影响学习效果!`
|
||||
|
||||
case 'list':
|
||||
default:
|
||||
return `🛑 **项目环境强制验证** 🛑
|
||||
${projectCheck.aiMessage}
|
||||
|
||||
⚠️ **使用前必须确认**:
|
||||
1. 立即确认上述路径是否为当前工作项目
|
||||
2. 如不一致,禁止继续任何操作
|
||||
3. 必须使用 \`promptx_init\` 更新正确路径
|
||||
4. 验证通过后才能使用角色服务
|
||||
|
||||
💥 **严重警告**:错误的项目环境将导致服务异常!`
|
||||
}
|
||||
} else {
|
||||
// 未设置项目路径的提示
|
||||
return `🛑 **致命错误:项目环境未初始化** 🛑
|
||||
${projectCheck.aiMessage}
|
||||
|
||||
💢 **立即执行**:
|
||||
1. 停止当前操作
|
||||
2. 调用 \`promptx_init\` 工具初始化环境
|
||||
3. 提供正确的 workingDirectory 参数
|
||||
4. 初始化完成后重新开始
|
||||
|
||||
⛔ **严禁继续**:未初始化环境中的任何操作都可能失败!`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成统一的项目状态提示信息
|
||||
* @param {string} contextType - 上下文类型:'list'(角色列表), 'action'(角色激活), 'learn'(学习资源)
|
||||
* @returns {string} 格式化的项目状态提示
|
||||
*/
|
||||
async generateProjectStatusPrompt(contextType = 'list') {
|
||||
const projectCheck = await this.checkProjectConsistency()
|
||||
|
||||
if (projectCheck.hasSaved) {
|
||||
// 已设置项目路径的提示
|
||||
switch (contextType) {
|
||||
case 'action':
|
||||
return `\n🛑 **执行前置检查**
|
||||
---
|
||||
## 📍 项目环境验证
|
||||
✅ ${projectCheck.aiMessage}
|
||||
|
||||
⚠️ **强制验证**:
|
||||
1. 请确认这是你当前工作的项目路径
|
||||
2. 如不一致,必须立即停止操作
|
||||
3. 使用 \`promptx_init\` 更新正确路径
|
||||
4. 仅当路径正确才能继续操作
|
||||
|
||||
💢 **违规警告**:
|
||||
- 在错误的项目路径下执行操作将导致不可预知的错误
|
||||
- 可能影响项目配置和资源完整性
|
||||
---\n`
|
||||
|
||||
case 'learn':
|
||||
return `\n🛑 **执行前置检查**
|
||||
---
|
||||
## 📍 学习环境验证
|
||||
✅ ${projectCheck.aiMessage}
|
||||
|
||||
⚠️ **强制验证**:
|
||||
1. 确保在正确的项目环境中学习
|
||||
2. 错误的项目环境将导致知识关联失效
|
||||
3. 如需切换项目,请立即停止并更新
|
||||
|
||||
💢 **违规警告**:
|
||||
- 项目环境不匹配将影响学习效果
|
||||
- 可能造成知识体系混乱
|
||||
---\n`
|
||||
|
||||
case 'list':
|
||||
default:
|
||||
return `🛑 **执行前置检查**
|
||||
|
||||
## 📍 项目环境强制验证
|
||||
✅ ${projectCheck.aiMessage}
|
||||
|
||||
⚠️ **检查步骤**:
|
||||
1. 立即确认上述路径是否为当前工作项目
|
||||
2. 如不一致,禁止继续任何操作
|
||||
3. 必须使用 \`promptx_init\` 更新正确路径
|
||||
4. 验证通过后才能使用角色服务
|
||||
|
||||
💢 **违规警告**:
|
||||
- 错误的项目环境将导致角色服务异常
|
||||
- 可能影响项目资源和配置完整性
|
||||
- 禁止在未经验证的环境中继续操作
|
||||
|
||||
💡 **操作指南**:
|
||||
1. 一致 → 继续使用角色服务
|
||||
2. 不一致 → 立即停止并更新路径
|
||||
3. 不确定 → 先确认再操作`
|
||||
}
|
||||
} else {
|
||||
// 未设置项目路径的提示
|
||||
return `🛑 **执行终止**
|
||||
|
||||
## ⚠️ 致命错误:项目环境未初始化
|
||||
${projectCheck.aiMessage}
|
||||
|
||||
💢 **强制要求**:
|
||||
1. 立即停止当前操作
|
||||
2. 调用 \`promptx_init\` 工具初始化环境:
|
||||
\`\`\`
|
||||
workingDirectory: "你当前工作的项目完整路径"
|
||||
\`\`\`
|
||||
3. 初始化完成后重新开始操作
|
||||
|
||||
⛔ **禁止事项**:
|
||||
- 禁止在未初始化环境中执行任何操作
|
||||
- 禁止跳过环境初始化步骤
|
||||
- 禁止使用可能不正确的项目路径
|
||||
|
||||
💥 **违规后果**:
|
||||
- 操作将失败或产生不可预知的错误
|
||||
- 可能破坏项目配置和资源完整性
|
||||
- 导致角色服务异常或失效`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证路径是否为有效的项目目录
|
||||
* @param {string} projectPath - 要验证的路径
|
||||
* @returns {Promise<boolean>} 是否为有效项目目录
|
||||
*/
|
||||
async validateProjectPath(projectPath) {
|
||||
try {
|
||||
// 基础检查:路径存在且为目录
|
||||
const stat = await fs.stat(projectPath)
|
||||
if (!stat.isDirectory()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 简单检查:避免明显错误的路径
|
||||
const resolved = path.resolve(projectPath)
|
||||
const homeDir = os.homedir()
|
||||
|
||||
// 不允许是用户主目录
|
||||
if (resolved === homeDir) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CurrentProjectManager
|
||||
Reference in New Issue
Block a user