From 2a13d8b17fc5b0746a3df94cad8e2fade8e62351 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sun, 4 Jan 2026 19:56:40 +0800 Subject: [PATCH] feat: update CLI commands to new structure and enhance settings handling --- ccw/src/core/routes/codexlens-routes.ts | 49 +++++++++++++++---- .../dashboard-js/views/codexlens-manager.js | 8 +-- ccw/src/tools/codex-lens.ts | 5 +- ccw/src/tools/smart-search.ts | 15 +++--- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/ccw/src/core/routes/codexlens-routes.ts b/ccw/src/core/routes/codexlens-routes.ts index 60ffd014..8691b122 100644 --- a/ccw/src/core/routes/codexlens-routes.ts +++ b/ccw/src/core/routes/codexlens-routes.ts @@ -605,15 +605,16 @@ export async function handleCodexLensRoutes(ctx: RouteContext): Promise } // Build CLI arguments based on index type - const args = ['init', targetPath, '--json']; + // Use 'index init' subcommand (new CLI structure) + const args = ['index', 'init', targetPath, '--json']; if (indexType === 'normal') { args.push('--no-embeddings'); } else { - // Add embedding model selection for vector index - args.push('--embedding-model', embeddingModel); - // Add embedding backend if not using default fastembed + // Add embedding model selection for vector index (use --model, not --embedding-model) + args.push('--model', embeddingModel); + // Add embedding backend if not using default fastembed (use --backend, not --embedding-backend) if (embeddingBackend && embeddingBackend !== 'fastembed') { - args.push('--embedding-backend', embeddingBackend); + args.push('--backend', embeddingBackend); } // Add max workers for concurrent API calls (useful for litellm backend) if (maxWorkers && maxWorkers > 1) { @@ -786,7 +787,8 @@ export async function handleCodexLensRoutes(ctx: RouteContext): Promise try { // Request more results to support split (full content + extra files) const totalToFetch = limit + extraFilesCount; - const args = ['search', query, '--path', projectPath, '--limit', totalToFetch.toString(), '--mode', mode, '--json']; + // Use --method instead of deprecated --mode + const args = ['search', query, '--path', projectPath, '--limit', totalToFetch.toString(), '--method', mode, '--json']; const result = await executeCodexLens(args, { cwd: projectPath }); @@ -853,7 +855,8 @@ export async function handleCodexLensRoutes(ctx: RouteContext): Promise } try { - const args = ['search', query, '--path', projectPath, '--limit', limit.toString(), '--mode', mode, '--files-only', '--json']; + // Use --method instead of deprecated --mode + const args = ['search', query, '--path', projectPath, '--limit', limit.toString(), '--method', mode, '--files-only', '--json']; const result = await executeCodexLens(args, { cwd: projectPath }); @@ -1681,7 +1684,8 @@ except Exception as e: } try { - const result = await executeCodexLens(['splade-index', projectPath, '--rebuild'], { + // Use 'index splade' instead of deprecated 'splade-index' + const result = await executeCodexLens(['index', 'splade', projectPath, '--rebuild'], { cwd: projectPath, timeout: 1800000 // 30 minutes for large codebases }); @@ -1769,12 +1773,39 @@ except Exception as e: envVars[key] = value; } + // Also read settings.json for current configuration + const settingsPath = join(homedir(), '.codexlens', 'settings.json'); + let settings: Record = {}; + try { + const settingsContent = await readFile(settingsPath, 'utf-8'); + settings = JSON.parse(settingsContent); + } catch (e) { + // Settings file doesn't exist or is invalid, use empty + } + + // Map settings to env var format for defaults + const settingsDefaults: Record = {}; + if (settings.embedding?.backend) { + settingsDefaults['CODEXLENS_EMBEDDING_BACKEND'] = settings.embedding.backend; + } + if (settings.embedding?.model) { + settingsDefaults['CODEXLENS_EMBEDDING_MODEL'] = settings.embedding.model; + } + if (settings.reranker?.backend) { + // Map 'api' to 'litellm' for UI consistency + settingsDefaults['CODEXLENS_RERANKER_BACKEND'] = settings.reranker.backend === 'api' ? 'litellm' : settings.reranker.backend; + } + if (settings.reranker?.model) { + settingsDefaults['CODEXLENS_RERANKER_MODEL'] = settings.reranker.model; + } + res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true, path: envPath, env: envVars, - raw: content + raw: content, + settings: settingsDefaults })); } catch (err) { res.writeHead(500, { 'Content-Type': 'application/json' }); diff --git a/ccw/src/templates/dashboard-js/views/codexlens-manager.js b/ccw/src/templates/dashboard-js/views/codexlens-manager.js index 89e1fc06..2ca92752 100644 --- a/ccw/src/templates/dashboard-js/views/codexlens-manager.js +++ b/ccw/src/templates/dashboard-js/views/codexlens-manager.js @@ -670,8 +670,8 @@ var ENV_VAR_GROUPS = { icon: 'hard-drive', showWhen: function(env) { return env['CODEXLENS_EMBEDDING_BACKEND'] !== 'litellm' || env['CODEXLENS_RERANKER_BACKEND'] !== 'litellm'; }, vars: { - 'CODEXLENS_EMBEDDING_MODEL': { label: 'Embedding Model', placeholder: 'fast (code, base, minilm, multilingual, balanced)' }, - 'CODEXLENS_RERANKER_MODEL': { label: 'Reranker Model', placeholder: 'Xenova/ms-marco-MiniLM-L-6-v2' } + 'CODEXLENS_EMBEDDING_MODEL': { label: 'Embedding Model', placeholder: 'fast (code, base, minilm, multilingual, balanced)', default: 'fast' }, + 'CODEXLENS_RERANKER_MODEL': { label: 'Reranker Model', placeholder: 'Xenova/ms-marco-MiniLM-L-6-v2', default: 'Xenova/ms-marco-MiniLM-L-6-v2' } } }, api: { @@ -747,6 +747,7 @@ async function loadEnvVariables() { } var env = result.env || {}; + var settings = result.settings || {}; // Current settings from settings.json var html = '
'; // Get available LiteLLM providers @@ -783,7 +784,8 @@ async function loadEnvVariables() { for (var key in group.vars) { var config = group.vars[key]; - var value = env[key] || config.default || ''; + // Priority: env file > settings.json > hardcoded default + var value = env[key] || settings[key] || config.default || ''; if (config.type === 'select') { html += '
' + diff --git a/ccw/src/tools/codex-lens.ts b/ccw/src/tools/codex-lens.ts index d66b74f1..0caf28d9 100644 --- a/ccw/src/tools/codex-lens.ts +++ b/ccw/src/tools/codex-lens.ts @@ -939,9 +939,10 @@ async function executeCodexLens(args: string[], options: ExecuteOptions = {}): P async function initIndex(params: Params): Promise { const { path = '.', languages } = params; - const args = ['init', path]; + // Use 'index init' subcommand (new CLI structure) + const args = ['index', 'init', path]; if (languages && languages.length > 0) { - args.push('--languages', languages.join(',')); + args.push('--language', languages.join(',')); } return executeCodexLens(args, { cwd: path }); diff --git a/ccw/src/tools/smart-search.ts b/ccw/src/tools/smart-search.ts index e74218ae..92eea258 100644 --- a/ccw/src/tools/smart-search.ts +++ b/ccw/src/tools/smart-search.ts @@ -658,9 +658,10 @@ async function executeInitAction(params: Params): Promise { } // Build args with --no-embeddings for FTS-only index (faster) - const args = ['init', path, '--no-embeddings']; + // Use 'index init' subcommand (new CLI structure) + const args = ['index', 'init', path, '--no-embeddings']; if (languages && languages.length > 0) { - args.push('--languages', languages.join(',')); + args.push('--language', languages.join(',')); } // Track progress updates @@ -750,9 +751,10 @@ async function executeUpdateAction(params: Params): Promise { } // Build args for incremental init (without --force) - const args = ['init', path]; + // Use 'index init' subcommand (new CLI structure) + const args = ['index', 'init', path]; if (languages && languages.length > 0) { - args.push('--languages', languages.join(',')); + args.push('--language', languages.join(',')); } // Track progress updates @@ -2398,9 +2400,10 @@ export async function executeInitWithProgress( }; } - const args = ['init', path]; + // Use 'index init' subcommand (new CLI structure) + const args = ['index', 'init', path]; if (languages && languages.length > 0) { - args.push('--languages', languages.join(',')); + args.push('--language', languages.join(',')); } // Track progress updates