mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
fix: Align semantic status check with CodexLens checkSemanticStatus
- Use checkSemanticStatus() from codex-lens.ts instead of isEmbedderAvailable() - Returns accurate detection of fastembed installation status - Fix install guide link to navigate to CLI Manager and open CodexLens config - Update i18n: "Install Guide" -> "Go to Settings" (EN/ZH) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -110,7 +110,7 @@ ccw install -m Path -p ./my-project
|
|||||||
ccw view
|
ccw view
|
||||||
|
|
||||||
# Start dashboard server on custom port
|
# Start dashboard server on custom port
|
||||||
ccw serve -p 8080
|
ccw serve --port 8080
|
||||||
|
|
||||||
# Upgrade all installations
|
# Upgrade all installations
|
||||||
ccw upgrade -a
|
ccw upgrade -a
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ ccw install -m Path -p ./my-project
|
|||||||
ccw view
|
ccw view
|
||||||
|
|
||||||
# 在自定义端口启动仪表板服务器
|
# 在自定义端口启动仪表板服务器
|
||||||
ccw serve -p 8080
|
ccw serve --port 8080
|
||||||
|
|
||||||
# 升级所有安装
|
# 升级所有安装
|
||||||
ccw upgrade -a
|
ccw upgrade -a
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import * as http from 'http';
|
|||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
import { getCoreMemoryStore } from '../core-memory-store.js';
|
import { getCoreMemoryStore } from '../core-memory-store.js';
|
||||||
import type { CoreMemory, SessionCluster, ClusterMember, ClusterRelation } from '../core-memory-store.js';
|
import type { CoreMemory, SessionCluster, ClusterMember, ClusterRelation } from '../core-memory-store.js';
|
||||||
import { getEmbeddingStatus, generateEmbeddings, isEmbedderAvailable } from '../memory-embedder-bridge.js';
|
import { getEmbeddingStatus, generateEmbeddings } from '../memory-embedder-bridge.js';
|
||||||
|
import { checkSemanticStatus } from '../../tools/codex-lens.js';
|
||||||
import { StoragePaths } from '../../config/storage-paths.js';
|
import { StoragePaths } from '../../config/storage-paths.js';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
@@ -309,9 +310,19 @@ export async function handleCoreMemoryRoutes(ctx: RouteContext): Promise<boolean
|
|||||||
const projectPath = url.searchParams.get('path') || initialPath;
|
const projectPath = url.searchParams.get('path') || initialPath;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!isEmbedderAvailable()) {
|
// Check semantic status using CodexLens's check (same as status page)
|
||||||
|
const semanticStatus = await checkSemanticStatus();
|
||||||
|
|
||||||
|
if (!semanticStatus.available) {
|
||||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
res.end(JSON.stringify(null));
|
res.end(JSON.stringify({
|
||||||
|
available: false,
|
||||||
|
total_chunks: 0,
|
||||||
|
embedded_chunks: 0,
|
||||||
|
pending_chunks: 0,
|
||||||
|
by_type: {},
|
||||||
|
error: semanticStatus.error
|
||||||
|
}));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,10 +331,18 @@ export async function handleCoreMemoryRoutes(ctx: RouteContext): Promise<boolean
|
|||||||
const status = await getEmbeddingStatus(dbPath);
|
const status = await getEmbeddingStatus(dbPath);
|
||||||
|
|
||||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
res.end(JSON.stringify(status));
|
res.end(JSON.stringify({ ...status, available: true }));
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
// Return status with available=true even on error (embedder exists but query failed)
|
||||||
res.end(JSON.stringify({ error: (error as Error).message }));
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({
|
||||||
|
available: true,
|
||||||
|
total_chunks: 0,
|
||||||
|
embedded_chunks: 0,
|
||||||
|
pending_chunks: 0,
|
||||||
|
by_type: {},
|
||||||
|
error: (error as Error).message
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -335,8 +354,10 @@ export async function handleCoreMemoryRoutes(ctx: RouteContext): Promise<boolean
|
|||||||
const basePath = projectPath || initialPath;
|
const basePath = projectPath || initialPath;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!isEmbedderAvailable()) {
|
// Check semantic status using CodexLens's check
|
||||||
return { error: 'Embedder not available. Install CodexLens first.', status: 503 };
|
const semanticStatus = await checkSemanticStatus();
|
||||||
|
if (!semanticStatus.available) {
|
||||||
|
return { error: semanticStatus.error || 'Semantic search not available. Install it from CLI > CodexLens > Semantic page.', status: 503 };
|
||||||
}
|
}
|
||||||
|
|
||||||
const paths = StoragePaths.project(basePath);
|
const paths = StoragePaths.project(basePath);
|
||||||
|
|||||||
@@ -1281,8 +1281,8 @@ const i18n = {
|
|||||||
'coreMemory.clusteringInProgress': 'Clustering in progress...',
|
'coreMemory.clusteringInProgress': 'Clustering in progress...',
|
||||||
'coreMemory.clusteringComplete': 'Created {created} clusters with {sessions} sessions',
|
'coreMemory.clusteringComplete': 'Created {created} clusters with {sessions} sessions',
|
||||||
'coreMemory.clusteringError': 'Auto-clustering failed',
|
'coreMemory.clusteringError': 'Auto-clustering failed',
|
||||||
'coreMemory.embeddingNotAvailable': 'Vector model not installed. Install to improve clustering accuracy.',
|
'coreMemory.embeddingNotAvailable': 'Semantic search not installed. Install to improve clustering accuracy.',
|
||||||
'coreMemory.installGuide': 'Install Guide',
|
'coreMemory.installGuide': 'Go to Settings',
|
||||||
'coreMemory.embeddingProgress': 'Embeddings: {pct}% ({pending} pending)',
|
'coreMemory.embeddingProgress': 'Embeddings: {pct}% ({pending} pending)',
|
||||||
'coreMemory.generateEmbeddings': 'Generate',
|
'coreMemory.generateEmbeddings': 'Generate',
|
||||||
'coreMemory.noChunksYet': 'No memories chunked yet. Run "ccw memory embed" to enable semantic clustering.',
|
'coreMemory.noChunksYet': 'No memories chunked yet. Run "ccw memory embed" to enable semantic clustering.',
|
||||||
@@ -2602,8 +2602,8 @@ const i18n = {
|
|||||||
'coreMemory.clusteringInProgress': '聚类进行中...',
|
'coreMemory.clusteringInProgress': '聚类进行中...',
|
||||||
'coreMemory.clusteringComplete': '创建了 {created} 个聚类,包含 {sessions} 个 session',
|
'coreMemory.clusteringComplete': '创建了 {created} 个聚类,包含 {sessions} 个 session',
|
||||||
'coreMemory.clusteringError': '自动聚类失败',
|
'coreMemory.clusteringError': '自动聚类失败',
|
||||||
'coreMemory.embeddingNotAvailable': '向量模型未安装。安装后可提升聚类准确度。',
|
'coreMemory.embeddingNotAvailable': '语义搜索未安装。安装后可提升聚类准确度。',
|
||||||
'coreMemory.installGuide': '安装指南',
|
'coreMemory.installGuide': '前往设置',
|
||||||
'coreMemory.embeddingProgress': '嵌入进度: {pct}% (待处理: {pending})',
|
'coreMemory.embeddingProgress': '嵌入进度: {pct}% (待处理: {pending})',
|
||||||
'coreMemory.generateEmbeddings': '生成',
|
'coreMemory.generateEmbeddings': '生成',
|
||||||
'coreMemory.noChunksYet': '暂无记忆分块。运行 "ccw memory embed" 启用语义聚类。',
|
'coreMemory.noChunksYet': '暂无记忆分块。运行 "ccw memory embed" 启用语义聚类。',
|
||||||
|
|||||||
@@ -45,20 +45,29 @@ async function loadClusters() {
|
|||||||
* Render embedding status hint
|
* Render embedding status hint
|
||||||
*/
|
*/
|
||||||
function renderEmbeddingHint() {
|
function renderEmbeddingHint() {
|
||||||
|
// No status data - API call failed
|
||||||
if (!embeddingStatus) {
|
if (!embeddingStatus) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Embedder not available - show install hint linking to status page
|
||||||
|
if (embeddingStatus.available === false) {
|
||||||
return `
|
return `
|
||||||
<div class="embedding-hint warning">
|
<div class="embedding-hint warning">
|
||||||
<i data-lucide="alert-triangle"></i>
|
<i data-lucide="alert-triangle"></i>
|
||||||
<span>${t('coreMemory.embeddingNotAvailable')}</span>
|
<span>${t('coreMemory.embeddingNotAvailable')}</span>
|
||||||
<a href="#" onclick="window.open('https://github.com/anthropics/claude-code', '_blank'); return false;" class="hint-link">
|
<a href="#" onclick="switchToSemanticStatus(); return false;" class="hint-link">
|
||||||
${t('coreMemory.installGuide')}
|
${t('coreMemory.installGuide')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has pending chunks - show progress
|
||||||
if (embeddingStatus.pending_chunks > 0) {
|
if (embeddingStatus.pending_chunks > 0) {
|
||||||
const pct = Math.round((embeddingStatus.embedded_chunks / embeddingStatus.total_chunks) * 100);
|
const pct = embeddingStatus.total_chunks > 0
|
||||||
|
? Math.round((embeddingStatus.embedded_chunks / embeddingStatus.total_chunks) * 100)
|
||||||
|
: 0;
|
||||||
return `
|
return `
|
||||||
<div class="embedding-hint info">
|
<div class="embedding-hint info">
|
||||||
<i data-lucide="cpu"></i>
|
<i data-lucide="cpu"></i>
|
||||||
@@ -70,18 +79,42 @@ function renderEmbeddingHint() {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No chunks yet - show hint to run embed
|
||||||
if (embeddingStatus.total_chunks === 0) {
|
if (embeddingStatus.total_chunks === 0) {
|
||||||
return `
|
return `
|
||||||
<div class="embedding-hint info">
|
<div class="embedding-hint info">
|
||||||
<i data-lucide="info"></i>
|
<i data-lucide="info"></i>
|
||||||
<span>${t('coreMemory.noChunksYet')}</span>
|
<span>${t('coreMemory.noChunksYet')}</span>
|
||||||
|
<button class="btn btn-xs" onclick="triggerEmbedding()">
|
||||||
|
${t('coreMemory.generateEmbeddings')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All embedded - no hint needed
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch to CLI Manager and show semantic install hint
|
||||||
|
*/
|
||||||
|
function switchToSemanticStatus() {
|
||||||
|
// Navigate to CLI Manager view (which contains the Semantic Search section)
|
||||||
|
const navItem = document.querySelector('[data-view="cli-manager"]');
|
||||||
|
if (navItem) {
|
||||||
|
navItem.click();
|
||||||
|
// Open CodexLens config modal after navigation
|
||||||
|
setTimeout(() => {
|
||||||
|
if (typeof openCodexLensConfig === 'function') {
|
||||||
|
openCodexLensConfig();
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
showNotification(t('coreMemory.goToSemanticStatus'), 'info');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger embedding generation
|
* Trigger embedding generation
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user