更新.gitignore以排除.kilocode目录;在DirectoryLocator.js中增强目录查找策略的注释,增加对IDE环境变量的检测逻辑,优化路径回退策略;在DirectoryService.js中添加IDE检测信息和路径配置建议,提升用户体验和环境配置的灵活性。
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -76,3 +76,4 @@ temp/
|
|||||||
*.orig
|
*.orig
|
||||||
.husky/_
|
.husky/_
|
||||||
|
|
||||||
|
.kilocode/
|
||||||
|
|||||||
@ -90,13 +90,13 @@ class ProjectRootLocator extends DirectoryLocator {
|
|||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super(options)
|
super(options)
|
||||||
|
|
||||||
// 可配置的查找策略优先级
|
// 可配置的查找策略优先级(按可靠性和准确性排序)
|
||||||
this.strategies = options.strategies || [
|
this.strategies = options.strategies || [
|
||||||
'existingPromptxDirectory',
|
'existingPromptxDirectory', // 1. 现有.promptx目录(最可靠的项目标识)
|
||||||
'currentWorkingDirectoryIfHasMarkers',
|
'packageJsonDirectory', // 2. 向上查找项目标识文件(最准确的项目边界)
|
||||||
'packageJsonDirectory',
|
'gitRootDirectory', // 3. Git根目录(通用可靠)
|
||||||
'gitRootDirectory',
|
'currentWorkingDirectoryIfHasMarkers', // 4. 当前目录项目标识(降级策略)
|
||||||
'currentWorkingDirectory'
|
'currentWorkingDirectory' // 5. 纯当前目录(最后回退)
|
||||||
]
|
]
|
||||||
|
|
||||||
// 项目标识文件
|
// 项目标识文件
|
||||||
@ -284,19 +284,19 @@ class PromptXWorkspaceLocator extends DirectoryLocator {
|
|||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略1:IDE环境变量
|
// 策略1:IDE环境变量(最高优先级 - 用户/IDE明确指定)
|
||||||
const workspaceFromIDE = await this._fromIDEEnvironment()
|
const workspaceFromIDE = await this._fromIDEEnvironment()
|
||||||
if (workspaceFromIDE) {
|
if (workspaceFromIDE) {
|
||||||
return this.setCached(cacheKey, workspaceFromIDE)
|
return this.setCached(cacheKey, workspaceFromIDE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略2:PromptX专用环境变量
|
// 策略2:PromptX专用环境变量(用户手动配置)
|
||||||
const workspaceFromEnv = await this._fromPromptXEnvironment()
|
const workspaceFromEnv = await this._fromPromptXEnvironment()
|
||||||
if (workspaceFromEnv) {
|
if (workspaceFromEnv) {
|
||||||
return this.setCached(cacheKey, workspaceFromEnv)
|
return this.setCached(cacheKey, workspaceFromEnv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略3:如果上下文指定了特定策略(如init命令),直接使用项目根目录
|
// 策略3:特定上下文策略(如init命令的强制指定)
|
||||||
if (context.strategies) {
|
if (context.strategies) {
|
||||||
const workspaceFromProject = await this._fromProjectRoot(context)
|
const workspaceFromProject = await this._fromProjectRoot(context)
|
||||||
if (workspaceFromProject) {
|
if (workspaceFromProject) {
|
||||||
@ -304,40 +304,103 @@ class PromptXWorkspaceLocator extends DirectoryLocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略4:现有.promptx目录
|
// 策略4:现有.promptx目录(已初始化的项目)
|
||||||
const workspaceFromExisting = await this._fromExistingDirectory(context.startDir)
|
const workspaceFromExisting = await this._fromExistingDirectory(context.startDir)
|
||||||
if (workspaceFromExisting) {
|
if (workspaceFromExisting) {
|
||||||
return this.setCached(cacheKey, workspaceFromExisting)
|
return this.setCached(cacheKey, workspaceFromExisting)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略5:项目根目录
|
// 策略5:项目根目录(基于项目结构推断)
|
||||||
const workspaceFromProject = await this._fromProjectRoot(context)
|
const workspaceFromProject = await this._fromProjectRoot(context)
|
||||||
if (workspaceFromProject) {
|
if (workspaceFromProject) {
|
||||||
return this.setCached(cacheKey, workspaceFromProject)
|
return this.setCached(cacheKey, workspaceFromProject)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 策略6:回退到当前目录
|
// 策略6:智能回退策略(兜底方案)
|
||||||
return this.setCached(cacheKey, context.startDir || process.cwd())
|
return this.setCached(cacheKey, await this._getSmartFallback(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从IDE环境变量获取
|
* 从IDE环境变量获取(支持多种IDE)
|
||||||
*/
|
*/
|
||||||
async _fromIDEEnvironment() {
|
async _fromIDEEnvironment() {
|
||||||
const workspaceFolders = process.env.WORKSPACE_FOLDER_PATHS
|
// IDE环境变量检测策略(按优先级排序)
|
||||||
if (workspaceFolders) {
|
const ideStrategies = [
|
||||||
|
// Claude IDE (现有格式)
|
||||||
|
{
|
||||||
|
name: 'Claude IDE',
|
||||||
|
vars: ['WORKSPACE_FOLDER_PATHS'],
|
||||||
|
parse: (value) => {
|
||||||
try {
|
try {
|
||||||
const folders = JSON.parse(workspaceFolders)
|
const folders = JSON.parse(value)
|
||||||
if (Array.isArray(folders) && folders.length > 0) {
|
return Array.isArray(folders) && folders.length > 0 ? folders[0] : null
|
||||||
const firstFolder = folders[0]
|
|
||||||
if (await this.isValidDirectory(firstFolder)) {
|
|
||||||
return firstFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
// 忽略解析错误
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// VSCode
|
||||||
|
{
|
||||||
|
name: 'VSCode',
|
||||||
|
vars: ['VSCODE_WORKSPACE_FOLDER', 'VSCODE_CWD'],
|
||||||
|
parse: (value) => value
|
||||||
|
},
|
||||||
|
|
||||||
|
// IntelliJ IDEA / WebStorm / PhpStorm
|
||||||
|
{
|
||||||
|
name: 'JetBrains IDEs',
|
||||||
|
vars: ['PROJECT_ROOT', 'IDEA_INITIAL_DIRECTORY', 'WEBSTORM_PROJECT_PATH'],
|
||||||
|
parse: (value) => value
|
||||||
|
},
|
||||||
|
|
||||||
|
// Sublime Text
|
||||||
|
{
|
||||||
|
name: 'Sublime Text',
|
||||||
|
vars: ['SUBLIME_PROJECT_PATH', 'SUBL_PROJECT_DIR'],
|
||||||
|
parse: (value) => value
|
||||||
|
},
|
||||||
|
|
||||||
|
// Atom
|
||||||
|
{
|
||||||
|
name: 'Atom',
|
||||||
|
vars: ['ATOM_PROJECT_PATH', 'ATOM_HOME_PROJECT'],
|
||||||
|
parse: (value) => value
|
||||||
|
},
|
||||||
|
|
||||||
|
// Vim/Neovim
|
||||||
|
{
|
||||||
|
name: 'Vim/Neovim',
|
||||||
|
vars: ['VIM_PROJECT_ROOT', 'NVIM_PROJECT_ROOT'],
|
||||||
|
parse: (value) => value
|
||||||
|
},
|
||||||
|
|
||||||
|
// 通用工作目录
|
||||||
|
{
|
||||||
|
name: 'Generic',
|
||||||
|
vars: ['WORKSPACE_ROOT', 'PROJECT_DIR', 'WORKING_DIRECTORY'],
|
||||||
|
parse: (value) => value
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 按策略逐一检测
|
||||||
|
for (const strategy of ideStrategies) {
|
||||||
|
for (const varName of strategy.vars) {
|
||||||
|
const envValue = process.env[varName]
|
||||||
|
if (envValue && envValue.trim() !== '') {
|
||||||
|
const parsedPath = strategy.parse(envValue.trim())
|
||||||
|
if (parsedPath) {
|
||||||
|
const normalizedPath = this.normalizePath(this.expandHome(parsedPath))
|
||||||
|
if (normalizedPath && await this.isValidDirectory(normalizedPath)) {
|
||||||
|
// 记录检测到的IDE类型(用于调试)
|
||||||
|
this._detectedIDE = strategy.name
|
||||||
|
return normalizedPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +433,95 @@ class PromptXWorkspaceLocator extends DirectoryLocator {
|
|||||||
const projectRoot = await this.projectRootLocator.locate(context)
|
const projectRoot = await this.projectRootLocator.locate(context)
|
||||||
return projectRoot
|
return projectRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 智能回退策略
|
||||||
|
*/
|
||||||
|
async _getSmartFallback(context) {
|
||||||
|
// 1. 尝试从命令行参数推断
|
||||||
|
const argPath = await this._fromProcessArguments()
|
||||||
|
if (argPath && await this.isValidDirectory(argPath)) {
|
||||||
|
return argPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 尝试从进程的工作目录
|
||||||
|
const processCwd = process.cwd()
|
||||||
|
if (await this.isValidDirectory(processCwd)) {
|
||||||
|
return processCwd
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 最后回退到用户主目录
|
||||||
|
return os.homedir()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从进程参数推断项目路径
|
||||||
|
*/
|
||||||
|
async _fromProcessArguments() {
|
||||||
|
const args = process.argv
|
||||||
|
|
||||||
|
// 查找可能的路径参数
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
const arg = args[i]
|
||||||
|
|
||||||
|
// 查找 --project-path 或类似参数
|
||||||
|
if (arg.startsWith('--project-path=')) {
|
||||||
|
return arg.split('=')[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg === '--project-path' && i + 1 < args.length) {
|
||||||
|
return args[i + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找 --cwd 参数
|
||||||
|
if (arg.startsWith('--cwd=')) {
|
||||||
|
return arg.split('=')[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg === '--cwd' && i + 1 < args.length) {
|
||||||
|
return args[i + 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取检测调试信息
|
||||||
|
*/
|
||||||
|
getDetectionInfo() {
|
||||||
|
return {
|
||||||
|
detectedIDE: this._detectedIDE || 'Unknown',
|
||||||
|
availableEnvVars: this._getAvailableEnvVars(),
|
||||||
|
platform: process.platform,
|
||||||
|
cwd: process.cwd(),
|
||||||
|
args: process.argv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取可用的环境变量
|
||||||
|
*/
|
||||||
|
_getAvailableEnvVars() {
|
||||||
|
const relevantVars = [
|
||||||
|
'WORKSPACE_FOLDER_PATHS', 'VSCODE_WORKSPACE_FOLDER', 'VSCODE_CWD',
|
||||||
|
'PROJECT_ROOT', 'IDEA_INITIAL_DIRECTORY', 'WEBSTORM_PROJECT_PATH',
|
||||||
|
'SUBLIME_PROJECT_PATH', 'SUBL_PROJECT_DIR',
|
||||||
|
'ATOM_PROJECT_PATH', 'ATOM_HOME_PROJECT',
|
||||||
|
'VIM_PROJECT_ROOT', 'NVIM_PROJECT_ROOT',
|
||||||
|
'WORKSPACE_ROOT', 'PROJECT_DIR', 'WORKING_DIRECTORY',
|
||||||
|
'PROMPTX_WORKSPACE', 'PWD'
|
||||||
|
]
|
||||||
|
|
||||||
|
const available = {}
|
||||||
|
for (const varName of relevantVars) {
|
||||||
|
if (process.env[varName]) {
|
||||||
|
available[varName] = process.env[varName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return available
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -150,15 +150,30 @@ class DirectoryService {
|
|||||||
const workspace = await this.getWorkspace(context)
|
const workspace = await this.getWorkspace(context)
|
||||||
const promptxDir = await this.getPromptXDirectory(context)
|
const promptxDir = await this.getPromptXDirectory(context)
|
||||||
|
|
||||||
|
// 获取IDE检测信息
|
||||||
|
const ideDetectionInfo = this.workspaceLocator?.getDetectionInfo() || {}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
projectRoot,
|
projectRoot,
|
||||||
workspace,
|
workspace,
|
||||||
promptxDirectory: promptxDir,
|
promptxDirectory: promptxDir,
|
||||||
isSame: projectRoot === workspace,
|
isSame: projectRoot === workspace,
|
||||||
|
ideDetection: {
|
||||||
|
detectedIDE: ideDetectionInfo.detectedIDE,
|
||||||
|
availableEnvVars: ideDetectionInfo.availableEnvVars,
|
||||||
|
cwd: process.cwd(),
|
||||||
|
args: process.argv.slice(2) // 隐藏node和脚本路径
|
||||||
|
},
|
||||||
environment: {
|
environment: {
|
||||||
|
// 主要IDE环境变量
|
||||||
WORKSPACE_FOLDER_PATHS: process.env.WORKSPACE_FOLDER_PATHS,
|
WORKSPACE_FOLDER_PATHS: process.env.WORKSPACE_FOLDER_PATHS,
|
||||||
|
VSCODE_WORKSPACE_FOLDER: process.env.VSCODE_WORKSPACE_FOLDER,
|
||||||
|
PROJECT_ROOT: process.env.PROJECT_ROOT,
|
||||||
|
SUBLIME_PROJECT_PATH: process.env.SUBLIME_PROJECT_PATH,
|
||||||
|
// PromptX专用
|
||||||
PROMPTX_WORKSPACE: process.env.PROMPTX_WORKSPACE,
|
PROMPTX_WORKSPACE: process.env.PROMPTX_WORKSPACE,
|
||||||
|
// 系统环境
|
||||||
PWD: process.env.PWD,
|
PWD: process.env.PWD,
|
||||||
NODE_ENV: process.env.NODE_ENV
|
NODE_ENV: process.env.NODE_ENV
|
||||||
},
|
},
|
||||||
@ -166,8 +181,42 @@ class DirectoryService {
|
|||||||
cache: {
|
cache: {
|
||||||
projectRootCacheSize: this.projectRootLocator?.cache.size || 0,
|
projectRootCacheSize: this.projectRootLocator?.cache.size || 0,
|
||||||
workspaceCacheSize: this.workspaceLocator?.cache.size || 0
|
workspaceCacheSize: this.workspaceLocator?.cache.size || 0
|
||||||
|
},
|
||||||
|
recommendations: this._getPathRecommendations(ideDetectionInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路径配置建议
|
||||||
|
*/
|
||||||
|
_getPathRecommendations(ideDetectionInfo = {}) {
|
||||||
|
const recommendations = []
|
||||||
|
|
||||||
|
if (!ideDetectionInfo.detectedIDE || ideDetectionInfo.detectedIDE === 'Unknown') {
|
||||||
|
recommendations.push({
|
||||||
|
type: 'env_var',
|
||||||
|
message: '未检测到IDE环境变量,建议设置项目路径环境变量',
|
||||||
|
suggestions: [
|
||||||
|
'export PROMPTX_WORKSPACE="/path/to/your/project"',
|
||||||
|
'export PROJECT_ROOT="/path/to/your/project"',
|
||||||
|
'export WORKSPACE_ROOT="/path/to/your/project"'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ideDetectionInfo.availableEnvVars || Object.keys(ideDetectionInfo.availableEnvVars).length === 0) {
|
||||||
|
recommendations.push({
|
||||||
|
type: 'manual_config',
|
||||||
|
message: '建议在IDE中配置MCP工作目录',
|
||||||
|
suggestions: [
|
||||||
|
'VSCode: 在settings.json中设置workspace.folders',
|
||||||
|
'IntelliJ: 在Run Configuration中设置Working directory',
|
||||||
|
'Claude IDE: 确保workspace路径正确传递'
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return recommendations
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user