Add parallel search mode and index progress bar

Features:
- CCW smart_search: Add 'parallel' mode that runs hybrid + exact + ripgrep
  simultaneously with RRF (Reciprocal Rank Fusion) for result merging
- Dashboard: Add real-time progress bar for CodexLens index initialization
- MCP: Return progress metadata in init action response
- Codex-lens: Auto-detect optimal worker count for parallel indexing

Changes:
- smart-search.ts: Add parallel mode, RRF fusion, progress tracking
- codex-lens.ts: Add onProgress callback support, progress parsing
- codexlens-routes.ts: Broadcast index progress via WebSocket
- codexlens-manager.js: New index progress modal with real-time updates
- notifications.js: Add WebSocket event handler registration system
- i18n.js: Add English/Chinese translations for progress UI
- index_tree.py: Workers parameter now auto-detects CPU count (max 16)
- commands.py: CLI --workers parameter supports auto-detection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
catlog22
2025-12-17 23:17:15 +08:00
parent 44d84116c3
commit 51a61bef31
8 changed files with 569 additions and 21 deletions

View File

@@ -12,6 +12,7 @@ import {
installSemantic,
uninstallCodexLens
} from '../../tools/codex-lens.js';
import type { ProgressInfo } from '../../tools/codex-lens.js';
export interface RouteContext {
pathname: string;
@@ -217,9 +218,32 @@ export async function handleCodexLensRoutes(ctx: RouteContext): Promise<boolean>
const { path: projectPath } = body;
const targetPath = projectPath || initialPath;
// Broadcast start event
broadcastToClients({
type: 'CODEXLENS_INDEX_PROGRESS',
payload: { stage: 'start', message: 'Starting index...', percent: 0, path: targetPath }
});
try {
const result = await executeCodexLens(['init', targetPath, '--json'], { cwd: targetPath });
const result = await executeCodexLens(['init', targetPath, '--json'], {
cwd: targetPath,
timeout: 300000, // 5 minutes
onProgress: (progress: ProgressInfo) => {
// Broadcast progress to all connected clients
broadcastToClients({
type: 'CODEXLENS_INDEX_PROGRESS',
payload: { ...progress, path: targetPath }
});
}
});
if (result.success) {
// Broadcast completion
broadcastToClients({
type: 'CODEXLENS_INDEX_PROGRESS',
payload: { stage: 'complete', message: 'Index complete', percent: 100, path: targetPath }
});
try {
const parsed = extractJSON(result.output);
return { success: true, result: parsed };
@@ -227,9 +251,19 @@ export async function handleCodexLensRoutes(ctx: RouteContext): Promise<boolean>
return { success: true, output: result.output };
}
} else {
// Broadcast error
broadcastToClients({
type: 'CODEXLENS_INDEX_PROGRESS',
payload: { stage: 'error', message: result.error || 'Unknown error', percent: 0, path: targetPath }
});
return { success: false, error: result.error, status: 500 };
}
} catch (err) {
// Broadcast error
broadcastToClients({
type: 'CODEXLENS_INDEX_PROGRESS',
payload: { stage: 'error', message: err.message, percent: 0, path: targetPath }
});
return { success: false, error: err.message, status: 500 };
}
});