mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
Add scripts for inspecting LLM summaries and testing misleading comments
- Implement `inspect_llm_summaries.py` to display LLM-generated summaries from the semantic_chunks table in the database. - Create `show_llm_analysis.py` to demonstrate LLM analysis of misleading code examples, highlighting discrepancies between comments and actual functionality. - Develop `test_misleading_comments.py` to compare pure vector search with LLM-enhanced search, focusing on the impact of misleading or missing comments on search results. - Introduce `test_llm_enhanced_search.py` to provide a test suite for evaluating the effectiveness of LLM-enhanced vector search against pure vector search. - Ensure all new scripts are integrated with the existing codebase and follow the established coding standards.
This commit is contained in:
@@ -64,7 +64,8 @@ const MODULE_CSS_FILES = [
|
||||
'11-prompt-history.css',
|
||||
'12-skills-rules.css',
|
||||
'13-claude-manager.css',
|
||||
'14-graph-explorer.css'
|
||||
'14-graph-explorer.css',
|
||||
'15-mcp-manager.css'
|
||||
];
|
||||
|
||||
// Modular JS files in dependency order
|
||||
|
||||
@@ -2,7 +2,187 @@
|
||||
MCP MANAGER - ORANGE THEME ENHANCEMENTS
|
||||
========================================== */
|
||||
|
||||
/* MCP CLI Mode Toggle - Orange for Codex */
|
||||
/* ==========================================
|
||||
BASIC BUTTON STYLES
|
||||
========================================== */
|
||||
|
||||
/* Primary buttons (blue) */
|
||||
.bg-primary {
|
||||
background-color: hsl(221.2, 83.2%, 53.3%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bg-primary:hover {
|
||||
background-color: hsl(221.2, 83.2%, 45%);
|
||||
}
|
||||
|
||||
.dark .bg-primary {
|
||||
background-color: hsl(217.2, 91.2%, 59.8%);
|
||||
}
|
||||
|
||||
.dark .bg-primary:hover {
|
||||
background-color: hsl(217.2, 91.2%, 65%);
|
||||
}
|
||||
|
||||
/* Success buttons (green) */
|
||||
.bg-success {
|
||||
background-color: hsl(142.1, 76.2%, 36.3%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bg-success:hover {
|
||||
background-color: hsl(142.1, 76.2%, 30%);
|
||||
}
|
||||
|
||||
.dark .bg-success {
|
||||
background-color: hsl(142.1, 70.6%, 45.3%);
|
||||
}
|
||||
|
||||
.dark .bg-success:hover {
|
||||
background-color: hsl(142.1, 70.6%, 50%);
|
||||
}
|
||||
|
||||
/* Destructive buttons (red) */
|
||||
.bg-destructive {
|
||||
background-color: hsl(0, 84.2%, 60.2%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bg-destructive:hover {
|
||||
background-color: hsl(0, 84.2%, 50%);
|
||||
}
|
||||
|
||||
.dark .bg-destructive {
|
||||
background-color: hsl(0, 62.8%, 30.6%);
|
||||
}
|
||||
|
||||
.dark .bg-destructive:hover {
|
||||
background-color: hsl(0, 62.8%, 40%);
|
||||
}
|
||||
|
||||
/* Secondary buttons (gray) */
|
||||
.bg-secondary {
|
||||
background-color: hsl(210, 40%, 96.1%);
|
||||
color: hsl(222.2, 47.4%, 11.2%);
|
||||
}
|
||||
|
||||
.bg-secondary:hover {
|
||||
background-color: hsl(210, 40%, 90%);
|
||||
}
|
||||
|
||||
.dark .bg-secondary {
|
||||
background-color: hsl(217.2, 32.6%, 17.5%);
|
||||
color: hsl(210, 40%, 98%);
|
||||
}
|
||||
|
||||
.dark .bg-secondary:hover {
|
||||
background-color: hsl(217.2, 32.6%, 22%);
|
||||
}
|
||||
|
||||
/* Muted/Ghost buttons */
|
||||
.bg-muted {
|
||||
background-color: hsl(210, 40%, 96.1%);
|
||||
color: hsl(215.4, 16.3%, 46.9%);
|
||||
}
|
||||
|
||||
.bg-muted:hover {
|
||||
background-color: hsl(210, 40%, 90%);
|
||||
}
|
||||
|
||||
.dark .bg-muted {
|
||||
background-color: hsl(217.2, 32.6%, 17.5%);
|
||||
color: hsl(215, 20.2%, 65.1%);
|
||||
}
|
||||
|
||||
.dark .bg-muted:hover {
|
||||
background-color: hsl(217.2, 32.6%, 22%);
|
||||
}
|
||||
|
||||
/* Button base styles */
|
||||
button {
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.5rem 1rem;
|
||||
font-weight: 500;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
button:focus-visible {
|
||||
outline: 2px solid hsl(221.2, 83.2%, 53.3%);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Icon buttons */
|
||||
button.icon-btn {
|
||||
padding: 0.5rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 2rem;
|
||||
min-height: 2rem;
|
||||
}
|
||||
|
||||
/* ==========================================
|
||||
CLAUDE (ORANGE) & CODEX (GREEN) THEMES
|
||||
========================================== */
|
||||
|
||||
/* Claude Orange Colors */
|
||||
.text-claude {
|
||||
color: #f97316;
|
||||
}
|
||||
|
||||
.bg-claude {
|
||||
background-color: #f97316;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bg-claude:hover {
|
||||
background-color: #ea580c;
|
||||
}
|
||||
|
||||
.border-claude {
|
||||
border-color: #f97316;
|
||||
}
|
||||
|
||||
/* Codex Green Colors */
|
||||
.text-codex {
|
||||
color: #22c55e;
|
||||
}
|
||||
|
||||
.bg-codex {
|
||||
background-color: #22c55e;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bg-codex:hover {
|
||||
background-color: #16a34a;
|
||||
}
|
||||
|
||||
.border-codex {
|
||||
border-color: #22c55e;
|
||||
}
|
||||
|
||||
/* Dark mode adjustments */
|
||||
.dark .text-claude {
|
||||
color: #fb923c;
|
||||
}
|
||||
|
||||
.dark .text-codex {
|
||||
color: #4ade80;
|
||||
}
|
||||
|
||||
/* ==========================================
|
||||
ORANGE THEME ENHANCEMENTS (CLAUDE)
|
||||
========================================== */
|
||||
|
||||
/* MCP CLI Mode Toggle - Orange for Claude */
|
||||
.mcp-cli-toggle .cli-mode-btn {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@@ -373,3 +553,186 @@
|
||||
.mcp-section .flex.items-center.gap-3 button:hover::before {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
/* ==========================================
|
||||
GREEN THEME ENHANCEMENTS (CODEX)
|
||||
========================================== */
|
||||
|
||||
/* Codex green colors palette */
|
||||
.bg-green-500 {
|
||||
background-color: #22c55e;
|
||||
}
|
||||
|
||||
.text-green-500 {
|
||||
color: #22c55e;
|
||||
}
|
||||
|
||||
.text-green-600 {
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
.text-green-700 {
|
||||
color: #15803d;
|
||||
}
|
||||
|
||||
.text-green-800 {
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
.bg-green-50 {
|
||||
background-color: #f0fdf4;
|
||||
}
|
||||
|
||||
.bg-green-100 {
|
||||
background-color: #dcfce7;
|
||||
}
|
||||
|
||||
.border-green-200 {
|
||||
border-color: #bbf7d0;
|
||||
}
|
||||
|
||||
.border-green-500\/20 {
|
||||
border-color: rgba(34, 197, 94, 0.2);
|
||||
}
|
||||
|
||||
.border-green-500\/30 {
|
||||
border-color: rgba(34, 197, 94, 0.3);
|
||||
}
|
||||
|
||||
.border-green-800 {
|
||||
border-color: #166534;
|
||||
}
|
||||
|
||||
/* Dark mode green colors */
|
||||
.dark .bg-green-50 {
|
||||
background-color: rgba(34, 197, 94, 0.05);
|
||||
}
|
||||
|
||||
.dark .bg-green-100 {
|
||||
background-color: rgba(34, 197, 94, 0.1);
|
||||
}
|
||||
|
||||
.dark .bg-green-900\/30 {
|
||||
background-color: rgba(20, 83, 45, 0.3);
|
||||
}
|
||||
|
||||
.dark .text-green-200 {
|
||||
color: #bbf7d0;
|
||||
}
|
||||
|
||||
.dark .text-green-300 {
|
||||
color: #86efac;
|
||||
}
|
||||
|
||||
.dark .text-green-400 {
|
||||
color: #4ade80;
|
||||
}
|
||||
|
||||
.dark .border-green-800 {
|
||||
border-color: #166534;
|
||||
}
|
||||
|
||||
.dark .border-green-950\/30 {
|
||||
background-color: rgba(5, 46, 22, 0.3);
|
||||
}
|
||||
|
||||
/* Codex MCP Server Cards - Green Borders */
|
||||
.mcp-server-card[data-cli-type="codex-green"] {
|
||||
border-left: 3px solid #22c55e;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.mcp-server-card[data-cli-type="codex-green"]:hover {
|
||||
border-left-width: 4px;
|
||||
box-shadow: 0 4px 16px rgba(34, 197, 94, 0.15);
|
||||
}
|
||||
|
||||
/* Toggle switches - Green for Codex */
|
||||
.mcp-toggle input:checked + div.peer-checked\:bg-green-500 {
|
||||
background: #22c55e;
|
||||
}
|
||||
|
||||
/* Installation buttons - Enhanced Green */
|
||||
.bg-green-500:hover {
|
||||
background-color: #16a34a;
|
||||
box-shadow: 0 4px 12px rgba(34, 197, 94, 0.3);
|
||||
}
|
||||
|
||||
/* Info panels - Green accent */
|
||||
.bg-green-50.dark\:bg-green-950\/30 {
|
||||
border-left: 3px solid #22c55e;
|
||||
}
|
||||
|
||||
/* Codex section headers - Green gradient */
|
||||
.text-green-500 svg {
|
||||
filter: drop-shadow(0 2px 4px rgba(34, 197, 94, 0.3));
|
||||
}
|
||||
|
||||
.mcp-section h3.text-green-500 {
|
||||
background: linear-gradient(90deg, #22c55e 0%, #16a34a 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Animated pulse for Codex servers */
|
||||
.border-green-500\/30 {
|
||||
animation: greenPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes greenPulse {
|
||||
0%, 100% {
|
||||
border-color: rgba(34, 197, 94, 0.3);
|
||||
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
|
||||
}
|
||||
50% {
|
||||
border-color: rgba(34, 197, 94, 0.6);
|
||||
box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Green button hover effects */
|
||||
.bg-green-500.rounded-lg {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bg-green-500.rounded-lg::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: translate(-50%, -50%);
|
||||
transition: width 0.3s, height 0.3s;
|
||||
}
|
||||
|
||||
.bg-green-500.rounded-lg:active::after {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* Green-themed success badges */
|
||||
.bg-green-100 {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* Loading states with green */
|
||||
@keyframes greenGlow {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 10px rgba(34, 197, 94, 0.3);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 20px rgba(34, 197, 94, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-green {
|
||||
animation: greenGlow 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@@ -306,17 +306,17 @@ function initializeCytoscape() {
|
||||
style: getCytoscapeStyles(),
|
||||
layout: {
|
||||
name: 'cose',
|
||||
idealEdgeLength: 100,
|
||||
nodeOverlap: 20,
|
||||
idealEdgeLength: 180,
|
||||
nodeOverlap: 50,
|
||||
refresh: 20,
|
||||
fit: true,
|
||||
padding: 30,
|
||||
padding: 50,
|
||||
randomize: false,
|
||||
componentSpacing: 100,
|
||||
nodeRepulsion: 400000,
|
||||
componentSpacing: 150,
|
||||
nodeRepulsion: 600000,
|
||||
edgeElasticity: 100,
|
||||
nestingFactor: 5,
|
||||
gravity: 80,
|
||||
gravity: 60,
|
||||
numIter: 1000,
|
||||
initialTemp: 200,
|
||||
coolingFactor: 0.95,
|
||||
@@ -412,18 +412,18 @@ function getCytoscapeStyles() {
|
||||
'label': 'data(label)',
|
||||
'width': function(ele) {
|
||||
var refs = ele.data('references') || 0;
|
||||
return Math.max(20, Math.min(60, 20 + refs * 2));
|
||||
return Math.max(16, Math.min(48, 16 + refs * 1.5));
|
||||
},
|
||||
'height': function(ele) {
|
||||
var refs = ele.data('references') || 0;
|
||||
return Math.max(20, Math.min(60, 20 + refs * 2));
|
||||
return Math.max(16, Math.min(48, 16 + refs * 1.5));
|
||||
},
|
||||
'text-valign': 'center',
|
||||
'text-halign': 'center',
|
||||
'font-size': '10px',
|
||||
'font-size': '8px',
|
||||
'color': '#000',
|
||||
'text-outline-color': '#fff',
|
||||
'text-outline-width': 2,
|
||||
'text-outline-width': 1.5,
|
||||
'overlay-padding': 6
|
||||
}
|
||||
},
|
||||
@@ -612,11 +612,14 @@ function refreshCytoscape() {
|
||||
cyInstance.add(elements);
|
||||
cyInstance.layout({
|
||||
name: 'cose',
|
||||
idealEdgeLength: 100,
|
||||
nodeOverlap: 20,
|
||||
idealEdgeLength: 180,
|
||||
nodeOverlap: 50,
|
||||
refresh: 20,
|
||||
fit: true,
|
||||
padding: 30
|
||||
padding: 50,
|
||||
componentSpacing: 150,
|
||||
nodeRepulsion: 600000,
|
||||
gravity: 60
|
||||
}).run();
|
||||
|
||||
deselectNode();
|
||||
@@ -625,7 +628,7 @@ function refreshCytoscape() {
|
||||
// ========== Cytoscape Controls ==========
|
||||
function fitCytoscape() {
|
||||
if (cyInstance) {
|
||||
cyInstance.fit(null, 30);
|
||||
cyInstance.fit(null, 50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,23 +193,23 @@ async function renderMcpManager() {
|
||||
${currentCliMode === 'codex' ? `
|
||||
<!-- CCW Tools MCP Server Card (Codex mode) -->
|
||||
<div class="mcp-section mb-6">
|
||||
<div class="ccw-tools-card bg-gradient-to-br from-orange-500/10 to-orange-500/5 border-2 ${codexMcpServers && codexMcpServers['ccw-tools'] ? 'border-success' : 'border-orange-500/30'} rounded-lg p-6 hover:shadow-lg transition-all">
|
||||
<div class="ccw-tools-card bg-gradient-to-br from-primary/10 to-primary/5 border-2 ${codexMcpServers && codexMcpServers['ccw-tools'] ? 'border-success' : 'border-primary/30'} rounded-lg p-6 hover:shadow-lg transition-all">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex items-start gap-4 flex-1">
|
||||
<div class="shrink-0 w-12 h-12 bg-orange-500 rounded-lg flex items-center justify-center">
|
||||
<div class="shrink-0 w-12 h-12 bg-primary rounded-lg flex items-center justify-center">
|
||||
<i data-lucide="wrench" class="w-6 h-6 text-white"></i>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<h3 class="text-lg font-bold text-foreground">CCW Tools MCP</h3>
|
||||
<span class="text-xs px-2 py-0.5 bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300 rounded-full">Codex</span>
|
||||
<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">Codex</span>
|
||||
${codexMcpServers && codexMcpServers['ccw-tools'] ? `
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold rounded-full bg-success-light text-success">
|
||||
<i data-lucide="check" class="w-3 h-3"></i>
|
||||
${enabledToolsCodex.length} tools
|
||||
</span>
|
||||
` : `
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold rounded-full bg-orange-500/20 text-orange-600 dark:text-orange-400">
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold rounded-full bg-primary/20 text-primary">
|
||||
<i data-lucide="package" class="w-3 h-3"></i>
|
||||
${t('mcp.available')}
|
||||
</span>
|
||||
@@ -228,14 +228,14 @@ async function renderMcpManager() {
|
||||
`).join('')}
|
||||
</div>
|
||||
<div class="flex items-center gap-3 text-xs">
|
||||
<button class="text-orange-500 hover:underline" onclick="selectCcwToolsCodex('core')">Core only</button>
|
||||
<button class="text-orange-500 hover:underline" onclick="selectCcwToolsCodex('all')">All</button>
|
||||
<button class="text-primary hover:underline" onclick="selectCcwToolsCodex('core')">Core only</button>
|
||||
<button class="text-primary hover:underline" onclick="selectCcwToolsCodex('all')">All</button>
|
||||
<button class="text-muted-foreground hover:underline" onclick="selectCcwToolsCodex('none')">None</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shrink-0">
|
||||
<button class="px-4 py-2 text-sm bg-orange-500 text-white rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
<button class="px-4 py-2 text-sm bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
onclick="installCcwToolsMcpToCodex()">
|
||||
<i data-lucide="download" class="w-4 h-4"></i>
|
||||
${codexMcpServers && codexMcpServers['ccw-tools'] ? t('mcp.update') : t('mcp.install')}
|
||||
@@ -250,10 +250,10 @@ async function renderMcpManager() {
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<i data-lucide="code-2" class="w-5 h-5 text-orange-500"></i>
|
||||
<i data-lucide="code-2" class="w-5 h-5 text-primary"></i>
|
||||
<h3 class="text-lg font-semibold text-foreground">${t('mcp.codex.globalServers')}</h3>
|
||||
</div>
|
||||
<button class="px-3 py-1.5 text-sm bg-orange-500 text-white rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
<button class="px-3 py-1.5 text-sm bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
onclick="openCodexMcpCreateModal()">
|
||||
<span>+</span> ${t('mcp.codex.newServer')}
|
||||
</button>
|
||||
@@ -273,12 +273,12 @@ async function renderMcpManager() {
|
||||
</div>
|
||||
|
||||
<!-- Info about Codex MCP -->
|
||||
<div class="bg-orange-50 dark:bg-orange-950/30 border border-orange-200 dark:border-orange-800 rounded-lg p-4 mb-4">
|
||||
<div class="bg-green-50 dark:bg-green-950/30 border border-primary/20 rounded-lg p-4 mb-4">
|
||||
<div class="flex items-start gap-3">
|
||||
<i data-lucide="info" class="w-5 h-5 text-orange-500 shrink-0 mt-0.5"></i>
|
||||
<i data-lucide="info" class="w-5 h-5 text-green-500 shrink-0 mt-0.5"></i>
|
||||
<div class="text-sm">
|
||||
<p class="text-orange-800 dark:text-orange-200 font-medium mb-1">${t('mcp.codex.infoTitle')}</p>
|
||||
<p class="text-orange-700 dark:text-orange-300 text-xs">${t('mcp.codex.infoDesc')}</p>
|
||||
<p class="text-primary font-medium mb-1">${t('mcp.codex.infoTitle')}</p>
|
||||
<p class="text-primary/80 text-xs">${t('mcp.codex.infoDesc')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -321,7 +321,7 @@ async function renderMcpManager() {
|
||||
${alreadyInCodex ? `<span class="text-xs px-2 py-0.5 bg-success/10 text-success rounded-full">${t('mcp.codex.alreadyAdded')}</span>` : ''}
|
||||
</div>
|
||||
${!alreadyInCodex ? `
|
||||
<button class="px-3 py-1 text-xs bg-orange-500 text-white rounded hover:opacity-90 transition-opacity"
|
||||
<button class="px-3 py-1 text-xs bg-primary text-primary-foreground rounded hover:opacity-90 transition-opacity"
|
||||
onclick="copyClaudeServerToCodex('${escapeHtml(serverName)}', ${JSON.stringify(serverConfig).replace(/'/g, "'")})"
|
||||
title="${t('mcp.codex.copyToCodex')}">
|
||||
<i data-lucide="arrow-right" class="w-3.5 h-3.5 inline"></i> Codex
|
||||
@@ -366,7 +366,7 @@ async function renderMcpManager() {
|
||||
<div class="mcp-section">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-foreground flex items-center gap-2">
|
||||
<i data-lucide="circle" class="w-5 h-5 text-blue-500"></i>
|
||||
<i data-lucide="circle" class="w-5 h-5 text-primary"></i>
|
||||
${t('mcp.codex.copyFromClaude')}
|
||||
</h3>
|
||||
<span class="text-sm text-muted-foreground">${crossCliServers.length} ${t('mcp.serversAvailable')}</span>
|
||||
@@ -379,10 +379,10 @@ async function renderMcpManager() {
|
||||
` : `
|
||||
<!-- CCW Tools MCP Server Card -->
|
||||
<div class="mcp-section mb-6">
|
||||
<div class="ccw-tools-card bg-gradient-to-br from-orange-500/10 to-orange-500/5 border-2 ${isCcwToolsInstalled ? 'border-success' : 'border-orange-500/30'} rounded-lg p-6 hover:shadow-lg transition-all">
|
||||
<div class="ccw-tools-card bg-gradient-to-br from-primary/10 to-primary/5 border-2 ${isCcwToolsInstalled ? 'border-success' : 'border-primary/30'} rounded-lg p-6 hover:shadow-lg transition-all">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex items-start gap-4 flex-1">
|
||||
<div class="shrink-0 w-12 h-12 bg-orange-500 rounded-lg flex items-center justify-center">
|
||||
<div class="shrink-0 w-12 h-12 bg-primary rounded-lg flex items-center justify-center">
|
||||
<i data-lucide="wrench" class="w-6 h-6 text-white"></i>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
@@ -394,7 +394,7 @@ async function renderMcpManager() {
|
||||
${enabledTools.length} tools
|
||||
</span>
|
||||
` : `
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold rounded-full bg-orange-500/20 text-orange-600 dark:text-orange-400">
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold rounded-full bg-primary/20 text-primary">
|
||||
<i data-lucide="package" class="w-3 h-3"></i>
|
||||
Available
|
||||
</span>
|
||||
@@ -412,15 +412,15 @@ async function renderMcpManager() {
|
||||
`).join('')}
|
||||
</div>
|
||||
<div class="flex items-center gap-3 text-xs">
|
||||
<button class="text-orange-500 hover:underline" onclick="selectCcwTools('core')">Core only</button>
|
||||
<button class="text-orange-500 hover:underline" onclick="selectCcwTools('all')">All</button>
|
||||
<button class="text-primary hover:underline" onclick="selectCcwTools('core')">Core only</button>
|
||||
<button class="text-primary hover:underline" onclick="selectCcwTools('all')">All</button>
|
||||
<button class="text-muted-foreground hover:underline" onclick="selectCcwTools('none')">None</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shrink-0 flex gap-2">
|
||||
${isCcwToolsInstalled ? `
|
||||
<button class="px-4 py-2 text-sm bg-orange-500 text-white rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
<button class="px-4 py-2 text-sm bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
onclick="updateCcwToolsMcp('workspace')"
|
||||
title="${t('mcp.updateInWorkspace')}">
|
||||
<i data-lucide="folder" class="w-4 h-4"></i>
|
||||
@@ -433,7 +433,7 @@ async function renderMcpManager() {
|
||||
${t('mcp.updateInGlobal')}
|
||||
</button>
|
||||
` : `
|
||||
<button class="px-4 py-2 text-sm bg-orange-500 text-white rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
<button class="px-4 py-2 text-sm bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity flex items-center gap-1"
|
||||
onclick="installCcwToolsMcp('workspace')"
|
||||
title="${t('mcp.installToWorkspace')}">
|
||||
<i data-lucide="folder" class="w-4 h-4"></i>
|
||||
@@ -546,7 +546,7 @@ async function renderMcpManager() {
|
||||
<div class="mcp-section mb-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-foreground flex items-center gap-2">
|
||||
<i data-lucide="circle-dashed" class="w-5 h-5 text-orange-500"></i>
|
||||
<i data-lucide="circle-dashed" class="w-5 h-5 text-primary"></i>
|
||||
${t('mcp.claude.copyFromCodex')}
|
||||
</h3>
|
||||
<span class="text-sm text-muted-foreground">${crossCliServers.length} ${t('mcp.serversAvailable')}</span>
|
||||
@@ -644,12 +644,12 @@ async function renderMcpManager() {
|
||||
const isStdio = !!serverConfig.command;
|
||||
const isHttp = !!serverConfig.url;
|
||||
return `
|
||||
<div class="mcp-server-card bg-card border ${alreadyInClaude ? 'border-success/50' : 'border-orange-200 dark:border-orange-800'} border-dashed rounded-lg p-4 hover:shadow-md transition-all">
|
||||
<div class="mcp-server-card bg-card border ${alreadyInClaude ? 'border-success/50' : 'border-primary/20'} border-dashed rounded-lg p-4 hover:shadow-md transition-all">
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<i data-lucide="code-2" class="w-5 h-5 text-orange-500"></i>
|
||||
<i data-lucide="code-2" class="w-5 h-5 text-primary"></i>
|
||||
<h4 class="font-semibold text-foreground">${escapeHtml(serverName)}</h4>
|
||||
<span class="text-xs px-2 py-0.5 bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300 rounded-full">Codex</span>
|
||||
<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">Codex</span>
|
||||
${isHttp
|
||||
? '<span class="text-xs px-2 py-0.5 bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300 rounded-full">HTTP</span>'
|
||||
: '<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">STDIO</span>'
|
||||
@@ -1039,7 +1039,7 @@ function renderAvailableServerCardForCodex(serverName, serverInfo) {
|
||||
${alreadyInCodex ? `<span class="text-xs px-2 py-0.5 bg-success/10 text-success rounded-full">${t('mcp.codex.alreadyAdded')}</span>` : ''}
|
||||
</div>
|
||||
${!alreadyInCodex ? `
|
||||
<button class="px-3 py-1 text-xs bg-orange-500 text-white rounded hover:opacity-90 transition-opacity"
|
||||
<button class="px-3 py-1 text-xs bg-primary text-primary-foreground rounded hover:opacity-90 transition-opacity"
|
||||
onclick="copyClaudeServerToCodex('${escapeHtml(originalName)}', ${JSON.stringify(serverConfig).replace(/'/g, "'")})"
|
||||
title="${t('mcp.codex.copyToCodex')}">
|
||||
<i data-lucide="arrow-right" class="w-3.5 h-3.5 inline"></i> Codex
|
||||
@@ -1065,7 +1065,7 @@ function renderAvailableServerCardForCodex(serverName, serverInfo) {
|
||||
</div>
|
||||
|
||||
<div class="mt-3 pt-3 border-t border-border flex items-center gap-2">
|
||||
<button class="text-xs text-orange-500 hover:text-orange-600 transition-colors flex items-center gap-1"
|
||||
<button class="text-xs text-primary hover:text-primary/80 transition-colors flex items-center gap-1"
|
||||
onclick="copyClaudeServerToCodex('${escapeHtml(originalName)}', ${JSON.stringify(serverConfig).replace(/'/g, "'")})"
|
||||
title="${t('mcp.codex.copyToCodex')}">
|
||||
<i data-lucide="download" class="w-3 h-3"></i>
|
||||
@@ -1094,7 +1094,7 @@ function renderCodexServerCard(serverName, serverConfig) {
|
||||
: `<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">STDIO</span>`;
|
||||
|
||||
return `
|
||||
<div class="mcp-server-card bg-card border border-orange-200 dark:border-orange-800 rounded-lg p-4 hover:shadow-md transition-all cursor-pointer ${!isEnabled ? 'opacity-60' : ''}"
|
||||
<div class="mcp-server-card bg-card border border-primary/20 rounded-lg p-4 hover:shadow-md transition-all cursor-pointer ${!isEnabled ? 'opacity-60' : ''}"
|
||||
data-server-name="${escapeHtml(serverName)}"
|
||||
data-server-config="${escapeHtml(JSON.stringify(serverConfig))}"
|
||||
data-cli-type="codex"
|
||||
@@ -1102,9 +1102,9 @@ function renderCodexServerCard(serverName, serverConfig) {
|
||||
title="${t('mcp.clickToEdit')}">
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<span>${isEnabled ? '<i data-lucide="check-circle" class="w-5 h-5 text-orange-500"></i>' : '<i data-lucide="circle" class="w-5 h-5 text-muted-foreground"></i>'}</span>
|
||||
<span>${isEnabled ? '<i data-lucide="check-circle" class="w-5 h-5 text-primary"></i>' : '<i data-lucide="circle" class="w-5 h-5 text-muted-foreground"></i>'}</span>
|
||||
<h4 class="font-semibold text-foreground">${escapeHtml(serverName)}</h4>
|
||||
<span class="text-xs px-2 py-0.5 bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300 rounded-full">Codex</span>
|
||||
<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">Codex</span>
|
||||
${typeBadge}
|
||||
</div>
|
||||
<label class="mcp-toggle relative inline-flex items-center cursor-pointer" onclick="event.stopPropagation()">
|
||||
@@ -1112,7 +1112,7 @@ function renderCodexServerCard(serverName, serverConfig) {
|
||||
${isEnabled ? 'checked' : ''}
|
||||
data-server-name="${escapeHtml(serverName)}"
|
||||
data-action="toggle-codex">
|
||||
<div class="w-9 h-5 bg-hover peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-orange-500"></div>
|
||||
<div class="w-9 h-5 bg-hover peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-primary"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1170,27 +1170,29 @@ function renderCrossCliServerCard(server, isClaude) {
|
||||
|
||||
// Icon and color based on source CLI
|
||||
const icon = fromCli === 'codex' ? 'circle-dashed' : 'circle';
|
||||
const iconColor = fromCli === 'codex' ? 'orange' : 'blue';
|
||||
const sourceBadgeColor = fromCli === 'codex' ? 'orange' : 'primary';
|
||||
const sourceBadgeColor = fromCli === 'codex' ? 'green' : 'orange';
|
||||
const targetCli = isClaude ? 'project' : 'codex';
|
||||
const buttonText = isClaude ? t('mcp.codex.copyToClaude') : t('mcp.claude.copyToCodex');
|
||||
const typeBadge = isHttp
|
||||
? `<span class="text-xs px-2 py-0.5 bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300 rounded-full">HTTP</span>`
|
||||
: `<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">STDIO</span>`;
|
||||
: `<span class="text-xs px-2 py-0.5 bg-muted text-muted-foreground rounded-full">STDIO</span>`;
|
||||
|
||||
// CLI badge with color
|
||||
const cliBadge = fromCli === 'codex'
|
||||
? `<span class="text-xs px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded-full">Codex</span>`
|
||||
: `<span class="text-xs px-2 py-0.5 bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300 rounded-full">Claude</span>`;
|
||||
|
||||
return `
|
||||
<div class="mcp-server-card bg-card border border-dashed border-${iconColor}-200 dark:border-${iconColor}-800 rounded-lg p-4 hover:shadow-md hover:border-solid transition-all">
|
||||
<div class="mcp-server-card bg-card border border-dashed border-primary/20 rounded-lg p-4 hover:shadow-md hover:border-solid transition-all">
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="shrink-0">
|
||||
<i data-lucide="${icon}" class="w-5 h-5 text-${iconColor}-500"></i>
|
||||
<i data-lucide="${icon}" class="w-5 h-5 text-primary"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2 flex-wrap mb-1">
|
||||
<h4 class="font-semibold text-foreground">${escapeHtml(name)}</h4>
|
||||
<span class="text-xs px-2 py-0.5 bg-${sourceBadgeColor}/10 text-${sourceBadgeColor} rounded-full">
|
||||
${fromCli === 'codex' ? 'Codex' : 'Claude'}
|
||||
</span>
|
||||
${cliBadge}
|
||||
${typeBadge}
|
||||
</div>
|
||||
<div class="text-sm space-y-1 text-muted-foreground">
|
||||
@@ -1209,7 +1211,7 @@ function renderCrossCliServerCard(server, isClaude) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 pt-3 border-t border-border">
|
||||
<button class="w-full px-3 py-2 text-sm font-medium bg-${iconColor}-500 hover:bg-${iconColor}-600 text-white rounded-lg transition-colors flex items-center justify-center gap-1.5"
|
||||
<button class="w-full px-3 py-2 text-sm font-medium bg-primary hover:bg-primary/90 text-primary-foreground rounded-lg transition-colors flex items-center justify-center gap-1.5"
|
||||
onclick="copyCrossCliServer('${escapeHtml(name)}', ${JSON.stringify(config).replace(/'/g, "'")}, '${fromCli}', '${targetCli}')">
|
||||
<i data-lucide="copy" class="w-4 h-4"></i>
|
||||
${buttonText}
|
||||
|
||||
Reference in New Issue
Block a user