Add help view and core memory styles

- Introduced styles for the help view including tab transitions, accordion animations, search highlighting, and responsive design.
- Implemented core memory styles with modal base styles, memory card designs, and knowledge graph visualization.
- Enhanced dark mode support across various components.
- Added loading states and empty state designs for better user experience.
This commit is contained in:
catlog22
2025-12-18 18:29:45 +08:00
parent 4577be71ce
commit 17af615fe2
46 changed files with 4941 additions and 4326 deletions

View File

@@ -24,15 +24,29 @@ const MODULE_CSS_FILES = [
'07-managers.css',
'08-review.css',
'09-explorer.css',
'10-cli.css',
'11-memory.css',
'11-prompt-history.css',
'12-skills-rules.css',
'13-claude-manager.css',
'14-graph-explorer.css',
'15-mcp-manager.css',
'16-help.css',
'17-core-memory.css'
// CLI modules (split from 10-cli.css)
'10-cli-status.css',
'11-cli-history.css',
'12-cli-legacy.css',
'13-cli-ccw.css',
'14-cli-modals.css',
'15-cli-endpoints.css',
'16-cli-session.css',
'17-cli-conversation.css',
'18-cli-settings.css',
'19-cli-native-session.css',
'20-cli-taskqueue.css',
'21-cli-toolmgmt.css',
'22-cli-semantic.css',
// Other modules
'23-memory.css',
'24-prompt-history.css',
'25-skills-rules.css',
'26-claude-manager.css',
'27-graph-explorer.css',
'28-mcp-manager.css',
'29-help.css',
'30-core-memory.css'
];
const MODULE_FILES = [

View File

@@ -61,15 +61,29 @@ const MODULE_CSS_FILES = [
'07-managers.css',
'08-review.css',
'09-explorer.css',
'10-cli.css',
'11-memory.css',
'11-prompt-history.css',
'12-skills-rules.css',
'13-claude-manager.css',
'14-graph-explorer.css',
'15-mcp-manager.css',
'16-help.css',
'17-core-memory.css'
// CLI modules (split from 10-cli.css)
'10-cli-status.css',
'11-cli-history.css',
'12-cli-legacy.css',
'13-cli-ccw.css',
'14-cli-modals.css',
'15-cli-endpoints.css',
'16-cli-session.css',
'17-cli-conversation.css',
'18-cli-settings.css',
'19-cli-native-session.css',
'20-cli-taskqueue.css',
'21-cli-toolmgmt.css',
'22-cli-semantic.css',
// Other modules
'23-memory.css',
'24-prompt-history.css',
'25-skills-rules.css',
'26-claude-manager.css',
'27-graph-explorer.css',
'28-mcp-manager.css',
'29-help.css',
'30-core-memory.css'
];
// Modular JS files in dependency order

View File

@@ -0,0 +1,337 @@
/* ========================================
* CLI Manager Styles
* Unified font: system-ui for UI, monospace for code
* ======================================== */
/* ========================================
* Status Manager - Two Column Layout
* ======================================== */
.status-manager {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.status-two-column {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
align-items: start;
}
@media (max-width: 1024px) {
.status-two-column {
grid-template-columns: 1fr;
}
}
/* Section Container */
.status-section {
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.75rem;
overflow: hidden;
}
/* CLI Section - No card wrapper */
.cli-section {
/* No background, border, or card styling */
}
.cli-section .section-header {
padding: 0 0 0.75rem 0;
border-bottom: none;
background: transparent;
}
.cli-section .section-header h3 {
font-size: 0.9375rem;
}
.cli-section .tools-list,
.cli-section .ccw-list,
.cli-section .endpoint-tools-grid {
padding: 0;
}
/* Section Header */
.section-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.875rem 1rem;
border-bottom: 1px solid hsl(var(--border));
background: hsl(var(--muted) / 0.3);
}
.section-header-left {
display: flex;
align-items: center;
gap: 0.75rem;
}
.section-header h3 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
}
.section-header h3 i {
color: hsl(var(--muted-foreground));
}
.section-count {
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
}
.section-header-actions {
display: flex;
align-items: center;
gap: 0.25rem;
}
/* Tools List */
.tools-list {
padding: 0.5rem;
}
.tool-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem;
border-radius: 0.5rem;
margin-bottom: 0.375rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
transition: all 0.15s ease;
}
.tool-item:last-child {
margin-bottom: 0;
}
.tool-item:hover {
background: hsl(var(--hover));
border-color: hsl(var(--primary) / 0.3);
}
.tool-item.available {
/* No left border - use status dot instead */
}
.tool-item.unavailable {
opacity: 0.7;
}
.tool-item.endpoint {
/* No left border */
}
.tool-item-left {
display: flex;
align-items: center;
gap: 0.75rem;
}
.tool-status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.tool-status-dot.status-available {
background: hsl(var(--success));
box-shadow: 0 0 6px hsl(var(--success) / 0.5);
}
.tool-status-dot.status-unavailable {
background: hsl(var(--muted-foreground) / 0.4);
}
.tool-item-info {
display: flex;
flex-direction: column;
gap: 0.125rem;
}
.tool-item-name {
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--foreground));
display: flex;
align-items: center;
gap: 0.5rem;
}
.tool-item-desc {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.tool-default-badge {
font-size: 0.5625rem;
font-weight: 600;
padding: 0.125rem 0.375rem;
background: hsl(var(--primary));
color: hsl(var(--primary-foreground));
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.tool-type-badge {
font-size: 0.5625rem;
font-weight: 500;
padding: 0.125rem 0.375rem;
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
}
.tool-type-badge.ai {
background: hsl(var(--primary) / 0.15);
color: hsl(var(--primary));
}
.tool-type-badge.llm {
background: hsl(142 76% 36% / 0.15);
color: hsl(142 76% 36%);
}
.tool-item-right {
display: flex;
align-items: center;
gap: 0.5rem;
}
.tool-status-text {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 0.6875rem;
font-weight: 500;
}
.tool-status-text.success {
color: hsl(var(--success));
}
.tool-status-text.muted {
color: hsl(var(--muted-foreground));
}
/* CCW List */
.ccw-list {
padding: 0.5rem;
}
.ccw-item {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 0.75rem;
border-radius: 0.5rem;
margin-bottom: 0.375rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
transition: all 0.15s ease;
}
.ccw-item:last-child {
margin-bottom: 0;
}
.ccw-item:hover {
background: hsl(var(--hover));
border-color: hsl(var(--primary) / 0.3);
}
.ccw-item-left {
display: flex;
align-items: flex-start;
gap: 0.75rem;
flex: 1;
min-width: 0;
}
.ccw-item-mode {
display: flex;
align-items: center;
justify-content: center;
width: 2.25rem;
height: 2.25rem;
border-radius: 0.5rem;
flex-shrink: 0;
}
.ccw-item-mode.global {
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
}
.ccw-item-mode.path {
background: hsl(var(--warning) / 0.1);
color: hsl(var(--warning));
}
.ccw-item-info {
flex: 1;
min-width: 0;
}
.ccw-item-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.25rem;
}
.ccw-item-name {
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--foreground));
}
.ccw-item-path {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
background: hsl(var(--muted) / 0.5);
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
margin-bottom: 0.375rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ccw-item-meta {
display: flex;
gap: 0.75rem;
font-size: 0.625rem;
color: hsl(var(--muted-foreground));
}
.ccw-item-meta span {
display: flex;
align-items: center;
gap: 0.25rem;
}
.ccw-item-actions {
display: flex;
align-items: center;
gap: 0.25rem;
opacity: 0;
transition: opacity 0.15s ease;
}
.ccw-item:hover .ccw-item-actions {
opacity: 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,271 @@
/* ========================================
* History View Styles
* ======================================== */
.history-view {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.history-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 0;
margin-bottom: 1rem;
border-bottom: 1px solid hsl(var(--border));
}
.history-header-left {
display: flex;
align-items: center;
gap: 0.75rem;
}
.history-count {
font-size: 0.8125rem;
color: hsl(var(--muted-foreground));
}
.history-header-right {
display: flex;
align-items: center;
gap: 0.5rem;
}
.history-search-wrapper {
position: relative;
display: flex;
align-items: center;
}
.history-search-wrapper i {
position: absolute;
left: 0.625rem;
color: hsl(var(--muted-foreground));
pointer-events: none;
}
.history-search-input {
padding: 0.5rem 0.75rem 0.5rem 2rem;
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.8125rem;
width: 220px;
transition: all 0.2s ease;
}
.history-search-input:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.15);
width: 260px;
}
.history-search-input::placeholder {
color: hsl(var(--muted-foreground) / 0.7);
}
.history-filter-select {
padding: 0.5rem 0.75rem;
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.8125rem;
cursor: pointer;
transition: all 0.2s ease;
}
.history-filter-select:hover {
border-color: hsl(var(--primary) / 0.5);
}
.history-filter-select:focus {
outline: none;
border-color: hsl(var(--primary));
}
/* History List */
.history-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.history-item {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 1rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.15s ease;
}
.history-item:hover {
background: hsl(var(--hover));
border-color: hsl(var(--primary) / 0.3);
box-shadow: 0 2px 8px hsl(var(--foreground) / 0.05);
}
.history-item:hover .history-item-actions {
opacity: 1;
}
.history-item-main {
flex: 1;
min-width: 0;
}
.history-item-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
flex-wrap: wrap;
}
.history-tool-tag {
font-size: 0.625rem;
font-weight: 600;
padding: 0.1875rem 0.5rem;
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.history-tool-tag.tool-gemini {
background: hsl(210 80% 55% / 0.12);
color: hsl(210 80% 45%);
}
.history-tool-tag.tool-qwen {
background: hsl(280 70% 55% / 0.12);
color: hsl(280 70% 45%);
}
.history-tool-tag.tool-codex {
background: hsl(142 71% 45% / 0.12);
color: hsl(142 71% 35%);
}
.history-tool-tag.tool-claude {
background: hsl(25 90% 50% / 0.12);
color: hsl(25 90% 40%);
}
.history-mode-tag {
font-size: 0.625rem;
font-weight: 500;
padding: 0.1875rem 0.5rem;
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
}
.history-source-dir {
font-size: 0.625rem;
font-weight: 500;
padding: 0.1875rem 0.5rem;
background: hsl(var(--accent));
color: hsl(var(--accent-foreground));
border-radius: 0.25rem;
display: inline-flex;
align-items: center;
gap: 0.25rem;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.history-status {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 0.625rem;
font-weight: 500;
padding: 0.1875rem 0.5rem;
border-radius: 9999px;
}
.history-status.success {
background: hsl(var(--success) / 0.12);
color: hsl(var(--success));
}
.history-status.warning {
background: hsl(var(--warning) / 0.12);
color: hsl(var(--warning));
}
.history-status.error {
background: hsl(var(--destructive) / 0.12);
color: hsl(var(--destructive));
}
.history-item-prompt {
font-size: 0.875rem;
font-weight: 450;
color: hsl(var(--foreground));
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
line-height: 1.5;
margin-bottom: 0.5rem;
}
.history-item-meta {
display: flex;
align-items: center;
gap: 1rem;
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.history-item-meta span {
display: flex;
align-items: center;
gap: 0.25rem;
}
.history-item-actions {
display: flex;
align-items: center;
gap: 0.25rem;
opacity: 0;
transition: opacity 0.15s ease;
margin-left: 0.75rem;
}
/* History Empty State */
.history-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 4rem 2rem;
text-align: center;
color: hsl(var(--muted-foreground));
}
.history-empty-state i {
opacity: 0.3;
margin-bottom: 1rem;
}
.history-empty-state h3 {
font-size: 1rem;
font-weight: 600;
color: hsl(var(--foreground));
margin-bottom: 0.5rem;
}
.history-empty-state p {
font-size: 0.8125rem;
}

View File

@@ -0,0 +1,796 @@
/* ========================================
* Legacy Container Styles (kept for compatibility)
* ======================================== */
/* Container */
.cli-manager-container {
display: flex;
flex-direction: column;
gap: 1.25rem;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.cli-manager-grid {
display: grid;
grid-template-columns: 1.2fr 0.8fr;
gap: 1.25rem;
align-items: start;
}
@media (max-width: 768px) {
.cli-manager-grid {
grid-template-columns: 1fr;
}
}
/* Panels */
.cli-panel {
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.75rem;
overflow: hidden;
box-shadow: 0 1px 3px hsl(var(--foreground) / 0.04);
transition: box-shadow 0.2s ease;
}
.cli-panel:hover {
box-shadow: 0 4px 12px hsl(var(--foreground) / 0.08);
}
.cli-panel-full {
grid-column: 1 / -1;
}
/* Status Panel */
.cli-status-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.625rem 0.75rem;
border-bottom: 1px solid hsl(var(--border));
background: hsl(var(--muted) / 0.3);
}
.cli-status-header h3 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
letter-spacing: -0.01em;
}
.cli-status-header h3 i {
color: hsl(var(--muted-foreground));
}
.cli-tools-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 0.5rem;
padding: 0.5rem 0.625rem;
}
.cli-tool-card {
padding: 0.625rem 0.5rem;
border-radius: 0.5rem;
background: hsl(var(--background));
text-align: center;
border: 1.5px solid hsl(var(--border));
transition: all 0.2s ease;
}
.cli-tool-card.available {
background: hsl(var(--background));
}
.cli-tool-card.available:hover {
box-shadow: 0 2px 8px hsl(var(--foreground) / 0.08);
}
/* Tool-specific border colors */
.cli-tool-card.tool-gemini.available {
border-color: hsl(210 80% 55% / 0.5);
}
.cli-tool-card.tool-gemini.available:hover {
border-color: hsl(210 80% 55% / 0.7);
}
.cli-tool-card.tool-qwen.available {
border-color: hsl(280 70% 55% / 0.5);
}
.cli-tool-card.tool-qwen.available:hover {
border-color: hsl(280 70% 55% / 0.7);
}
.cli-tool-card.tool-codex.available {
border-color: hsl(142 71% 45% / 0.5);
}
.cli-tool-card.tool-codex.available:hover {
border-color: hsl(142 71% 45% / 0.7);
}
.cli-tool-card.tool-claude.available {
border-color: hsl(25 90% 50% / 0.5);
}
.cli-tool-card.tool-claude.available:hover {
border-color: hsl(25 90% 50% / 0.7);
}
.cli-tool-card.unavailable {
border-color: hsl(var(--border));
opacity: 0.6;
}
.cli-tool-header {
display: flex;
align-items: center;
justify-content: center;
gap: 0.375rem;
margin-bottom: 0.1875rem;
}
.cli-tool-status {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.cli-tool-status.status-available {
background: hsl(var(--success));
box-shadow: 0 0 6px hsl(var(--success) / 0.5);
}
.cli-tool-status.status-unavailable {
background: hsl(var(--muted-foreground) / 0.5);
}
.cli-tool-name {
font-weight: 600;
font-size: 0.8125rem;
color: hsl(var(--foreground));
letter-spacing: -0.01em;
}
.cli-tool-badge {
font-size: 0.5625rem;
font-weight: 600;
padding: 0.125rem 0.375rem;
background: hsl(var(--primary));
color: hsl(var(--primary-foreground));
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.cli-tool-info {
font-size: 0.6875rem;
margin-bottom: 0.3125rem;
color: hsl(var(--muted-foreground));
}
.cli-tool-info .text-success {
color: hsl(var(--success));
font-weight: 500;
}
/* CLI Tool Description */
.cli-tool-desc {
font-size: 0.625rem;
color: hsl(var(--muted-foreground) / 0.8);
line-height: 1.3;
}
/* CLI Tool Actions */
.cli-tool-actions {
min-height: 1.75rem;
}
/* CodexLens specific styles */
.cli-tool-card.tool-codexlens.available {
border-color: hsl(35 90% 50% / 0.5);
}
.cli-tool-card.tool-codexlens.available:hover {
border-color: hsl(35 90% 50% / 0.7);
}
/* Semantic Search specific styles */
.cli-tool-card.tool-semantic.available {
border-color: hsl(260 80% 60% / 0.5);
}
.cli-tool-card.tool-semantic.available:hover {
border-color: hsl(260 80% 60% / 0.7);
}
.cli-tool-card.tool-semantic.clickable {
cursor: pointer;
}
.cli-tool-card.tool-semantic.clickable:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px hsl(260 80% 60% / 0.15);
}
/* Execute Panel */
.cli-execute-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
border-bottom: 1px solid hsl(var(--border));
}
.cli-execute-header h3 {
font-size: 0.875rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
}
.cli-execute-form {
padding: 1rem;
}
.cli-execute-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.75rem;
margin-bottom: 0.75rem;
}
.cli-form-group {
display: flex;
flex-direction: column;
gap: 0.375rem;
}
.cli-form-group label {
font-size: 0.75rem;
font-weight: 500;
color: hsl(var(--muted-foreground));
}
.cli-select,
.cli-textarea {
padding: 0.5rem;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.875rem;
}
.cli-textarea {
min-height: 80px;
resize: vertical;
font-family: monospace;
}
.cli-select:focus,
.cli-textarea:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
}
.cli-execute-actions {
display: flex;
justify-content: flex-end;
margin-top: 0.75rem;
}
/* History Panel */
.cli-history-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.875rem 1rem;
border-bottom: 1px solid hsl(var(--border));
background: hsl(var(--muted) / 0.3);
}
.cli-history-header h3 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
letter-spacing: -0.01em;
}
.cli-history-header h3 i {
color: hsl(var(--muted-foreground));
}
.cli-history-controls {
display: flex;
align-items: center;
gap: 0.5rem;
}
/* Search Input for History */
.cli-history-search {
padding: 0.375rem 0.625rem;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.75rem;
width: 160px;
transition: all 0.2s ease;
}
.cli-history-search:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.15);
width: 200px;
}
.cli-history-search::placeholder {
color: hsl(var(--muted-foreground) / 0.7);
}
.cli-tool-filter {
padding: 0.375rem 0.625rem;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.75rem;
cursor: pointer;
transition: all 0.2s ease;
}
.cli-tool-filter:hover {
border-color: hsl(var(--primary) / 0.5);
}
.cli-tool-filter:focus {
outline: none;
border-color: hsl(var(--primary));
}
.cli-history-list {
max-height: 450px;
overflow-y: auto;
}
.cli-history-item {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 0.75rem 1rem;
border-bottom: 1px solid hsl(var(--border) / 0.5);
cursor: pointer;
transition: all 0.15s ease;
}
.cli-history-item:hover {
background: hsl(var(--hover));
}
.cli-history-item:hover .cli-history-actions {
opacity: 1;
}
.cli-history-item:last-child {
border-bottom: none;
}
.cli-history-item-content {
flex: 1;
min-width: 0;
}
.cli-history-item-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.375rem;
}
.cli-tool-tag {
font-size: 0.5625rem;
font-weight: 600;
padding: 0.125rem 0.5rem;
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.cli-tool-gemini {
background: hsl(210 80% 55% / 0.12);
color: hsl(210 80% 45%);
}
.cli-tool-qwen {
background: hsl(280 70% 55% / 0.12);
color: hsl(280 70% 45%);
}
.cli-tool-codex {
background: hsl(142 71% 45% / 0.12);
color: hsl(142 71% 35%);
}
.cli-tool-claude {
background: hsl(25 90% 50% / 0.12);
color: hsl(25 90% 40%);
}
.cli-history-time {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.cli-history-prompt {
font-size: 0.8125rem;
font-weight: 450;
color: hsl(var(--foreground));
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
line-height: 1.4;
}
.cli-history-meta {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.6875rem;
margin-top: 0.25rem;
color: hsl(var(--muted-foreground));
}
/* History Item Actions */
.cli-history-actions {
display: flex;
align-items: center;
gap: 0.25rem;
opacity: 0;
transition: opacity 0.15s ease;
margin-left: 0.5rem;
}
.cli-history-actions .btn-icon {
padding: 0.25rem;
color: hsl(var(--muted-foreground));
}
.cli-history-actions .btn-icon:hover {
color: hsl(var(--foreground));
background: hsl(var(--hover));
}
.cli-history-actions .btn-icon.btn-danger:hover {
color: hsl(var(--destructive));
background: hsl(var(--destructive) / 0.1);
}
/* Output Panel */
.cli-output-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
border-bottom: 1px solid hsl(var(--border));
}
.cli-output-header h3 {
font-size: 0.875rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
}
.cli-output-status {
display: flex;
align-items: center;
gap: 0.5rem;
}
.status-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
}
.status-indicator.running {
background: hsl(var(--warning));
animation: pulse 1.5s infinite;
}
.status-indicator.success {
background: hsl(var(--success));
}
.status-indicator.error {
background: hsl(var(--destructive));
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.cli-output-content {
padding: 1rem;
background: hsl(var(--muted));
font-family: monospace;
font-size: 0.75rem;
color: hsl(var(--foreground));
max-height: 300px;
overflow-y: auto;
white-space: pre-wrap;
word-wrap: break-word;
margin: 0;
}
/* Detail Modal */
.cli-detail-header {
margin-bottom: 1.25rem;
padding-bottom: 1rem;
border-bottom: 1px solid hsl(var(--border));
}
.cli-detail-info {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.625rem;
flex-wrap: wrap;
}
.cli-detail-status {
font-size: 0.6875rem;
font-weight: 600;
padding: 0.25rem 0.625rem;
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.cli-detail-status.status-success {
background: hsl(var(--success) / 0.12);
color: hsl(var(--success));
}
.cli-detail-status.status-error {
background: hsl(var(--destructive) / 0.12);
color: hsl(var(--destructive));
}
.cli-detail-status.status-timeout {
background: hsl(var(--warning) / 0.12);
color: hsl(var(--warning));
}
.cli-detail-meta {
display: flex;
gap: 1.25rem;
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
flex-wrap: wrap;
}
.cli-detail-meta span {
display: flex;
align-items: center;
gap: 0.375rem;
}
.cli-detail-section {
margin-bottom: 1.25rem;
}
.cli-detail-section h4 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--foreground));
margin-bottom: 0.625rem;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.cli-detail-section h4 i {
width: 14px;
height: 14px;
color: hsl(var(--muted-foreground));
}
.cli-detail-prompt {
padding: 1rem;
background: hsl(var(--muted) / 0.5);
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
font-size: 0.75rem;
line-height: 1.6;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 200px;
overflow-y: auto;
color: hsl(var(--foreground));
}
.cli-detail-output {
padding: 1rem;
background: hsl(var(--muted) / 0.5);
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
font-size: 0.75rem;
line-height: 1.6;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 350px;
overflow-y: auto;
color: hsl(var(--foreground));
}
.cli-detail-error {
padding: 1rem;
background: hsl(var(--destructive) / 0.08);
border: 1px solid hsl(var(--destructive) / 0.2);
border-radius: 0.5rem;
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
font-size: 0.75rem;
line-height: 1.6;
color: hsl(var(--destructive));
white-space: pre-wrap;
word-wrap: break-word;
max-height: 180px;
overflow-y: auto;
}
/* Detail Actions */
.cli-detail-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1.5rem;
padding-top: 1rem;
border-top: 1px solid hsl(var(--border));
}
/* Button Styles */
.btn {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.375rem;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all 0.15s ease;
}
.btn-primary {
background: hsl(var(--primary));
color: hsl(var(--primary-foreground));
}
.btn-primary:hover:not(:disabled) {
opacity: 0.9;
}
.btn-primary:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-icon {
padding: 0.375rem;
background: transparent;
border: none;
color: hsl(var(--muted-foreground));
cursor: pointer;
border-radius: 0.25rem;
transition: all 0.15s ease;
}
.btn-icon:hover {
background: hsl(var(--hover));
color: hsl(var(--foreground));
}
.btn-sm {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.25rem;
padding: 0.375rem 0.625rem;
font-size: 0.75rem;
font-weight: 500;
border-radius: 0.375rem;
border: 1px solid hsl(var(--border));
background: hsl(var(--background));
color: hsl(var(--foreground));
cursor: pointer;
transition: all 0.15s ease;
white-space: nowrap;
}
.btn-sm:hover {
background: hsl(var(--hover));
border-color: hsl(var(--primary) / 0.3);
}
.btn-sm.btn-primary {
background: hsl(var(--primary));
color: hsl(var(--primary-foreground));
border-color: hsl(var(--primary));
}
.btn-sm.btn-primary:hover {
opacity: 0.9;
}
.btn-sm.btn-outline {
background: transparent;
border-color: hsl(var(--border));
}
.btn-sm.btn-outline:hover {
background: hsl(var(--hover));
}
.btn-outline {
background: transparent;
border: 1px solid hsl(var(--border));
color: hsl(var(--foreground));
}
.btn-outline:hover {
background: hsl(var(--hover));
}
.btn-outline.btn-danger {
border-color: hsl(var(--destructive) / 0.3);
color: hsl(var(--destructive));
}
.btn-outline.btn-danger:hover {
background: hsl(var(--destructive) / 0.1);
border-color: hsl(var(--destructive) / 0.5);
}
/* Empty State */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
color: hsl(var(--muted-foreground));
}
.empty-state svg {
width: 2rem;
height: 2rem;
margin-bottom: 0.5rem;
opacity: 0.5;
}
.empty-state p {
font-size: 0.875rem;
}

View File

@@ -0,0 +1,199 @@
/* ========================================
* CCW Installation Panel Styles
* ======================================== */
/* CCW Header Actions */
.ccw-header-actions {
display: flex;
align-items: center;
gap: 0.25rem;
}
/* CCW Install Content */
.ccw-install-content {
padding: 0.5rem 0.625rem;
}
/* CCW Empty State */
.ccw-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem 1rem;
text-align: center;
color: hsl(var(--muted-foreground));
}
.ccw-empty-state i {
opacity: 0.4;
margin-bottom: 0.75rem;
}
.ccw-empty-state p {
font-size: 0.8125rem;
margin-bottom: 1rem;
}
/* ========================================
* CCW Carousel Styles
* ======================================== */
.ccw-carousel-wrapper {
position: relative;
display: flex;
align-items: center;
gap: 0.5rem;
}
.ccw-carousel-track {
display: flex;
flex: 1;
overflow: hidden;
transition: transform 0.3s ease;
}
.ccw-carousel-card {
flex: 0 0 100%;
min-width: 0;
padding: 0.625rem 0.75rem;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
transition: all 0.2s ease;
}
.ccw-carousel-card.active {
border-color: hsl(var(--primary) / 0.4);
box-shadow: 0 2px 8px hsl(var(--primary) / 0.1);
}
/* Carousel Card Header */
.ccw-card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.375rem;
}
.ccw-card-header-right {
display: flex;
align-items: center;
gap: 0.375rem;
}
.ccw-card-mode {
display: flex;
align-items: center;
gap: 0.375rem;
font-weight: 600;
font-size: 0.8125rem;
color: hsl(var(--foreground));
}
.btn-icon-sm {
padding: 0.25rem;
}
.ccw-card-mode.global {
color: hsl(var(--primary));
}
.ccw-card-mode.path {
color: hsl(var(--warning));
}
.ccw-version-tag {
font-size: 0.625rem;
font-weight: 600;
padding: 0.25rem 0.5rem;
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
border-radius: 9999px;
letter-spacing: 0.02em;
}
/* Carousel Card Path */
.ccw-card-path {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
background: hsl(var(--muted) / 0.5);
padding: 0.3125rem 0.5rem;
border-radius: 0.375rem;
margin-bottom: 0.375rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Carousel Card Meta */
.ccw-card-meta {
display: flex;
gap: 0.75rem;
font-size: 0.625rem;
color: hsl(var(--muted-foreground));
}
.ccw-card-meta span {
display: flex;
align-items: center;
gap: 0.25rem;
}
/* Carousel Card Actions - moved to header */
/* Carousel Navigation Buttons */
.ccw-carousel-btn {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
flex-shrink: 0;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: 50%;
color: hsl(var(--muted-foreground));
cursor: pointer;
transition: all 0.15s ease;
}
.ccw-carousel-btn:hover {
background: hsl(var(--hover));
color: hsl(var(--foreground));
border-color: hsl(var(--primary) / 0.3);
}
.ccw-carousel-btn:disabled {
opacity: 0.3;
cursor: not-allowed;
}
/* Carousel Dots */
.ccw-carousel-dots {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.5rem;
}
.ccw-carousel-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: hsl(var(--muted-foreground) / 0.3);
border: none;
cursor: pointer;
transition: all 0.2s ease;
}
.ccw-carousel-dot:hover {
background: hsl(var(--muted-foreground) / 0.5);
}
.ccw-carousel-dot.active {
background: hsl(var(--primary));
width: 20px;
border-radius: 4px;
}

View File

@@ -0,0 +1,258 @@
/* ========================================
* CCW Install Modal Styles
* ======================================== */
.ccw-install-modal {
padding: 0.5rem 0;
}
.ccw-install-options {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.ccw-install-option {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
background: hsl(var(--muted) / 0.3);
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.15s ease;
}
.ccw-install-option:hover {
background: hsl(var(--hover));
border-color: hsl(var(--primary) / 0.3);
}
.ccw-option-icon {
display: flex;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
border-radius: 0.5rem;
flex-shrink: 0;
}
.ccw-option-icon.global {
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
}
.ccw-option-icon.path {
background: hsl(var(--warning) / 0.1);
color: hsl(var(--warning));
}
.ccw-option-info {
flex: 1;
}
.ccw-option-title {
font-weight: 600;
font-size: 0.875rem;
color: hsl(var(--foreground));
margin-bottom: 0.25rem;
}
.ccw-option-desc {
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
}
/* Path Input Section */
.ccw-path-input-section {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid hsl(var(--border));
}
.ccw-path-input-group {
margin-bottom: 1rem;
}
.ccw-path-input-group label {
display: block;
font-size: 0.75rem;
font-weight: 500;
color: hsl(var(--muted-foreground));
margin-bottom: 0.5rem;
}
.ccw-path-input-group .cli-textarea {
width: 100%;
min-height: auto;
padding: 0.625rem 0.75rem;
font-size: 0.8125rem;
}
.ccw-install-action {
display: flex;
justify-content: flex-end;
}
/* Danger Button (icon style - subtle) */
.btn-icon.btn-danger {
color: hsl(var(--muted-foreground));
background: transparent;
}
.btn-icon.btn-danger:hover {
color: hsl(var(--destructive));
background: hsl(var(--destructive) / 0.1);
}
/* ========================================
* Generic Modal Styles
* ======================================== */
.generic-modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
opacity: 0;
transition: opacity 0.2s ease;
}
.generic-modal-overlay.active {
opacity: 1;
}
.generic-modal {
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.75rem;
width: 90%;
max-width: 600px;
max-height: 85vh;
display: flex;
flex-direction: column;
box-shadow: 0 8px 32px rgb(0 0 0 / 0.25);
transform: scale(0.95);
transition: transform 0.2s ease;
}
.generic-modal-overlay.active .generic-modal {
transform: scale(1);
}
.generic-modal.large {
max-width: 800px;
}
.generic-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.25rem;
border-bottom: 1px solid hsl(var(--border));
background: hsl(var(--muted) / 0.3);
border-radius: 0.75rem 0.75rem 0 0;
}
.generic-modal-title {
font-size: 0.9375rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
}
.generic-modal-close {
width: 2rem;
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
font-size: 1.25rem;
color: hsl(var(--muted-foreground));
cursor: pointer;
border-radius: 0.375rem;
transition: all 0.15s ease;
}
.generic-modal-close:hover {
background: hsl(var(--hover));
color: hsl(var(--foreground));
}
.generic-modal-body {
flex: 1;
overflow-y: auto;
padding: 1.25rem;
}
.generic-modal.lg {
max-width: 640px;
}
/* ========================================
* Modal Aliases (for backward compatibility)
* ======================================== */
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
opacity: 1;
transition: opacity 0.2s ease;
}
.modal-container {
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.75rem;
width: 90%;
max-width: 600px;
max-height: 85vh;
display: flex;
flex-direction: column;
box-shadow: 0 8px 32px rgb(0 0 0 / 0.25);
transform: scale(1);
transition: transform 0.2s ease;
}
.modal-container.large {
max-width: 800px;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.25rem;
border-bottom: 1px solid hsl(var(--border));
background: hsl(var(--muted) / 0.3);
border-radius: 0.75rem 0.75rem 0 0;
}
.modal-icon {
display: flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
background: hsl(var(--primary-light));
border-radius: 0.5rem;
color: hsl(var(--primary));
}
.modal-body {
flex: 1;
overflow-y: auto;
padding: 1.25rem;
}

View File

@@ -0,0 +1,305 @@
/* ========================================
* Endpoint Tools Grid Styles
* ======================================== */
.endpoint-tools-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 0.75rem;
padding: 0.75rem;
}
.endpoint-tool-card {
display: flex;
flex-direction: column;
padding: 0.875rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.2s ease;
min-height: 100px;
}
.endpoint-tool-card:hover {
background: hsl(var(--hover));
border-color: hsl(var(--indigo) / 0.5);
box-shadow: 0 2px 8px hsl(var(--indigo) / 0.1);
transform: translateY(-1px);
}
.endpoint-tool-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
}
.endpoint-tool-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: hsl(var(--indigo));
box-shadow: 0 0 6px hsl(var(--indigo) / 0.5);
flex-shrink: 0;
}
.endpoint-tool-name {
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--foreground));
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.endpoint-tool-desc {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
line-height: 1.4;
flex: 1;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
margin-bottom: 0.5rem;
}
.endpoint-tool-meta {
display: flex;
align-items: center;
gap: 0.5rem;
margin-top: auto;
}
.endpoint-tool-params {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 0.625rem;
color: hsl(var(--muted-foreground));
background: hsl(var(--muted) / 0.5);
padding: 0.1875rem 0.375rem;
border-radius: 0.25rem;
}
.endpoint-tool-required {
font-size: 0.5625rem;
color: hsl(var(--warning));
background: hsl(var(--warning) / 0.1);
padding: 0.125rem 0.375rem;
border-radius: 9999px;
font-weight: 500;
}
/* ========================================
* Tool Detail Modal Styles
* ======================================== */
.tool-detail-modal {
padding: 0.5rem 0;
}
.tool-detail-header {
display: flex;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid hsl(var(--border));
}
.tool-detail-icon {
display: flex;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
background: hsl(var(--indigo) / 0.1);
color: hsl(var(--indigo));
border-radius: 0.5rem;
flex-shrink: 0;
}
.tool-detail-title h3 {
font-size: 1rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0 0 0.375rem 0;
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
}
.tool-detail-badge {
font-size: 0.625rem;
font-weight: 500;
padding: 0.1875rem 0.5rem;
background: hsl(var(--indigo) / 0.1);
color: hsl(var(--indigo));
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.tool-detail-desc {
font-size: 0.8125rem;
color: hsl(var(--muted-foreground));
line-height: 1.6;
margin-bottom: 1.25rem;
}
.tool-detail-params h4,
.tool-detail-usage h4 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0 0 0.75rem 0;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.tool-detail-params h4 i,
.tool-detail-usage h4 i {
color: hsl(var(--muted-foreground));
}
.tool-params-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-height: 280px;
overflow-y: auto;
padding-right: 0.5rem;
}
.tool-param-item {
padding: 0.75rem;
background: hsl(var(--muted) / 0.3);
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
}
.tool-param-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.375rem;
flex-wrap: wrap;
}
.tool-param-name {
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--foreground));
background: hsl(var(--muted));
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
}
.tool-param-type {
font-size: 0.625rem;
color: hsl(var(--primary));
background: hsl(var(--primary) / 0.1);
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
}
.tool-param-required {
font-size: 0.5625rem;
font-weight: 600;
color: hsl(var(--destructive));
background: hsl(var(--destructive) / 0.1);
padding: 0.125rem 0.375rem;
border-radius: 9999px;
text-transform: uppercase;
}
.tool-param-optional {
font-size: 0.5625rem;
font-weight: 500;
color: hsl(var(--muted-foreground));
background: hsl(var(--muted));
padding: 0.125rem 0.375rem;
border-radius: 9999px;
}
.tool-param-desc {
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
line-height: 1.5;
}
.tool-param-default,
.tool-param-enum {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
margin-top: 0.25rem;
}
.tool-param-default code,
.tool-param-enum code {
font-size: 0.6875rem;
background: hsl(var(--muted));
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
color: hsl(var(--foreground));
}
.tool-detail-no-params {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 1.5rem;
background: hsl(var(--muted) / 0.3);
border: 1px dashed hsl(var(--border));
border-radius: 0.5rem;
color: hsl(var(--muted-foreground));
font-size: 0.8125rem;
}
.tool-detail-usage {
margin-top: 1.25rem;
}
.tool-usage-code {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem;
background: hsl(var(--muted) / 0.5);
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
overflow-x: auto;
}
.tool-usage-code code {
font-size: 0.75rem;
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
color: hsl(var(--foreground));
white-space: nowrap;
flex: 1;
}
.tool-copy-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 0.375rem;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: 0.25rem;
color: hsl(var(--muted-foreground));
cursor: pointer;
transition: all 0.15s ease;
flex-shrink: 0;
}
.tool-copy-btn:hover {
background: hsl(var(--hover));
color: hsl(var(--foreground));
border-color: hsl(var(--primary) / 0.3);
}

View File

@@ -0,0 +1,241 @@
/* ========================================
* Resume Session Styles
* ======================================== */
/* Resume Badge */
.history-resume-badge {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.1875rem 0.375rem;
background: hsl(var(--primary) / 0.12);
color: hsl(var(--primary));
border-radius: 0.25rem;
font-size: 0.625rem;
}
/* Resume Item Highlight */
.history-item-resume {
border-left: 3px solid hsl(var(--primary) / 0.5);
}
.history-item-resume:hover {
border-left-color: hsl(var(--primary));
}
/* History ID Display */
.history-id {
font-family: 'SF Mono', 'Consolas', 'Liberation Mono', monospace;
font-size: 0.625rem;
color: hsl(var(--muted-foreground) / 0.7);
}
/* Resume Button */
.btn-resume {
color: hsl(var(--primary));
}
.btn-resume:hover {
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
}
/* Resume Modal */
.resume-modal p {
font-size: 0.875rem;
color: hsl(var(--muted-foreground));
margin-bottom: 1rem;
}
.resume-prompt-input {
width: 100%;
padding: 0.75rem;
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.875rem;
font-family: inherit;
resize: vertical;
min-height: 80px;
transition: all 0.2s ease;
}
.resume-prompt-input:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.15);
}
.resume-prompt-input::placeholder {
color: hsl(var(--muted-foreground) / 0.7);
}
.resume-modal-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid hsl(var(--border));
}
/* ========================================
* Batch Delete & Multi-Select Styles
* ======================================== */
/* Delete Dropdown */
.history-delete-dropdown {
position: relative;
display: inline-block;
}
.delete-dropdown-menu {
display: none;
position: absolute;
top: 100%;
right: 0;
z-index: 50;
min-width: 180px;
padding: 0.375rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
box-shadow: 0 4px 16px hsl(var(--foreground) / 0.1);
margin-top: 0.25rem;
}
.delete-dropdown-menu.show {
display: block;
}
.delete-dropdown-menu button {
display: flex;
align-items: center;
gap: 0.5rem;
width: 100%;
padding: 0.5rem 0.625rem;
border: none;
background: transparent;
color: hsl(var(--foreground));
font-size: 0.75rem;
text-align: left;
cursor: pointer;
border-radius: 0.375rem;
transition: all 0.15s ease;
}
.delete-dropdown-menu button:hover {
background: hsl(var(--hover));
}
.delete-dropdown-menu button i {
color: hsl(var(--muted-foreground));
}
.delete-dropdown-menu .delete-all-btn {
color: hsl(var(--destructive));
}
.delete-dropdown-menu .delete-all-btn i {
color: hsl(var(--destructive));
}
.delete-dropdown-menu .delete-all-btn:hover {
background: hsl(var(--destructive) / 0.1);
}
.dropdown-divider {
height: 1px;
margin: 0.375rem 0;
background: hsl(var(--border));
}
/* Batch Actions Bar */
.history-batch-actions {
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.75rem 1rem;
background: hsl(var(--primary) / 0.08);
border: 1px solid hsl(var(--primary) / 0.2);
border-radius: 0.5rem;
margin-bottom: 1rem;
}
.batch-select-count {
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--primary));
margin-right: auto;
}
.btn-danger {
background: hsl(var(--destructive));
color: hsl(var(--destructive-foreground));
border-color: hsl(var(--destructive));
}
.btn-danger:hover:not(:disabled) {
opacity: 0.9;
}
.btn-danger:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Override for icon-style danger buttons (subtle, not solid red) */
.btn-icon.btn-danger,
.history-item-actions .btn-danger,
.cli-history-actions .btn-danger {
background: transparent;
color: hsl(var(--muted-foreground));
border: none;
}
.btn-icon.btn-danger:hover,
.history-item-actions .btn-danger:hover,
.cli-history-actions .btn-danger:hover {
background: hsl(var(--destructive) / 0.1);
color: hsl(var(--destructive));
opacity: 1;
}
/* Multi-Select Checkbox */
.history-checkbox-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
margin-right: 0.75rem;
flex-shrink: 0;
}
.history-checkbox {
width: 1.125rem;
height: 1.125rem;
cursor: pointer;
accent-color: hsl(var(--primary));
}
/* Selected Item State */
.history-item-selected {
background: hsl(var(--primary) / 0.08) !important;
border-color: hsl(var(--primary) / 0.3) !important;
}
/* Turn Badge for History List */
.history-turn-badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
font-size: 0.625rem;
font-weight: 600;
padding: 0.1875rem 0.5rem;
background: hsl(var(--primary) / 0.12);
color: hsl(var(--primary));
border-radius: 9999px;
}

View File

@@ -0,0 +1,283 @@
/* ========================================
* Multi-Turn Conversation Styles
* ======================================== */
/* Turn Badge in History List */
.cli-turn-badge {
font-size: 0.5625rem;
font-weight: 600;
padding: 0.125rem 0.5rem;
background: hsl(var(--primary) / 0.12);
color: hsl(var(--primary));
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.02em;
}
/* Turns Container in Detail Modal */
.cli-turns-container {
max-height: 60vh;
overflow-y: auto;
}
/* Turn Section */
.cli-turn-section {
margin-bottom: 1rem;
}
.cli-turn-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.75rem;
flex-wrap: wrap;
}
.cli-turn-number {
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.625rem;
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
border-radius: 9999px;
}
.cli-turn-status {
font-size: 0.625rem;
font-weight: 600;
padding: 0.1875rem 0.5rem;
border-radius: 9999px;
text-transform: uppercase;
}
.cli-turn-status.status-success {
background: hsl(var(--success) / 0.12);
color: hsl(var(--success));
}
.cli-turn-status.status-error {
background: hsl(var(--destructive) / 0.12);
color: hsl(var(--destructive));
}
.cli-turn-status.status-timeout {
background: hsl(var(--warning) / 0.12);
color: hsl(var(--warning));
}
.cli-turn-duration {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
/* Turn Divider (legacy) */
.cli-turn-divider {
border: none;
border-top: 1px dashed hsl(var(--border));
margin: 1.25rem 0;
}
/* Error Section (smaller in multi-turn) */
.cli-detail-error-section .cli-detail-error {
max-height: 100px;
}
/* ========================================
* Enhanced Multi-Turn Display
* ======================================== */
/* Turn Section */
.cli-turn-section {
padding: 0.75rem;
border-radius: 0.5rem;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
}
.cli-turn-section.cli-turn-latest {
border-color: hsl(var(--primary) / 0.3);
background: hsl(var(--primary) / 0.03);
}
/* Turn Header */
.cli-turn-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.75rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid hsl(var(--border));
flex-wrap: wrap;
gap: 0.5rem;
}
.cli-turn-marker {
display: flex;
align-items: center;
gap: 0.5rem;
}
.cli-turn-number {
font-size: 0.8125rem;
font-weight: 600;
color: hsl(var(--primary));
}
.cli-turn-latest-badge {
font-size: 0.5625rem;
font-weight: 600;
padding: 0.125rem 0.375rem;
background: hsl(var(--success) / 0.12);
color: hsl(var(--success));
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.cli-turn-meta {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.cli-turn-meta span {
display: flex;
align-items: center;
gap: 0.25rem;
}
.cli-turn-time i,
.cli-turn-duration i {
color: hsl(var(--muted-foreground) / 0.7);
}
/* Turn Body */
.cli-turn-body {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
/* Section Labels */
.cli-prompt-section h4 {
color: hsl(var(--primary));
}
.cli-prompt-section h4 i {
color: hsl(var(--primary));
}
.cli-output-section h4 {
color: hsl(var(--success));
}
.cli-output-section h4 i {
color: hsl(var(--success));
}
/* Turn Connector (visual line between turns) */
.cli-turn-connector {
display: flex;
justify-content: center;
padding: 0.25rem 0;
}
.cli-turn-line {
width: 2px;
height: 1.5rem;
background: linear-gradient(
to bottom,
hsl(var(--border)),
hsl(var(--primary) / 0.3),
hsl(var(--border))
);
border-radius: 1px;
}
/* Truncated Notice */
.cli-truncated-notice {
display: flex;
align-items: center;
gap: 0.375rem;
font-size: 0.75rem;
color: hsl(var(--warning));
margin-top: 0.5rem;
padding: 0.375rem 0.625rem;
background: hsl(var(--warning) / 0.08);
border-radius: 0.25rem;
}
.cli-truncated-notice i {
flex-shrink: 0;
}
/* Turn Badge with Icon */
.cli-turn-badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
.cli-turn-badge i {
width: 12px;
height: 12px;
}
/* ========================================
* Conversation View Toggle
* ======================================== */
/* View Toggle Bar */
.cli-view-toggle {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
padding: 0.5rem;
background: hsl(var(--muted) / 0.3);
border-radius: 0.5rem;
}
.cli-view-toggle .btn {
flex: 1;
justify-content: center;
}
.cli-view-toggle .btn.active {
background: hsl(var(--primary));
color: hsl(var(--primary-foreground));
border-color: hsl(var(--primary));
}
/* Concatenated Prompt Section */
.cli-concat-section {
margin-top: 1rem;
}
.cli-concat-format-selector {
display: flex;
gap: 0.375rem;
margin-bottom: 0.75rem;
}
.cli-concat-format-selector .btn-xs {
padding: 0.25rem 0.625rem;
font-size: 0.6875rem;
}
.cli-concat-output {
max-height: 400px;
overflow-y: auto;
font-size: 0.75rem;
white-space: pre-wrap;
word-break: break-word;
}
/* Button Sizes */
.btn-xs {
padding: 0.25rem 0.5rem;
font-size: 0.6875rem;
border-radius: 0.25rem;
}

View File

@@ -0,0 +1,160 @@
/* ========================================
* CLI Settings Section
* ======================================== */
.cli-settings-section {
/* No card wrapper - just title and cards */
}
.cli-settings-section .section-header {
padding: 0 0 0.75rem 0;
border-bottom: none;
background: transparent;
}
.cli-settings-section .section-header h3 {
font-size: 0.9375rem;
}
.cli-settings-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.75rem;
}
@media (max-width: 1200px) {
.cli-settings-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 640px) {
.cli-settings-grid {
grid-template-columns: 1fr;
}
}
.cli-setting-item {
padding: 0.75rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
display: flex;
flex-direction: column;
min-height: 90px;
}
.cli-setting-label {
display: flex;
align-items: center;
gap: 0.375rem;
font-size: 0.6875rem;
font-weight: 600;
color: hsl(var(--muted-foreground));
text-transform: uppercase;
letter-spacing: 0.025em;
margin-bottom: 0.5rem;
}
.cli-setting-label i {
color: hsl(var(--primary));
width: 12px;
height: 12px;
}
.cli-setting-control {
margin-bottom: 0.5rem;
flex-shrink: 0;
}
.cli-setting-select {
width: 100%;
padding: 0.4375rem 0.5rem;
font-size: 0.8125rem;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
color: hsl(var(--foreground));
cursor: pointer;
transition: all 0.15s ease;
}
.cli-setting-select:hover {
border-color: hsl(var(--primary) / 0.5);
}
.cli-setting-select:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.1);
}
.cli-setting-desc {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
line-height: 1.3;
margin-top: auto;
}
.cli-setting-value {
font-size: 0.875rem;
color: hsl(var(--foreground));
font-weight: 500;
}
/* Toggle Switch */
.cli-toggle {
position: relative;
display: inline-block;
width: 36px;
height: 20px;
}
.cli-toggle input {
opacity: 0;
width: 0;
height: 0;
}
.cli-toggle-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: hsl(var(--muted));
transition: 0.3s;
border-radius: 20px;
}
.cli-toggle-slider:before {
position: absolute;
content: "";
height: 14px;
width: 14px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.3s;
border-radius: 50%;
}
.cli-toggle input:checked + .cli-toggle-slider {
background-color: hsl(var(--primary));
}
.cli-toggle input:checked + .cli-toggle-slider:before {
transform: translateX(16px);
}
.cli-toggle input:focus + .cli-toggle-slider {
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
}
/* Disabled state for settings */
.cli-setting-item.disabled {
opacity: 0.5;
pointer-events: none;
}

View File

@@ -0,0 +1,496 @@
/* ========================================
* Native Session Styles
* ======================================== */
/* Native badge in history list */
.cli-native-badge {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.125rem 0.375rem;
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
border-radius: 0.25rem;
font-size: 0.625rem;
}
.cli-history-item.has-native {
border-left: 2px solid hsl(var(--primary) / 0.5);
}
/* Mode tag */
.cli-mode-tag {
display: inline-flex;
align-items: center;
padding: 0.125rem 0.375rem;
font-size: 0.625rem;
font-weight: 500;
color: hsl(var(--muted-foreground));
background: hsl(var(--muted));
border-radius: 0.25rem;
}
/* Status badge */
.cli-status-badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.125rem 0.375rem;
font-size: 0.625rem;
font-weight: 500;
border-radius: 0.25rem;
}
.cli-status-badge.text-success {
background: hsl(var(--success) / 0.1);
color: hsl(var(--success));
}
.cli-status-badge.text-warning {
background: hsl(var(--warning) / 0.1);
color: hsl(var(--warning));
}
.cli-status-badge.text-destructive {
background: hsl(var(--destructive) / 0.1);
color: hsl(var(--destructive));
}
/* Native Session Detail Modal */
.native-session-detail {
font-family: system-ui, -apple-system, sans-serif;
}
.native-session-header {
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid hsl(var(--border));
}
.native-session-info {
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
margin-bottom: 0.5rem;
}
.native-model,
.native-session-id {
display: inline-flex;
align-items: center;
gap: 0.25rem;
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
}
.native-session-meta {
display: flex;
flex-wrap: wrap;
gap: 1rem;
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.native-session-meta span {
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
/* Tokens Summary */
.native-tokens-summary {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1rem;
margin-bottom: 1rem;
background: hsl(var(--muted) / 0.5);
border-radius: 0.5rem;
font-size: 0.75rem;
color: hsl(var(--foreground));
}
/* Native Turns Container */
.native-turns-container {
max-height: 60vh;
overflow-y: auto;
padding-right: 0.5rem;
}
/* Native Turn */
.native-turn {
margin-bottom: 1rem;
padding: 0.875rem;
border-radius: 0.5rem;
border: 1px solid hsl(var(--border));
}
.native-turn.user {
background: hsl(var(--muted) / 0.3);
border-left: 3px solid hsl(var(--primary));
}
.native-turn.assistant {
background: hsl(var(--background));
border-left: 3px solid hsl(var(--success));
}
.native-turn.latest {
box-shadow: 0 0 0 1px hsl(var(--primary) / 0.3);
}
.native-turn-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.625rem;
flex-wrap: wrap;
}
.native-turn-role {
display: inline-flex;
align-items: center;
gap: 0.25rem;
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--foreground));
}
.native-turn-number {
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.native-turn-tokens {
display: inline-flex;
align-items: center;
gap: 0.25rem;
font-size: 0.625rem;
color: hsl(var(--muted-foreground));
padding: 0.125rem 0.375rem;
background: hsl(var(--muted));
border-radius: 0.25rem;
}
.native-turn-latest {
font-size: 0.625rem;
font-weight: 500;
padding: 0.125rem 0.375rem;
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
border-radius: 0.25rem;
}
.native-turn-content pre {
margin: 0;
padding: 0.75rem;
background: hsl(var(--muted));
border-radius: 0.375rem;
font-family: monospace;
font-size: 0.75rem;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 300px;
overflow-y: auto;
}
/* Thoughts Section */
.native-thoughts-section {
margin-top: 0.75rem;
padding: 0.625rem;
background: hsl(var(--warning) / 0.05);
border: 1px solid hsl(var(--warning) / 0.2);
border-radius: 0.375rem;
}
.native-thoughts-section h5 {
display: flex;
align-items: center;
gap: 0.375rem;
font-size: 0.6875rem;
font-weight: 600;
color: hsl(var(--warning));
margin: 0 0 0.5rem 0;
}
.native-thoughts-list {
margin: 0;
padding-left: 1.25rem;
font-size: 0.6875rem;
color: hsl(var(--foreground));
}
.native-thoughts-list li {
margin-bottom: 0.25rem;
}
/* Tool Calls Section */
.native-tools-section {
margin-top: 0.75rem;
padding: 0.625rem;
background: hsl(var(--muted) / 0.5);
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
}
.native-tools-section h5 {
display: flex;
align-items: center;
gap: 0.375rem;
font-size: 0.6875rem;
font-weight: 600;
color: hsl(var(--muted-foreground));
margin: 0 0 0.5rem 0;
}
.native-tools-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.native-tool-call {
padding: 0.5rem;
background: hsl(var(--background));
border-radius: 0.25rem;
}
.native-tool-name {
display: inline-block;
font-family: monospace;
font-size: 0.6875rem;
font-weight: 600;
color: hsl(var(--primary));
margin-bottom: 0.25rem;
}
.native-tool-output {
margin: 0.25rem 0 0 0;
padding: 0.375rem;
background: hsl(var(--muted));
border-radius: 0.25rem;
font-family: monospace;
font-size: 0.625rem;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 100px;
overflow-y: auto;
}
/* Native Session Actions */
.native-session-actions {
display: flex;
gap: 0.5rem;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid hsl(var(--border));
flex-wrap: wrap;
}
/* ========================================
* Enhanced Native Session Display
* ======================================== */
/* View Full Process Button in Execution Detail */
.cli-detail-native-action {
margin-top: 0.75rem;
padding-top: 0.75rem;
border-top: 1px solid hsl(var(--border) / 0.5);
}
.cli-detail-native-action .btn {
font-size: 0.8125rem;
gap: 0.5rem;
}
/* Collapsible Thinking Process */
.turn-thinking-details {
border: none;
margin: 0;
}
.turn-thinking-summary {
display: flex;
align-items: center;
gap: 0.375rem;
cursor: pointer;
padding: 0.5rem;
background: hsl(var(--warning) / 0.08);
border: 1px solid hsl(var(--warning) / 0.25);
border-radius: 0.375rem;
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--warning));
transition: all 0.2s ease;
list-style: none;
}
.turn-thinking-summary::-webkit-details-marker {
display: none;
}
.turn-thinking-summary:hover {
background: hsl(var(--warning) / 0.15);
border-color: hsl(var(--warning) / 0.4);
}
.turn-thinking-summary::before {
content: '▶';
display: inline-block;
margin-right: 0.25rem;
transition: transform 0.2s ease;
font-size: 0.6875rem;
}
.turn-thinking-details[open] .turn-thinking-summary::before {
transform: rotate(90deg);
}
.turn-thinking-content {
padding: 0.75rem;
margin-top: 0.5rem;
background: hsl(var(--warning) / 0.03);
border: 1px solid hsl(var(--warning) / 0.15);
border-radius: 0.375rem;
font-style: italic;
}
.turn-thinking-content ul {
margin: 0;
padding-left: 1.25rem;
}
.turn-thinking-content li {
margin-bottom: 0.375rem;
font-size: 0.6875rem;
line-height: 1.6;
color: hsl(var(--foreground) / 0.85);
}
/* Tool Calls Header */
.turn-tool-calls-header {
display: flex;
align-items: center;
gap: 0.375rem;
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--muted-foreground));
margin-bottom: 0.625rem;
padding-bottom: 0.375rem;
border-bottom: 1px solid hsl(var(--border) / 0.5);
}
/* Collapsible Tool Calls */
.turn-tool-call-details {
border: none;
margin-bottom: 0.5rem;
}
.turn-tool-call-summary {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
padding: 0.5rem 0.75rem;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
font-size: 0.7rem;
transition: all 0.2s ease;
list-style: none;
}
.turn-tool-call-summary::-webkit-details-marker {
display: none;
}
.turn-tool-call-summary:hover {
background: hsl(var(--muted) / 0.5);
border-color: hsl(var(--primary) / 0.4);
}
.turn-tool-call-summary::before {
content: '▶';
display: inline-block;
margin-right: 0.5rem;
transition: transform 0.2s ease;
font-size: 0.625rem;
color: hsl(var(--muted-foreground));
}
.turn-tool-call-details[open] .turn-tool-call-summary::before {
transform: rotate(90deg);
}
.native-tool-size {
font-size: 0.625rem;
color: hsl(var(--muted-foreground));
font-weight: 400;
}
.turn-tool-call-content {
padding: 0.75rem;
margin-top: 0.5rem;
background: hsl(var(--muted) / 0.3);
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.turn-tool-input,
.turn-tool-output {
margin-bottom: 0.75rem;
}
.turn-tool-input:last-child,
.turn-tool-output:last-child {
margin-bottom: 0;
}
.turn-tool-input strong,
.turn-tool-output strong {
display: block;
font-size: 0.6875rem;
font-weight: 600;
color: hsl(var(--foreground));
margin-bottom: 0.375rem;
}
.turn-tool-input pre,
.turn-tool-output pre {
margin: 0;
padding: 0.5rem;
background: hsl(var(--background));
border: 1px solid hsl(var(--border));
border-radius: 0.25rem;
font-family: monospace;
font-size: 0.6875rem;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 400px;
overflow-y: auto;
}
/* Improved scrollbar for tool output */
.turn-tool-output pre::-webkit-scrollbar {
width: 6px;
}
.turn-tool-output pre::-webkit-scrollbar-track {
background: hsl(var(--muted));
border-radius: 3px;
}
.turn-tool-output pre::-webkit-scrollbar-thumb {
background: hsl(var(--muted-foreground) / 0.3);
border-radius: 3px;
}
.turn-tool-output pre::-webkit-scrollbar-thumb:hover {
background: hsl(var(--muted-foreground) / 0.5);
}

View File

@@ -0,0 +1,188 @@
/* ========================================
* Task Queue Sidebar - CLI Tab Styles
* ======================================== */
/* Tab Navigation */
.task-queue-tabs {
display: flex;
gap: 0;
border-bottom: 1px solid hsl(var(--border));
padding: 0 1rem;
}
.task-queue-tab {
flex: 1;
padding: 0.625rem 0.75rem;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
color: hsl(var(--muted-foreground));
font-size: 0.8125rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 0.375rem;
}
.task-queue-tab:hover {
color: hsl(var(--foreground));
background: hsl(var(--muted) / 0.3);
}
.task-queue-tab.active {
color: hsl(var(--primary));
border-bottom-color: hsl(var(--primary));
}
.task-queue-tab .tab-badge {
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
padding: 0.125rem 0.375rem;
border-radius: 9999px;
font-size: 0.6875rem;
font-weight: 600;
min-width: 1.25rem;
text-align: center;
}
.task-queue-tab.active .tab-badge {
background: hsl(var(--primary) / 0.15);
color: hsl(var(--primary));
}
/* CLI Filter Buttons */
.cli-filter-btn {
padding: 0.375rem 0.625rem;
background: transparent;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
color: hsl(var(--muted-foreground));
font-size: 0.75rem;
cursor: pointer;
transition: all 0.15s;
white-space: nowrap;
}
.cli-filter-btn:hover {
background: hsl(var(--muted) / 0.5);
color: hsl(var(--foreground));
}
.cli-filter-btn.active {
background: hsl(var(--primary));
border-color: hsl(var(--primary));
color: hsl(var(--primary-foreground));
}
/* CLI Queue Item */
.cli-queue-item {
padding: 0.75rem;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
margin-bottom: 0.5rem;
cursor: pointer;
transition: all 0.15s;
}
.cli-queue-item:hover {
background: hsl(var(--muted) / 0.5);
border-color: hsl(var(--primary) / 0.3);
}
.cli-queue-item.category-user {
border-left: 3px solid #3b82f6;
}
.cli-queue-item.category-insight {
border-left: 3px solid #a855f7;
}
.cli-queue-item.category-internal {
border-left: 3px solid #22c55e;
}
.cli-queue-item-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.375rem;
}
.cli-queue-category-icon {
font-size: 0.875rem;
}
.cli-queue-tool-tag {
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
font-size: 0.625rem;
font-weight: 600;
text-transform: uppercase;
}
.cli-queue-tool-tag.cli-tool-gemini {
background: hsl(210 100% 50% / 0.15);
color: hsl(210 100% 45%);
}
.cli-queue-tool-tag.cli-tool-qwen {
background: hsl(280 100% 50% / 0.15);
color: hsl(280 100% 40%);
}
.cli-queue-tool-tag.cli-tool-codex {
background: hsl(145 60% 45% / 0.15);
color: hsl(145 60% 35%);
}
.cli-queue-tool-tag.cli-tool-claude {
background: hsl(25 90% 50% / 0.15);
color: hsl(25 90% 40%);
}
.cli-queue-status {
font-size: 0.75rem;
}
.cli-queue-time {
margin-left: auto;
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.cli-queue-prompt {
font-size: 0.75rem;
color: hsl(var(--foreground));
line-height: 1.4;
margin-bottom: 0.375rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cli-queue-meta {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.6875rem;
color: hsl(var(--muted-foreground));
}
.cli-queue-id {
font-family: monospace;
}
.cli-queue-turns {
background: hsl(var(--muted));
padding: 0.0625rem 0.25rem;
border-radius: 0.25rem;
}
.cli-queue-native {
font-size: 0.75rem;
}

View File

@@ -0,0 +1,310 @@
/* ========================================
* CLI Tool Management Styles
* ======================================== */
/* Disabled tool card */
.cli-tool-card.disabled {
opacity: 0.6;
}
.cli-tool-card.disabled .cli-tool-header {
opacity: 0.8;
}
/* Disabled status indicator */
.cli-tool-status.status-disabled {
background: hsl(var(--warning));
}
/* Warning badge */
.cli-tool-badge.badge-warning {
background: hsl(var(--warning) / 0.15);
color: hsl(var(--warning));
font-size: 0.65rem;
padding: 0.125rem 0.375rem;
border-radius: 0.25rem;
margin-left: 0.25rem;
}
/* Compact toggle for tool cards */
.cli-toggle-compact {
position: relative;
display: inline-block;
width: 28px;
height: 16px;
cursor: pointer;
}
.cli-toggle-compact input {
opacity: 0;
width: 0;
height: 0;
position: absolute;
}
.cli-toggle-slider-compact {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: hsl(var(--muted));
transition: 0.2s;
border-radius: 16px;
}
.cli-toggle-slider-compact:before {
position: absolute;
content: "";
height: 12px;
width: 12px;
left: 2px;
bottom: 2px;
background-color: white;
transition: 0.2s;
border-radius: 50%;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
.cli-toggle-compact input:checked + .cli-toggle-slider-compact {
background-color: hsl(var(--primary));
}
.cli-toggle-compact input:checked + .cli-toggle-slider-compact:before {
transform: translateX(12px);
}
.cli-toggle-compact input:focus + .cli-toggle-slider-compact {
box-shadow: 0 0 0 2px hsl(var(--ring) / 0.5);
}
/* Language Setting Status Badge */
.cli-setting-status {
margin-left: 0.75rem;
padding: 0.25rem 0.625rem;
font-size: 0.6875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.03em;
border-radius: 0.25rem;
display: inline-flex;
align-items: center;
}
.cli-setting-status.enabled {
background: hsl(var(--primary) / 0.15);
color: hsl(var(--primary));
}
.cli-setting-status.disabled {
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
}
/* Ghost button variant for destructive actions */
.btn-ghost.text-destructive {
color: hsl(var(--destructive));
}
/* ========================================
* Tool Configuration Modal
* ======================================== */
/* Tool item clickable */
.tool-item.clickable {
cursor: pointer;
transition: all 0.15s ease;
}
.tool-item.clickable:hover {
background: hsl(var(--accent));
border-color: hsl(var(--primary) / 0.3);
}
.tool-item.clickable:hover .tool-config-icon {
opacity: 1;
}
.tool-config-icon {
margin-left: 0.375rem;
color: hsl(var(--muted-foreground));
opacity: 0;
transition: opacity 0.15s ease;
}
/* Tool Config Modal */
.tool-config-modal {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.tool-config-section {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.tool-config-section h4 {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.025em;
color: hsl(var(--muted-foreground));
margin: 0;
}
.tool-config-section h4 .text-muted {
font-weight: 400;
text-transform: none;
color: hsl(var(--muted-foreground) / 0.7);
}
/* Status Badges */
.tool-config-badges {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.25rem 0.5rem;
font-size: 0.6875rem;
font-weight: 500;
border-radius: 9999px;
}
.badge-success {
background: hsl(var(--success) / 0.15);
color: hsl(var(--success));
}
.badge-primary {
background: hsl(var(--primary) / 0.15);
color: hsl(var(--primary));
}
.badge-muted {
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
}
/* Config Actions */
.tool-config-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.btn-danger-outline {
border-color: hsl(var(--destructive) / 0.5);
color: hsl(var(--destructive));
}
.btn-danger-outline:hover {
background: hsl(var(--destructive) / 0.1);
border-color: hsl(var(--destructive));
}
/* Config Selects and Inputs */
.tool-config-select,
.tool-config-input {
width: 100%;
padding: 0.5rem 0.75rem;
font-size: 0.8125rem;
font-family: inherit;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.tool-config-select:focus,
.tool-config-input:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
}
.tool-config-select {
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.25rem;
padding-right: 2rem;
}
.tool-config-input.hidden {
display: none;
}
.tool-config-input {
margin-top: 0.375rem;
}
/* Config Footer */
.tool-config-footer {
display: flex;
justify-content: flex-end;
gap: 0.75rem;
padding: 1rem 1.25rem 1.25rem 1.25rem;
border-top: 1px solid hsl(var(--border));
margin-top: 0.5rem;
}
.tool-config-footer .btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.375rem;
padding: 0.5rem 1rem;
font-size: 0.8125rem;
font-weight: 500;
border-radius: 0.375rem;
cursor: pointer;
transition: all 0.15s ease;
}
.tool-config-footer .btn-outline {
background: transparent;
border: 1px solid hsl(var(--border));
color: hsl(var(--foreground));
}
.tool-config-footer .btn-outline:hover {
background: hsl(var(--muted));
border-color: hsl(var(--muted-foreground) / 0.3);
}
.tool-config-footer .btn-primary {
background: hsl(var(--primary));
border: 1px solid hsl(var(--primary));
color: hsl(var(--primary-foreground));
}
.tool-config-footer .btn-primary:hover {
background: hsl(var(--primary) / 0.9);
}
/* Model Select Group */
.model-select-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.model-select-group .tool-config-input {
margin-top: 0;
}
.btn-ghost.text-destructive:hover {
background: hsl(var(--destructive) / 0.1);
}

View File

@@ -0,0 +1,240 @@
/* ========================================
* Semantic Metadata Viewer Styles
* ======================================== */
.semantic-viewer-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
background: hsl(var(--muted) / 0.3);
border-bottom: 1px solid hsl(var(--border));
}
.semantic-table-container {
max-height: 400px;
overflow-y: auto;
}
.semantic-table {
width: 100%;
border-collapse: collapse;
font-size: 0.8125rem;
}
.semantic-table th {
position: sticky;
top: 0;
background: hsl(var(--card));
padding: 0.625rem 0.75rem;
text-align: left;
font-weight: 600;
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
border-bottom: 1px solid hsl(var(--border));
white-space: nowrap;
}
.semantic-table td {
padding: 0.625rem 0.75rem;
border-bottom: 1px solid hsl(var(--border) / 0.5);
vertical-align: top;
}
.semantic-row {
cursor: pointer;
transition: background 0.15s ease;
}
.semantic-row:hover {
background: hsl(var(--hover));
}
.semantic-cell-file {
max-width: 200px;
}
.semantic-cell-lang {
width: 80px;
color: hsl(var(--muted-foreground));
}
.semantic-cell-purpose {
max-width: 180px;
color: hsl(var(--foreground) / 0.8);
}
.semantic-cell-keywords {
max-width: 160px;
}
.semantic-cell-tool {
width: 70px;
}
.semantic-cell-date {
width: 80px;
color: hsl(var(--muted-foreground));
font-size: 0.75rem;
}
.semantic-keyword {
display: inline-block;
padding: 0.125rem 0.375rem;
margin: 0.125rem;
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
border-radius: 0.25rem;
font-size: 0.6875rem;
}
.semantic-keyword-more {
display: inline-block;
padding: 0.125rem 0.375rem;
margin: 0.125rem;
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
font-size: 0.6875rem;
}
.tool-badge {
display: inline-block;
padding: 0.125rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.6875rem;
font-weight: 500;
text-transform: capitalize;
}
.tool-badge.tool-gemini {
background: hsl(210 80% 55% / 0.15);
color: hsl(210 80% 45%);
}
.tool-badge.tool-qwen {
background: hsl(142 76% 36% / 0.15);
color: hsl(142 76% 36%);
}
.tool-badge.tool-unknown {
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
}
.semantic-detail-row {
background: hsl(var(--muted) / 0.2);
}
.semantic-detail-row.hidden {
display: none;
}
.semantic-detail-content {
padding: 1rem;
}
.semantic-detail-section {
margin-bottom: 1rem;
}
.semantic-detail-section h4 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.75rem;
font-weight: 600;
color: hsl(var(--muted-foreground));
margin-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.semantic-detail-section p {
font-size: 0.8125rem;
line-height: 1.5;
color: hsl(var(--foreground));
}
.semantic-keywords-full {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
}
.semantic-detail-meta {
display: flex;
gap: 1rem;
padding-top: 0.75rem;
border-top: 1px solid hsl(var(--border) / 0.5);
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
}
.semantic-detail-meta span {
display: flex;
align-items: center;
gap: 0.375rem;
}
.semantic-viewer-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
background: hsl(var(--muted) / 0.3);
border-top: 1px solid hsl(var(--border));
}
.semantic-loading,
.semantic-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3rem;
text-align: center;
color: hsl(var(--muted-foreground));
}
.semantic-loading {
gap: 1rem;
}
/* ========================================
* CodexLens Test Search Results
* ======================================== */
#searchResults {
margin-top: 0.5rem;
}
#searchResults > div {
display: flex;
flex-direction: column;
max-height: 200px;
overflow: hidden;
background: hsl(var(--muted) / 0.3);
border-radius: 0.5rem;
padding: 0.75rem;
}
#searchResults .flex.items-center {
flex-shrink: 0;
margin-bottom: 0.5rem;
}
#searchResultContent {
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
font-size: 0.75rem;
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-all;
color: hsl(var(--foreground) / 0.9);
background: hsl(var(--background) / 0.5);
border-radius: 0.375rem;
padding: 0.5rem;
margin: 0;
}

View File

@@ -130,14 +130,14 @@
.stat-label {
font-size: 0.875rem;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
margin-bottom: 0.25rem;
}
.stat-value {
font-size: 1.5rem;
font-weight: 600;
color: var(--text-primary);
color: hsl(var(--foreground));
}
/* Memories Grid */
@@ -155,8 +155,8 @@
/* Memory Card */
.memory-card {
background: var(--card-bg);
border: 1px solid var(--border-color);
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 8px;
padding: 1.25rem;
transition: all 0.2s ease;
@@ -184,7 +184,7 @@
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
flex-wrap: wrap;
}
@@ -203,7 +203,7 @@
border: none;
padding: 0.25rem;
cursor: pointer;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
transition: color 0.2s;
display: flex;
align-items: center;
@@ -211,11 +211,11 @@
}
.icon-btn:hover {
color: var(--text-primary);
color: hsl(var(--foreground));
}
.icon-btn.danger:hover {
color: var(--danger-color);
color: hsl(var(--destructive));
}
.icon-btn i {
@@ -231,13 +231,13 @@
.memory-summary {
font-size: 0.9375rem;
line-height: 1.6;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.memory-preview {
font-size: 0.875rem;
line-height: 1.5;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
}
/* Memory Tags */
@@ -250,8 +250,8 @@
.tag {
padding: 0.25rem 0.75rem;
background: var(--accent-bg);
color: var(--accent-color);
background: hsl(var(--accent));
color: hsl(var(--primary));
border-radius: 4px;
font-size: 0.75rem;
font-weight: 500;
@@ -263,14 +263,14 @@
flex-direction: column;
gap: 0.75rem;
padding-top: 1rem;
border-top: 1px solid var(--border-color);
border-top: 1px solid hsl(var(--border));
}
.memory-meta {
display: flex;
gap: 1rem;
font-size: 0.8125rem;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
flex-wrap: wrap;
}
@@ -293,8 +293,8 @@
.feature-btn {
padding: 0.375rem 0.75rem;
background: var(--secondary-bg);
border: 1px solid var(--border-color);
background: hsl(var(--muted));
border: 1px solid hsl(var(--border));
border-radius: 4px;
font-size: 0.8125rem;
cursor: pointer;
@@ -302,12 +302,12 @@
display: flex;
align-items: center;
gap: 0.375rem;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.feature-btn:hover {
background: var(--hover-bg);
border-color: var(--accent-color);
background: hsl(var(--hover));
border-color: hsl(var(--primary));
}
.feature-btn i {
@@ -362,17 +362,17 @@
display: block;
font-weight: 500;
margin-bottom: 0.5rem;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.form-group textarea,
.form-group input[type="text"] {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--border-color);
border: 1px solid hsl(var(--border));
border-radius: 6px;
background: var(--input-bg);
color: var(--text-primary);
background: hsl(var(--background));
color: hsl(var(--foreground));
font-family: inherit;
font-size: 0.9375rem;
resize: vertical;
@@ -381,8 +381,8 @@
.form-group textarea:focus,
.form-group input[type="text"]:focus {
outline: none;
border-color: var(--accent-color);
box-shadow: 0 0 0 3px var(--accent-shadow, rgba(99, 102, 241, 0.1));
border-color: hsl(var(--primary));
box-shadow: 0 0 0 3px hsl(var(--primary) / 0.1);
}
/* Memory Detail Content */
@@ -396,19 +396,19 @@
font-size: 1rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.detail-text {
font-size: 0.9375rem;
line-height: 1.6;
color: var(--text-primary);
color: hsl(var(--foreground));
white-space: pre-wrap;
}
.detail-code {
background: var(--secondary-bg);
border: 1px solid var(--border-color);
background: hsl(var(--muted));
border: 1px solid hsl(var(--border));
border-radius: 6px;
padding: 1rem;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
@@ -430,7 +430,7 @@
font-size: 1rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.entities-list,
@@ -442,8 +442,8 @@
.entity-item {
padding: 0.75rem;
background: var(--secondary-bg);
border: 1px solid var(--border-color);
background: hsl(var(--muted));
border: 1px solid hsl(var(--border));
border-radius: 6px;
display: flex;
justify-content: space-between;
@@ -452,21 +452,21 @@
.entity-name {
font-weight: 500;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.entity-type {
padding: 0.25rem 0.5rem;
background: var(--accent-bg);
color: var(--accent-color);
background: hsl(var(--accent));
color: hsl(var(--primary));
border-radius: 4px;
font-size: 0.75rem;
}
.relationship-item {
padding: 0.75rem;
background: var(--secondary-bg);
border: 1px solid var(--border-color);
background: hsl(var(--muted));
border: 1px solid hsl(var(--border));
border-radius: 6px;
display: flex;
align-items: center;
@@ -477,13 +477,13 @@
.rel-target {
flex: 1;
font-weight: 500;
color: var(--text-primary);
color: hsl(var(--foreground));
}
.rel-type {
padding: 0.25rem 0.5rem;
background: var(--info-bg, #dbeafe);
color: var(--info-color, #1e3a8a);
background: hsl(var(--info) / 0.15);
color: hsl(var(--info));
border-radius: 4px;
font-size: 0.75rem;
white-space: nowrap;
@@ -498,9 +498,9 @@
.evolution-version {
padding: 1rem;
background: var(--secondary-bg);
border: 1px solid var(--border-color);
border-left: 3px solid var(--accent-color);
background: hsl(var(--muted));
border: 1px solid hsl(var(--border));
border-left: 3px solid hsl(var(--primary));
border-radius: 6px;
}
@@ -513,17 +513,17 @@
.version-number {
font-weight: 600;
color: var(--accent-color);
color: hsl(var(--primary));
}
.version-date {
font-size: 0.8125rem;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
}
.version-reason {
font-size: 0.875rem;
color: var(--text-primary);
color: hsl(var(--foreground));
margin-top: 0.5rem;
}
@@ -531,7 +531,7 @@
.empty-state {
text-align: center;
padding: 3rem 1rem;
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
}
.empty-state i {
@@ -546,7 +546,7 @@
}
.empty-text {
color: var(--text-secondary);
color: hsl(var(--muted-foreground));
font-style: italic;
}
@@ -573,6 +573,219 @@
}
}
/* ============================================
Knowledge Graph D3 Visualization Styles
============================================ */
.knowledge-graph-container {
width: 100%;
min-height: 400px;
background: hsl(var(--muted) / 0.3);
border: 1px solid hsl(var(--border));
border-radius: 8px;
overflow: hidden;
}
.knowledge-graph-svg {
display: block;
width: 100%;
height: 100%;
}
.graph-content {
cursor: grab;
}
.graph-content:active {
cursor: grabbing;
}
.graph-edge {
stroke: hsl(var(--muted-foreground));
stroke-width: 1.5;
stroke-opacity: 0.6;
fill: none;
}
.graph-node {
cursor: pointer;
transition: all 0.2s ease;
}
.graph-node:hover {
filter: brightness(1.2);
stroke-width: 3;
}
.graph-label {
font-size: 11px;
fill: hsl(var(--foreground));
pointer-events: none;
user-select: none;
}
.graph-node-group.file .graph-node { fill: #3b82f6; }
.graph-node-group.function .graph-node { fill: #10b981; }
.graph-node-group.module .graph-node { fill: #8b5cf6; }
.graph-node-group.class .graph-node { fill: #f59e0b; }
.graph-node-group.entity .graph-node { fill: #6b7280; }
.graph-error,
.graph-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 300px;
color: hsl(var(--muted-foreground));
text-align: center;
padding: 2rem;
}
.graph-error i,
.graph-empty-state i {
width: 48px;
height: 48px;
margin-bottom: 1rem;
opacity: 0.5;
}
.graph-error p,
.graph-empty-state p {
font-size: 0.9375rem;
margin: 0;
}
/* ============================================
Evolution Version Card Styles
============================================ */
.version-card {
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-left: 3px solid hsl(var(--primary));
border-radius: 8px;
padding: 1rem;
transition: all 0.2s ease;
}
.version-card:hover {
box-shadow: 0 2px 8px hsl(var(--foreground) / 0.08);
}
.version-card .version-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.version-card .version-info {
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
}
.version-card .version-number {
font-size: 0.875rem;
font-weight: 700;
color: hsl(var(--primary));
padding: 0.25rem 0.5rem;
background: hsl(var(--primary) / 0.1);
border-radius: 4px;
}
.version-card .version-date {
font-size: 0.8125rem;
color: hsl(var(--muted-foreground));
}
.version-content-preview {
font-size: 0.875rem;
line-height: 1.5;
color: hsl(var(--muted-foreground));
background: hsl(var(--muted) / 0.5);
padding: 0.75rem;
border-radius: 6px;
margin-bottom: 0.75rem;
white-space: pre-wrap;
word-break: break-word;
}
.version-diff-stats {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 0.75rem;
}
.diff-stat {
display: flex;
align-items: center;
gap: 0.375rem;
font-size: 0.75rem;
font-weight: 500;
padding: 0.25rem 0.625rem;
border-radius: 4px;
}
.diff-stat i {
width: 12px;
height: 12px;
}
.diff-stat.diff-added {
background: hsl(142 76% 36% / 0.15);
color: hsl(142 76% 30%);
}
.diff-stat.diff-modified {
background: hsl(38 92% 50% / 0.15);
color: hsl(38 92% 40%);
}
.diff-stat.diff-deleted {
background: hsl(0 84% 60% / 0.15);
color: hsl(0 84% 45%);
}
.version-card .version-reason {
font-size: 0.8125rem;
color: hsl(var(--foreground));
padding-top: 0.75rem;
border-top: 1px solid hsl(var(--border));
margin-top: 0;
}
.version-card .version-reason strong {
color: hsl(var(--muted-foreground));
font-weight: 600;
}
.evolution-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 200px;
color: hsl(var(--muted-foreground));
text-align: center;
padding: 2rem;
}
.evolution-empty-state i {
width: 48px;
height: 48px;
margin-bottom: 1rem;
opacity: 0.5;
}
.evolution-empty-state p {
font-size: 0.9375rem;
margin: 0;
}
/* Dark Mode Adjustments */
[data-theme="dark"] .memory-card {
background: #1e293b;
@@ -594,3 +807,25 @@
background: #1e293b;
border-color: #334155;
}
[data-theme="dark"] .knowledge-graph-container {
background: #0f172a;
border-color: #334155;
}
[data-theme="dark"] .graph-label {
fill: #e2e8f0;
}
[data-theme="dark"] .graph-edge {
stroke: #64748b;
}
[data-theme="dark"] .version-card {
background: #1e293b;
border-color: #334155;
}
[data-theme="dark"] .version-content-preview {
background: #0f172a;
}

View File

@@ -92,6 +92,15 @@ async function loadCodexLensStatus() {
const data = await response.json();
codexLensStatus = data;
// Expose to window for other modules (e.g., codexlens-manager.js)
if (!window.cliToolsStatus) {
window.cliToolsStatus = {};
}
window.cliToolsStatus.codexlens = {
installed: data.ready || false,
version: data.version || null
};
// Update CodexLens badge
updateCodexLensBadge();

View File

@@ -39,7 +39,27 @@ async function loadIndexStats() {
*/
function renderIndexCard() {
const container = document.getElementById('indexCard');
if (!container || !indexData) return;
if (!container) {
console.warn('[IndexManager] Container not found');
return;
}
// Handle case when data is not loaded yet
if (!indexData) {
container.innerHTML = `
<div class="bg-card border border-border rounded-lg overflow-hidden">
<div class="bg-muted/30 border-b border-border px-4 py-3 flex items-center gap-2">
<i data-lucide="database" class="w-4 h-4 text-primary"></i>
<span class="font-medium text-foreground">${t('index.manager') || 'Index Manager'}</span>
</div>
<div class="p-4 text-center text-muted-foreground">
<div class="animate-pulse">${t('common.loading') || 'Loading...'}</div>
</div>
</div>
`;
if (typeof lucide !== 'undefined') lucide.createIcons();
return;
}
const { indexDir, indexes, summary } = indexData;
@@ -64,113 +84,113 @@ function renderIndexCard() {
if (indexes && indexes.length > 0) {
indexes.forEach(function(idx) {
const vectorBadge = idx.hasVectorIndex
? '<span class="text-xs px-1.5 py-0.5 bg-primary/10 text-primary rounded">' + (t('index.vector') || 'Vector') + '</span>'
? `<span class="text-xs px-1.5 py-0.5 bg-primary/10 text-primary rounded">${t('index.vector') || 'Vector'}</span>`
: '';
const normalBadge = idx.hasNormalIndex
? '<span class="text-xs px-1.5 py-0.5 bg-muted text-muted-foreground rounded">' + (t('index.fts') || 'FTS') + '</span>'
? `<span class="text-xs px-1.5 py-0.5 bg-muted text-muted-foreground rounded">${t('index.fts') || 'FTS'}</span>`
: '';
indexRows += '\
<tr class="border-t border-border hover:bg-muted/30 transition-colors">\
<td class="py-2 px-2 text-foreground">\
<div class="flex items-center gap-2">\
<span class="font-mono text-xs truncate max-w-[250px]" title="' + escapeHtml(idx.id) + '">' + escapeHtml(idx.id) + '</span>\
</div>\
</td>\
<td class="py-2 px-2 text-right text-muted-foreground">' + idx.sizeFormatted + '</td>\
<td class="py-2 px-2 text-center">\
<div class="flex items-center justify-center gap-1">' + vectorBadge + normalBadge + '</div>\
</td>\
<td class="py-2 px-2 text-right text-muted-foreground">' + formatTimeAgo(idx.lastModified) + '</td>\
<td class="py-2 px-1 text-center">\
<button onclick="cleanIndexProject(\'' + escapeHtml(idx.id) + '\')" \
class="text-destructive/70 hover:text-destructive p-1 rounded hover:bg-destructive/10 transition-colors" \
title="' + (t('index.cleanProject') || 'Clean Index') + '">\
<i data-lucide="trash-2" class="w-3.5 h-3.5"></i>\
</button>\
</td>\
</tr>\
';
indexRows += `
<tr class="border-t border-border hover:bg-muted/30 transition-colors">
<td class="py-2 px-2 text-foreground">
<div class="flex items-center gap-2">
<span class="font-mono text-xs truncate max-w-[250px]" title="${escapeHtml(idx.id)}">${escapeHtml(idx.id)}</span>
</div>
</td>
<td class="py-2 px-2 text-right text-muted-foreground">${idx.sizeFormatted}</td>
<td class="py-2 px-2 text-center">
<div class="flex items-center justify-center gap-1">${vectorBadge}${normalBadge}</div>
</td>
<td class="py-2 px-2 text-right text-muted-foreground">${formatTimeAgo(idx.lastModified)}</td>
<td class="py-2 px-1 text-center">
<button onclick="cleanIndexProject('${escapeHtml(idx.id)}')"
class="text-destructive/70 hover:text-destructive p-1 rounded hover:bg-destructive/10 transition-colors"
title="${t('index.cleanProject') || 'Clean Index'}">
<i data-lucide="trash-2" class="w-3.5 h-3.5"></i>
</button>
</td>
</tr>
`;
});
} else {
indexRows = '\
<tr>\
<td colspan="5" class="py-4 text-center text-muted-foreground text-sm">' + (t('index.noIndexes') || 'No indexes yet') + '</td>\
</tr>\
';
indexRows = `
<tr>
<td colspan="5" class="py-4 text-center text-muted-foreground text-sm">${t('index.noIndexes') || 'No indexes yet'}</td>
</tr>
`;
}
container.innerHTML = '\
<div class="bg-card border border-border rounded-lg overflow-hidden">\
<div class="bg-muted/30 border-b border-border px-4 py-3 flex items-center justify-between">\
<div class="flex items-center gap-2">\
<i data-lucide="database" class="w-4 h-4 text-primary"></i>\
<span class="font-medium text-foreground">' + (t('index.manager') || 'Index Manager') + '</span>\
<span class="text-xs px-2 py-0.5 bg-muted rounded-full text-muted-foreground">' + (summary?.totalSizeFormatted || '0 B') + '</span>\
</div>\
<div class="flex items-center gap-2">\
<button onclick="loadIndexStats()" class="text-xs px-2 py-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors" title="' + (t('common.refresh') || 'Refresh') + '">\
<i data-lucide="refresh-cw" class="w-3.5 h-3.5"></i>\
</button>\
<button onclick="showCodexLensConfigModal()" class="text-xs px-2 py-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors" title="' + (t('common.settings') || 'Settings') + '">\
<i data-lucide="settings" class="w-3.5 h-3.5"></i>\
</button>\
</div>\
</div>\
<div class="p-4">\
<div class="flex items-center gap-2 mb-3 text-xs text-muted-foreground">\
<i data-lucide="folder" class="w-3.5 h-3.5"></i>\
<span class="font-mono truncate" title="' + escapeHtml(indexDir || '') + '">' + escapeHtml(indexDir || t('index.notConfigured') || 'Not configured') + '</span>\
</div>\
<div class="grid grid-cols-4 gap-3 mb-4">\
<div class="bg-muted/30 rounded-lg p-3 text-center">\
<div class="text-lg font-semibold text-foreground">' + (summary?.totalProjects || 0) + '</div>\
<div class="text-xs text-muted-foreground">' + (t('index.projects') || 'Projects') + '</div>\
</div>\
<div class="bg-muted/30 rounded-lg p-3 text-center">\
<div class="text-lg font-semibold text-foreground">' + (summary?.totalSizeFormatted || '0 B') + '</div>\
<div class="text-xs text-muted-foreground">' + (t('index.totalSize') || 'Total Size') + '</div>\
</div>\
<div class="bg-muted/30 rounded-lg p-3 text-center">\
<div class="text-lg font-semibold text-foreground">' + (summary?.vectorIndexCount || 0) + '</div>\
<div class="text-xs text-muted-foreground">' + (t('index.vectorIndexes') || 'Vector') + '</div>\
</div>\
<div class="bg-muted/30 rounded-lg p-3 text-center">\
<div class="text-lg font-semibold text-foreground">' + (summary?.normalIndexCount || 0) + '</div>\
<div class="text-xs text-muted-foreground">' + (t('index.ftsIndexes') || 'FTS') + '</div>\
</div>\
</div>\
<div class="border border-border rounded-lg overflow-hidden">\
<table class="w-full text-sm">\
<thead class="bg-muted/50">\
<tr class="text-xs text-muted-foreground">\
<th class="py-2 px-2 text-left font-medium">' + (t('index.projectId') || 'Project ID') + '</th>\
<th class="py-2 px-2 text-right font-medium">' + (t('index.size') || 'Size') + '</th>\
<th class="py-2 px-2 text-center font-medium">' + (t('index.type') || 'Type') + '</th>\
<th class="py-2 px-2 text-right font-medium">' + (t('index.lastModified') || 'Modified') + '</th>\
<th class="py-2 px-1 w-8"></th>\
</tr>\
</thead>\
<tbody>\
' + indexRows + '\
</tbody>\
</table>\
</div>\
<div class="mt-4 flex justify-between items-center gap-2">\
<button onclick="initCodexLensIndex()" \
class="text-xs px-3 py-1.5 bg-primary/10 text-primary hover:bg-primary/20 rounded transition-colors flex items-center gap-1.5">\
<i data-lucide="database" class="w-3.5 h-3.5"></i>\
' + (t('index.initCurrent') || 'Init Current Project') + '\
</button>\
<button onclick="cleanAllIndexesConfirm()" \
class="text-xs px-3 py-1.5 bg-destructive/10 text-destructive hover:bg-destructive/20 rounded transition-colors flex items-center gap-1.5">\
<i data-lucide="trash" class="w-3.5 h-3.5"></i>\
' + (t('index.cleanAll') || 'Clean All') + '\
</button>\
</div>\
</div>\
</div>\
';
container.innerHTML = `
<div class="bg-card border border-border rounded-lg overflow-hidden">
<div class="bg-muted/30 border-b border-border px-4 py-3 flex items-center justify-between">
<div class="flex items-center gap-2">
<i data-lucide="database" class="w-4 h-4 text-primary"></i>
<span class="font-medium text-foreground">${t('index.manager') || 'Index Manager'}</span>
<span class="text-xs px-2 py-0.5 bg-muted rounded-full text-muted-foreground">${summary?.totalSizeFormatted || '0 B'}</span>
</div>
<div class="flex items-center gap-2">
<button onclick="loadIndexStats()" class="text-xs px-2 py-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors" title="${t('common.refresh') || 'Refresh'}">
<i data-lucide="refresh-cw" class="w-3.5 h-3.5"></i>
</button>
<button onclick="showCodexLensConfigModal()" class="text-xs px-2 py-1 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors" title="${t('common.settings') || 'Settings'}">
<i data-lucide="settings" class="w-3.5 h-3.5"></i>
</button>
</div>
</div>
<div class="p-4">
<div class="flex items-center gap-2 mb-3 text-xs text-muted-foreground">
<i data-lucide="folder" class="w-3.5 h-3.5"></i>
<span class="font-mono truncate" title="${escapeHtml(indexDir || '')}">${escapeHtml(indexDir || t('index.notConfigured') || 'Not configured')}</span>
</div>
<div class="grid grid-cols-4 gap-3 mb-4">
<div class="bg-muted/30 rounded-lg p-3 text-center">
<div class="text-lg font-semibold text-foreground">${summary?.totalProjects || 0}</div>
<div class="text-xs text-muted-foreground">${t('index.projects') || 'Projects'}</div>
</div>
<div class="bg-muted/30 rounded-lg p-3 text-center">
<div class="text-lg font-semibold text-foreground">${summary?.totalSizeFormatted || '0 B'}</div>
<div class="text-xs text-muted-foreground">${t('index.totalSize') || 'Total Size'}</div>
</div>
<div class="bg-muted/30 rounded-lg p-3 text-center">
<div class="text-lg font-semibold text-foreground">${summary?.vectorIndexCount || 0}</div>
<div class="text-xs text-muted-foreground">${t('index.vectorIndexes') || 'Vector'}</div>
</div>
<div class="bg-muted/30 rounded-lg p-3 text-center">
<div class="text-lg font-semibold text-foreground">${summary?.normalIndexCount || 0}</div>
<div class="text-xs text-muted-foreground">${t('index.ftsIndexes') || 'FTS'}</div>
</div>
</div>
<div class="border border-border rounded-lg overflow-hidden">
<table class="w-full text-sm">
<thead class="bg-muted/50">
<tr class="text-xs text-muted-foreground">
<th class="py-2 px-2 text-left font-medium">${t('index.projectId') || 'Project ID'}</th>
<th class="py-2 px-2 text-right font-medium">${t('index.size') || 'Size'}</th>
<th class="py-2 px-2 text-center font-medium">${t('index.type') || 'Type'}</th>
<th class="py-2 px-2 text-right font-medium">${t('index.lastModified') || 'Modified'}</th>
<th class="py-2 px-1 w-8"></th>
</tr>
</thead>
<tbody>
${indexRows}
</tbody>
</table>
</div>
<div class="mt-4 flex justify-between items-center gap-2">
<button onclick="initCodexLensIndex()"
class="text-xs px-3 py-1.5 bg-primary/10 text-primary hover:bg-primary/20 rounded transition-colors flex items-center gap-1.5">
<i data-lucide="database" class="w-3.5 h-3.5"></i>
${t('index.initCurrent') || 'Init Current Project'}
</button>
<button onclick="cleanAllIndexesConfirm()"
class="text-xs px-3 py-1.5 bg-destructive/10 text-destructive hover:bg-destructive/20 rounded transition-colors flex items-center gap-1.5">
<i data-lucide="trash" class="w-3.5 h-3.5"></i>
${t('index.cleanAll') || 'Clean All'}
</button>
</div>
</div>
</div>
`;
// Reinitialize Lucide icons
if (typeof lucide !== 'undefined') {
@@ -185,24 +205,24 @@ function renderIndexCardError(errorMessage) {
const container = document.getElementById('indexCard');
if (!container) return;
container.innerHTML = '\
<div class="bg-card border border-border rounded-lg overflow-hidden">\
<div class="bg-muted/30 border-b border-border px-4 py-3 flex items-center gap-2">\
<i data-lucide="database" class="w-4 h-4 text-primary"></i>\
<span class="font-medium text-foreground">' + (t('index.manager') || 'Index Manager') + '</span>\
</div>\
<div class="p-4 text-center">\
<div class="text-destructive mb-2">\
<i data-lucide="alert-circle" class="w-8 h-8 mx-auto"></i>\
</div>\
<p class="text-sm text-muted-foreground mb-3">' + escapeHtml(errorMessage) + '</p>\
<button onclick="loadIndexStats()" \
class="text-xs px-3 py-1.5 bg-primary text-primary-foreground hover:bg-primary/90 rounded transition-colors">\
' + (t('common.retry') || 'Retry') + '\
</button>\
</div>\
</div>\
';
container.innerHTML = `
<div class="bg-card border border-border rounded-lg overflow-hidden">
<div class="bg-muted/30 border-b border-border px-4 py-3 flex items-center gap-2">
<i data-lucide="database" class="w-4 h-4 text-primary"></i>
<span class="font-medium text-foreground">${t('index.manager') || 'Index Manager'}</span>
</div>
<div class="p-4 text-center">
<div class="text-destructive mb-2">
<i data-lucide="alert-circle" class="w-8 h-8 mx-auto"></i>
</div>
<p class="text-sm text-muted-foreground mb-3">${escapeHtml(errorMessage)}</p>
<button onclick="loadIndexStats()"
class="text-xs px-3 py-1.5 bg-primary text-primary-foreground hover:bg-primary/90 rounded transition-colors">
${t('common.retry') || 'Retry'}
</button>
</div>
</div>
`;
// Reinitialize Lucide icons
if (typeof lucide !== 'undefined') {

View File

@@ -45,10 +45,26 @@ function showModal(title, content, options = {}) {
}
function closeModal() {
const overlay = document.querySelector('.generic-modal-overlay');
if (overlay) {
overlay.classList.remove('active');
setTimeout(() => overlay.remove(), 200);
// Try generic modal overlay first
const genericOverlay = document.querySelector('.generic-modal-overlay');
if (genericOverlay) {
genericOverlay.classList.remove('active');
setTimeout(() => genericOverlay.remove(), 200);
return;
}
// Try CodexLens config modal
const codexLensModal = document.getElementById('codexlensConfigModal');
if (codexLensModal) {
codexLensModal.remove();
return;
}
// Try any modal-backdrop
const modalBackdrop = document.querySelector('.modal-backdrop');
if (modalBackdrop) {
modalBackdrop.remove();
return;
}
}

View File

@@ -19,9 +19,10 @@ async function showCodexLensConfigModal() {
const modalHtml = buildCodexLensConfigContent(config);
// Create and show modal
const modalContainer = document.createElement('div');
modalContainer.innerHTML = modalHtml;
document.body.appendChild(modalContainer);
const tempContainer = document.createElement('div');
tempContainer.innerHTML = modalHtml;
const modal = tempContainer.firstElementChild;
document.body.appendChild(modal);
// Initialize icons
if (window.lucide) lucide.createIcons();
@@ -65,11 +66,21 @@ function buildCodexLensConfigContent(config) {
'<div class="flex items-center gap-4 text-sm">' +
'<div class="flex items-center gap-2">' +
'<span class="text-muted-foreground">' + t('codexlens.currentWorkspace') + ':</span>' +
'<span class="font-medium">' + (isInstalled ? t('codexlens.installed') : t('codexlens.notInstalled')) + '</span>' +
(isInstalled
? '<span class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-success/10 text-success border border-success/20">' +
'<i data-lucide="check-circle" class="w-3.5 h-3.5"></i>' +
t('codexlens.installed') +
'</span>'
: '<span class="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-muted text-muted-foreground border border-border">' +
'<i data-lucide="circle" class="w-3.5 h-3.5"></i>' +
t('codexlens.notInstalled') +
'</span>') +
'</div>' +
'<div class="flex items-center gap-2">' +
'<span class="text-muted-foreground">' + t('codexlens.indexes') + ':</span>' +
'<span class="font-medium">' + indexCount + '</span>' +
'<span class="inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium bg-primary/10 text-primary border border-primary/20">' +
indexCount +
'</span>' +
'</div>' +
'</div>' +
'</div>' +
@@ -106,20 +117,20 @@ function buildCodexLensConfigContent(config) {
'<h4>' + t('codexlens.actions') + '</h4>' +
'<div class="tool-config-actions">' +
(isInstalled
? '<button class="btn-sm btn-outline" onclick="initCodexLensIndex()">' +
'<i data-lucide="database" class="w-3 h-3"></i> ' + t('codexlens.initializeIndex') +
? '<button class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md border border-primary/30 bg-primary/5 text-primary hover:bg-primary/10 transition-colors" onclick="initCodexLensIndex()">' +
'<i data-lucide="database" class="w-3.5 h-3.5"></i> ' + t('codexlens.initializeIndex') +
'</button>' +
'<button class="btn-sm btn-outline" onclick="cleanCurrentWorkspaceIndex()">' +
'<i data-lucide="folder-x" class="w-3 h-3"></i> ' + t('codexlens.cleanCurrentWorkspace') +
'<button class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md border border-border bg-background hover:bg-muted/50 transition-colors" onclick="cleanCurrentWorkspaceIndex()">' +
'<i data-lucide="folder-x" class="w-3.5 h-3.5"></i> ' + t('codexlens.cleanCurrentWorkspace') +
'</button>' +
'<button class="btn-sm btn-outline" onclick="cleanCodexLensIndexes()">' +
'<i data-lucide="trash" class="w-3 h-3"></i> ' + t('codexlens.cleanAllIndexes') +
'<button class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md border border-border bg-background hover:bg-muted/50 transition-colors" onclick="cleanCodexLensIndexes()">' +
'<i data-lucide="trash" class="w-3.5 h-3.5"></i> ' + t('codexlens.cleanAllIndexes') +
'</button>' +
'<button class="btn-sm btn-outline btn-danger" onclick="uninstallCodexLens()">' +
'<i data-lucide="trash-2" class="w-3 h-3"></i> ' + t('cli.uninstall') +
'<button class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md border border-destructive/30 bg-destructive/5 text-destructive hover:bg-destructive/10 transition-colors" onclick="uninstallCodexLens()">' +
'<i data-lucide="trash-2" class="w-3.5 h-3.5"></i> ' + t('cli.uninstall') +
'</button>'
: '<button class="btn-sm btn-primary" onclick="installCodexLens()">' +
'<i data-lucide="download" class="w-3 h-3"></i> ' + t('codexlens.installCodexLens') +
: '<button class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors" onclick="installCodexLens()">' +
'<i data-lucide="download" class="w-3.5 h-3.5"></i> ' + t('codexlens.installCodexLens') +
'</button>') +
'</div>' +
'</div>' +
@@ -172,12 +183,12 @@ function buildCodexLensConfigContent(config) {
'</button>' +
'</div>' +
'<div id="searchResults" class="hidden">' +
'<div class="bg-muted/30 rounded-lg p-3 max-h-64 overflow-y-auto">' +
'<div class="flex items-center justify-between mb-2">' +
'<div>' +
'<div class="flex items-center justify-between">' +
'<p class="text-sm font-medium">' + t('codexlens.results') + ':</p>' +
'<span id="searchResultCount" class="text-xs text-muted-foreground"></span>' +
'</div>' +
'<pre id="searchResultContent" class="text-xs font-mono whitespace-pre-wrap break-all"></pre>' +
'<pre id="searchResultContent"></pre>' +
'</div>' +
'</div>' +
'</div>' +

View File

@@ -758,11 +758,12 @@ async function executeCliTool(
const startTime = Date.now();
return new Promise((resolve, reject) => {
// Direct spawn without shell - CLI tools (codex/gemini/qwen) don't need shell wrapper
// This avoids Windows cmd.exe ENOENT errors and simplifies argument handling
// Windows requires shell: true for npm global commands (.cmd files)
// Unix-like systems can use shell: false for direct execution
const isWindows = process.platform === 'win32';
const child = spawn(command, args, {
cwd: workingDir,
shell: false,
shell: isWindows, // Enable shell on Windows for .cmd files
stdio: [useStdin ? 'pipe' : 'ignore', 'pipe', 'pipe']
});

View File

@@ -39,10 +39,16 @@ const ParamsSchema = z.object({
'init',
'search',
'search_files',
'status',
'symbol',
'check',
'update',
'bootstrap',
]),
path: z.string().optional(),
query: z.string().optional(),
mode: z.enum(['auto', 'text', 'semantic', 'exact', 'fuzzy', 'hybrid', 'vector', 'pure-vector']).default('auto'),
format: z.enum(['json', 'text', 'pretty']).default('json'),
languages: z.array(z.string()).optional(),
limit: z.number().default(20),
// Additional fields for internal functions
@@ -790,8 +796,13 @@ Note: For advanced operations (config, status, clean), use CLI directly: codexle
'init',
'search',
'search_files',
'status',
'symbol',
'check',
'update',
'bootstrap',
],
description: 'Action to perform: init (index directory), search (search code), search_files (search files only)',
description: 'Action to perform: init/update (index directory), search (search code), search_files (search files only), status (index status), symbol (extract symbols), check (check if ready), bootstrap (setup venv)',
},
path: {
type: 'string',
@@ -807,6 +818,12 @@ Note: For advanced operations (config, status, clean), use CLI directly: codexle
description: 'Search mode: auto (default, hybrid if embeddings exist), text/exact (FTS), hybrid (best), fuzzy, vector, semantic/pure-vector',
default: 'auto',
},
format: {
type: 'string',
enum: ['json', 'text', 'pretty'],
description: 'Output format: json (default), text, pretty',
default: 'json',
},
languages: {
type: 'array',
items: { type: 'string' },
@@ -847,9 +864,41 @@ export async function handler(params: Record<string, unknown>): Promise<ToolResu
result = await searchFiles(parsed.data);
break;
case 'status':
result = await getStatus(parsed.data);
break;
case 'symbol':
result = await extractSymbols(parsed.data);
break;
case 'check':
const checkStatus = await ensureReady();
result = {
success: checkStatus.ready,
ready: checkStatus.ready,
version: checkStatus.version,
error: checkStatus.error,
};
break;
case 'update':
// Update is an alias for init (incremental update)
result = await initIndex(parsed.data);
break;
case 'bootstrap':
const bootstrapResult = await bootstrapVenv();
result = {
success: bootstrapResult.success,
message: bootstrapResult.message,
error: bootstrapResult.error,
};
break;
default:
throw new Error(
`Unknown action: ${action}. Valid actions: init, search, search_files`
`Unknown action: ${action}. Valid actions: init, search, search_files, status, symbol, check, update, bootstrap`
);
}

View File

@@ -141,9 +141,11 @@ async function checkIndexStatus(path: string = '.'): Promise<IndexStatus> {
try {
// Strip ANSI color codes from JSON output
const cleanOutput = (result.output || '{}').replace(/\x1b\[[0-9;]*m/g, '');
const status = JSON.parse(cleanOutput);
const indexed = status.indexed === true || status.file_count > 0;
const parsed = JSON.parse(cleanOutput);
// Handle both direct and nested response formats (status returns {success, result: {...}})
const status = parsed.result || parsed;
const indexed = status.projects_count > 0 || status.total_files > 0;
// Get embeddings coverage from comprehensive status
const embeddingsData = status.embeddings || {};
const embeddingsCoverage = embeddingsData.coverage_percent || 0;
@@ -161,7 +163,7 @@ async function checkIndexStatus(path: string = '.'): Promise<IndexStatus> {
return {
indexed,
has_embeddings,
file_count: status.file_count,
file_count: status.total_files,
embeddings_coverage_percent: embeddingsCoverage,
warning,
};