mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
feat: 添加 Code Index MCP 提供者支持,更新相关 API 和配置
This commit is contained in:
@@ -40,7 +40,9 @@ import {
|
||||
updateClaudeCacheSettings,
|
||||
getClaudeCliToolsInfo,
|
||||
addClaudeCustomEndpoint,
|
||||
removeClaudeCustomEndpoint
|
||||
removeClaudeCustomEndpoint,
|
||||
updateCodeIndexMcp,
|
||||
getCodeIndexMcp
|
||||
} from '../../tools/claude-cli-tools.js';
|
||||
|
||||
export interface RouteContext {
|
||||
@@ -750,5 +752,45 @@ export async function handleCliRoutes(ctx: RouteContext): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
// API: Get Code Index MCP provider
|
||||
if (pathname === '/api/cli/code-index-mcp' && req.method === 'GET') {
|
||||
try {
|
||||
const provider = getCodeIndexMcp(initialPath);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ provider }));
|
||||
} catch (err) {
|
||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: (err as Error).message }));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// API: Update Code Index MCP provider
|
||||
if (pathname === '/api/cli/code-index-mcp' && req.method === 'PUT') {
|
||||
handlePostRequest(req, res, async (body: unknown) => {
|
||||
try {
|
||||
const { provider } = body as { provider: 'codexlens' | 'ace' };
|
||||
if (!provider || !['codexlens', 'ace'].includes(provider)) {
|
||||
return { error: 'Invalid provider. Must be "codexlens" or "ace"', status: 400 };
|
||||
}
|
||||
|
||||
const result = updateCodeIndexMcp(initialPath, provider);
|
||||
|
||||
if (result.success) {
|
||||
broadcastToClients({
|
||||
type: 'CODE_INDEX_MCP_UPDATED',
|
||||
payload: { provider, timestamp: new Date().toISOString() }
|
||||
});
|
||||
return { success: true, provider };
|
||||
} else {
|
||||
return { error: result.error, status: 500 };
|
||||
}
|
||||
} catch (err) {
|
||||
return { error: (err as Error).message, status: 500 };
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ let nativeResumeEnabled = localStorage.getItem('ccw-native-resume') !== 'false';
|
||||
// Recursive Query settings (for hierarchical storage aggregation)
|
||||
let recursiveQueryEnabled = localStorage.getItem('ccw-recursive-query') !== 'false'; // default true
|
||||
|
||||
// Code Index MCP provider (codexlens or ace)
|
||||
let codeIndexMcpProvider = 'codexlens';
|
||||
|
||||
// ========== Initialization ==========
|
||||
function initCliStatus() {
|
||||
// Load all statuses in one call using aggregated endpoint
|
||||
@@ -241,7 +244,12 @@ async function loadCliToolsConfig() {
|
||||
defaultCliTool = data.defaultTool;
|
||||
}
|
||||
|
||||
console.log('[CLI Config] Loaded from:', data._configInfo?.source || 'unknown', '| Default:', data.defaultTool);
|
||||
// Load Code Index MCP provider from config
|
||||
if (data.settings?.codeIndexMcp) {
|
||||
codeIndexMcpProvider = data.settings.codeIndexMcp;
|
||||
}
|
||||
|
||||
console.log('[CLI Config] Loaded from:', data._configInfo?.source || 'unknown', '| Default:', data.defaultTool, '| CodeIndexMCP:', codeIndexMcpProvider);
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error('Failed to load CLI tools config:', err);
|
||||
@@ -614,6 +622,25 @@ function renderCliStatus() {
|
||||
</div>
|
||||
<p class="cli-setting-desc">Cache prefix/suffix injection mode for prompts</p>
|
||||
</div>
|
||||
<div class="cli-setting-item">
|
||||
<label class="cli-setting-label">
|
||||
<i data-lucide="search" class="w-3 h-3"></i>
|
||||
Code Index MCP
|
||||
</label>
|
||||
<div class="cli-setting-control">
|
||||
<div class="flex items-center bg-muted rounded-lg p-0.5">
|
||||
<button class="code-mcp-btn px-3 py-1.5 text-xs font-medium rounded-md transition-all ${codeIndexMcpProvider === 'codexlens' ? 'bg-primary text-primary-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}"
|
||||
onclick="setCodeIndexMcpProvider('codexlens')">
|
||||
CodexLens
|
||||
</button>
|
||||
<button class="code-mcp-btn px-3 py-1.5 text-xs font-medium rounded-md transition-all ${codeIndexMcpProvider === 'ace' ? 'bg-primary text-primary-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}"
|
||||
onclick="setCodeIndexMcpProvider('ace')">
|
||||
ACE
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="cli-setting-desc">Code search provider (updates CLAUDE.md context-tools reference)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -736,6 +763,30 @@ async function setCacheInjectionMode(mode) {
|
||||
}
|
||||
}
|
||||
|
||||
async function setCodeIndexMcpProvider(provider) {
|
||||
try {
|
||||
const response = await fetch('/api/cli/code-index-mcp', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ provider: provider })
|
||||
});
|
||||
if (response.ok) {
|
||||
codeIndexMcpProvider = provider;
|
||||
if (window.claudeCliToolsConfig && window.claudeCliToolsConfig.settings) {
|
||||
window.claudeCliToolsConfig.settings.codeIndexMcp = provider;
|
||||
}
|
||||
showRefreshToast(`Code Index MCP switched to ${provider === 'ace' ? 'ACE (Augment)' : 'CodexLens'}`, 'success');
|
||||
renderCliStatus();
|
||||
} else {
|
||||
const data = await response.json();
|
||||
showRefreshToast(`Failed to switch Code Index MCP: ${data.error}`, 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to switch Code Index MCP:', err);
|
||||
showRefreshToast('Failed to switch Code Index MCP', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshAllCliStatus() {
|
||||
await loadAllStatuses();
|
||||
renderCliStatus();
|
||||
|
||||
@@ -42,6 +42,7 @@ export interface ClaudeCliToolsConfig {
|
||||
nativeResume: boolean;
|
||||
recursiveQuery: boolean;
|
||||
cache: ClaudeCacheSettings;
|
||||
codeIndexMcp: 'codexlens' | 'ace'; // Code Index MCP provider
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,7 +90,8 @@ const DEFAULT_CONFIG: ClaudeCliToolsConfig = {
|
||||
injectionMode: 'auto',
|
||||
defaultPrefix: '',
|
||||
defaultSuffix: ''
|
||||
}
|
||||
},
|
||||
codeIndexMcp: 'codexlens' // Default to CodexLens
|
||||
}
|
||||
};
|
||||
|
||||
@@ -298,3 +300,76 @@ export function getClaudeCliToolsInfo(projectDir: string): {
|
||||
source: resolved.source
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Code Index MCP provider and switch CLAUDE.md reference
|
||||
*/
|
||||
export function updateCodeIndexMcp(
|
||||
projectDir: string,
|
||||
provider: 'codexlens' | 'ace'
|
||||
): { success: boolean; error?: string; config?: ClaudeCliToolsConfig } {
|
||||
try {
|
||||
// Update config
|
||||
const config = loadClaudeCliTools(projectDir);
|
||||
config.settings.codeIndexMcp = provider;
|
||||
saveClaudeCliTools(projectDir, config);
|
||||
|
||||
// Update CLAUDE.md reference
|
||||
const claudeMdPath = path.join(projectDir, '.claude', 'CLAUDE.md');
|
||||
if (fs.existsSync(claudeMdPath)) {
|
||||
let content = fs.readFileSync(claudeMdPath, 'utf-8');
|
||||
|
||||
// Define the file patterns
|
||||
const codexlensPattern = /@~\/\.claude\/workflows\/context-tools\.md/g;
|
||||
const acePattern = /@~\/\.claude\/workflows\/context-tools-ace\.md/g;
|
||||
|
||||
// Also handle project-level references
|
||||
const codexlensPatternProject = /@\.claude\/workflows\/context-tools\.md/g;
|
||||
const acePatternProject = /@\.claude\/workflows\/context-tools-ace\.md/g;
|
||||
|
||||
if (provider === 'ace') {
|
||||
// Switch to ACE
|
||||
content = content.replace(codexlensPattern, '@~/.claude/workflows/context-tools-ace.md');
|
||||
content = content.replace(codexlensPatternProject, '@.claude/workflows/context-tools-ace.md');
|
||||
} else {
|
||||
// Switch to CodexLens
|
||||
content = content.replace(acePattern, '@~/.claude/workflows/context-tools.md');
|
||||
content = content.replace(acePatternProject, '@.claude/workflows/context-tools.md');
|
||||
}
|
||||
|
||||
fs.writeFileSync(claudeMdPath, content, 'utf-8');
|
||||
console.log(`[claude-cli-tools] Updated CLAUDE.md to use ${provider}`);
|
||||
}
|
||||
|
||||
// Also update global CLAUDE.md if it exists
|
||||
const globalClaudeMdPath = path.join(os.homedir(), '.claude', 'CLAUDE.md');
|
||||
if (fs.existsSync(globalClaudeMdPath)) {
|
||||
let content = fs.readFileSync(globalClaudeMdPath, 'utf-8');
|
||||
|
||||
const codexlensPattern = /@~\/\.claude\/workflows\/context-tools\.md/g;
|
||||
const acePattern = /@~\/\.claude\/workflows\/context-tools-ace\.md/g;
|
||||
|
||||
if (provider === 'ace') {
|
||||
content = content.replace(codexlensPattern, '@~/.claude/workflows/context-tools-ace.md');
|
||||
} else {
|
||||
content = content.replace(acePattern, '@~/.claude/workflows/context-tools.md');
|
||||
}
|
||||
|
||||
fs.writeFileSync(globalClaudeMdPath, content, 'utf-8');
|
||||
console.log(`[claude-cli-tools] Updated global CLAUDE.md to use ${provider}`);
|
||||
}
|
||||
|
||||
return { success: true, config };
|
||||
} catch (err) {
|
||||
console.error('[claude-cli-tools] Error updating Code Index MCP:', err);
|
||||
return { success: false, error: (err as Error).message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current Code Index MCP provider
|
||||
*/
|
||||
export function getCodeIndexMcp(projectDir: string): 'codexlens' | 'ace' {
|
||||
const config = loadClaudeCliTools(projectDir);
|
||||
return config.settings.codeIndexMcp || 'codexlens';
|
||||
}
|
||||
|
||||
@@ -337,9 +337,8 @@ function buildCommand(params: {
|
||||
args.push(nativeResume.sessionId);
|
||||
}
|
||||
// Codex resume still supports additional flags
|
||||
if (dir) {
|
||||
args.push('-C', dir);
|
||||
}
|
||||
// Note: -C is NOT used because spawn's cwd already sets the working directory
|
||||
// Using both would cause path to be applied twice (e.g., codex-lens/codex-lens)
|
||||
// Permission configuration based on mode:
|
||||
// - analysis: --full-auto (read-only sandbox, no prompts) - safer for read operations
|
||||
// - write/auto: --dangerously-bypass-approvals-and-sandbox (full access for modifications)
|
||||
@@ -362,9 +361,8 @@ function buildCommand(params: {
|
||||
} else {
|
||||
// Standard exec mode
|
||||
args.push('exec');
|
||||
if (dir) {
|
||||
args.push('-C', dir);
|
||||
}
|
||||
// Note: -C is NOT used because spawn's cwd already sets the working directory
|
||||
// Using both would cause path to be applied twice (e.g., codex-lens/codex-lens)
|
||||
// Permission configuration based on mode:
|
||||
// - analysis: --full-auto (read-only sandbox, no prompts) - safer for read operations
|
||||
// - write/auto: --dangerously-bypass-approvals-and-sandbox (full access for modifications)
|
||||
|
||||
Reference in New Issue
Block a user