feat: Implement CLAUDE.md Manager View with file tree, viewer, and metadata actions

- Added main JavaScript functionality for CLAUDE.md management including file loading, rendering, and editing capabilities.
- Created a test HTML file to validate the functionality of the CLAUDE.md manager.
- Introduced CLI generation examples and documentation for rules creation via CLI.
- Enhanced error handling and notifications for file operations.
This commit is contained in:
catlog22
2025-12-14 23:08:36 +08:00
parent 0529b57694
commit d91477ad80
30 changed files with 7961 additions and 298 deletions

View File

@@ -1528,6 +1528,11 @@ code.ctx-meta-chip-value {
color: white;
}
.status-toast.warning {
background: hsl(38 92% 50%);
color: white;
}
.status-toast.fade-out {
animation: toastFadeOut 0.3s ease forwards;
}

View File

@@ -214,3 +214,113 @@
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
}
/* ==========================================
CREATE MODAL STYLES (Skills & Rules)
========================================== */
/* Modal Overlay */
.modal-overlay {
animation: fadeIn 0.15s ease-out;
backdrop-filter: blur(2px);
}
/* Modal Dialog */
.modal-dialog {
animation: slideUpModal 0.2s ease-out;
}
@keyframes slideUpModal {
from {
opacity: 0;
transform: translateY(20px) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
/* Location Selection Buttons */
.location-btn {
cursor: pointer;
}
.location-btn:active {
transform: scale(0.98);
}
/* Validation Result Animations */
#skillValidationResult > div,
#ruleValidationResult > div {
animation: slideDown 0.2s ease-out;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Path Input List Animations */
#rulePathsList > div {
animation: slideDown 0.15s ease-out;
}
/* Form Input Focus States */
.modal-dialog input:focus,
.modal-dialog textarea:focus,
.modal-dialog select:focus {
outline: none;
border-color: hsl(var(--primary));
ring: 2px;
ring-color: hsl(var(--primary) / 0.2);
}
/* Checkbox Custom Styling */
.modal-dialog input[type="checkbox"] {
cursor: pointer;
accent-color: hsl(var(--primary));
}
/* Textarea Specific */
.modal-dialog textarea {
resize: vertical;
min-height: 100px;
}
/* Button Hover States */
.modal-dialog button:not(:disabled):hover {
opacity: 0.9;
}
.modal-dialog button:not(:disabled):active {
transform: scale(0.98);
}
/* Loading Spinner in Validation */
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Responsive Modal */
@media (max-width: 640px) {
.modal-dialog {
max-width: 95vw;
max-height: 95vh;
}
}

View File

@@ -0,0 +1,759 @@
/* ========================================
* CLAUDE.md Manager Styles
* Three-column layout: File Tree | Viewer/Editor | Metadata
* ======================================== */
/* ========================================
* Main Layout
* ======================================== */
.claude-manager-view {
height: 100%;
min-height: calc(100vh - 180px);
max-height: calc(100vh - 180px);
overflow: hidden;
display: flex;
flex-direction: column;
}
.claude-manager-view.loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* ========================================
* Header
* ======================================== */
.claude-manager-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem 0;
margin-bottom: 0.5rem;
border-bottom: 1px solid hsl(var(--border));
flex-shrink: 0;
}
.claude-manager-header-left {
display: flex;
align-items: center;
gap: 0.75rem;
}
.claude-manager-header-left h2 {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.125rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
}
.file-count-badge {
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
}
.claude-manager-header-right {
display: flex;
align-items: center;
gap: 0.5rem;
}
/* ========================================
* Three-Column Grid
* ======================================== */
.claude-manager-columns {
display: grid;
grid-template-columns: 280px 1fr 320px;
gap: 1rem;
flex: 1;
min-height: 0;
overflow: hidden;
}
.claude-manager-column {
display: flex;
flex-direction: column;
min-height: 0;
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
}
.claude-manager-column.left {
overflow-y: auto;
height: 100%;
}
.claude-manager-column.center {
overflow: hidden;
height: 100%;
}
.claude-manager-column.right {
overflow-y: auto;
height: 100%;
}
/* ========================================
* File Tree (Left Column)
* ======================================== */
.file-tree {
padding: 0;
}
/* Search Box */
.file-tree-search {
position: relative;
padding: 0.5rem 0.75rem;
border-bottom: 1px solid hsl(var(--border));
}
.file-tree-search input {
width: 100%;
padding: 0.5rem 2.5rem 0.5rem 0.75rem;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.875rem;
}
.file-tree-search input:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.1);
}
.file-tree-search i {
position: absolute;
right: 1.5rem;
top: 50%;
transform: translateY(-50%);
color: hsl(var(--muted-foreground));
pointer-events: none;
}
.file-tree-section {
margin-bottom: 0.5rem;
}
.file-tree-header {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem;
cursor: pointer;
font-weight: 600;
color: hsl(var(--foreground));
border-radius: 0.25rem;
transition: background-color 0.15s;
}
.file-tree-header:hover {
background: hsl(var(--muted));
}
.file-tree-header .file-count {
margin-left: auto;
font-size: 0.75rem;
padding: 0.125rem 0.375rem;
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
}
.file-tree-subheader {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.375rem 0.5rem;
cursor: pointer;
font-size: 0.875rem;
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
transition: background-color 0.15s;
}
.file-tree-subheader:hover {
background: hsl(var(--muted) / 0.5);
}
.file-tree-subheader .file-count {
margin-left: auto;
font-size: 0.7rem;
padding: 0.125rem 0.25rem;
background: hsl(var(--muted));
color: hsl(var(--muted-foreground));
border-radius: 0.25rem;
}
.file-tree-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.375rem 0.5rem;
cursor: pointer;
font-size: 0.875rem;
color: hsl(var(--foreground));
border-radius: 0.25rem;
transition: background-color 0.15s;
}
.file-tree-item:hover {
background: hsl(var(--muted) / 0.5);
}
.file-tree-item.selected {
background: hsl(var(--primary) / 0.1);
color: hsl(var(--primary));
font-weight: 500;
}
.file-tree-item.empty {
color: hsl(var(--muted-foreground));
cursor: default;
font-style: italic;
}
.file-tree-item.empty:hover {
background: transparent;
}
.file-tree-item .file-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-tree-item .file-path-hint {
font-size: 0.7rem;
color: hsl(var(--muted-foreground));
opacity: 0.7;
}
/* Color coding for level icons */
.text-orange-500 {
color: hsl(25, 95%, 53%);
}
.text-green-500 {
color: hsl(142, 71%, 45%);
}
.text-blue-500 {
color: hsl(217, 91%, 60%);
}
/* ========================================
* File Viewer (Center Column)
* ======================================== */
.file-viewer {
display: flex;
flex-direction: column;
height: 100%;
}
.file-viewer-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
border-bottom: 1px solid hsl(var(--border));
flex-shrink: 0;
}
.file-viewer-header h3 {
font-size: 1rem;
font-weight: 600;
color: hsl(var(--foreground));
margin: 0;
}
.file-viewer-actions {
display: flex;
gap: 0.5rem;
}
.file-viewer-content {
flex: 1;
overflow-y: auto;
padding: 1rem;
}
.markdown-content {
line-height: 1.6;
color: hsl(var(--foreground));
}
.markdown-content h1 {
font-size: 1.5rem;
font-weight: 700;
margin: 1.5rem 0 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid hsl(var(--border));
}
.markdown-content h2 {
font-size: 1.25rem;
font-weight: 600;
margin: 1.25rem 0 0.75rem;
}
.markdown-content h3 {
font-size: 1.125rem;
font-weight: 600;
margin: 1rem 0 0.5rem;
}
.markdown-content strong {
font-weight: 600;
color: hsl(var(--foreground));
}
.markdown-content em {
font-style: italic;
}
.markdown-content code {
font-family: 'Consolas', 'Monaco', monospace;
font-size: 0.875rem;
padding: 0.125rem 0.375rem;
background: hsl(var(--muted));
border-radius: 0.25rem;
}
.file-editor {
width: 100%;
height: 100%;
min-height: 400px;
padding: 1rem;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 0.875rem;
line-height: 1.5;
color: hsl(var(--foreground));
background: hsl(var(--background));
border: none;
outline: none;
resize: none;
}
.file-editor:focus {
background: hsl(var(--background));
}
/* ========================================
* File Metadata (Right Column)
* ======================================== */
.file-metadata {
padding: 1rem;
}
.metadata-section {
margin-bottom: 1.5rem;
}
.metadata-section h4 {
font-size: 0.875rem;
font-weight: 600;
color: hsl(var(--muted-foreground));
text-transform: uppercase;
letter-spacing: 0.05em;
margin: 0 0 0.75rem;
}
.metadata-item {
display: flex;
flex-direction: column;
gap: 0.25rem;
margin-bottom: 0.75rem;
}
.metadata-item .label {
font-size: 0.75rem;
color: hsl(var(--muted-foreground));
}
.metadata-item .value {
font-size: 0.875rem;
color: hsl(var(--foreground));
font-weight: 500;
}
.metadata-item .value.path {
font-family: 'Consolas', 'Monaco', monospace;
font-size: 0.75rem;
word-break: break-all;
background: hsl(var(--muted));
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
}
.metadata-section .btn.full-width {
width: 100%;
margin-bottom: 0.5rem;
justify-content: center;
}
/* ========================================
* CLI Sync Panel
* ======================================== */
.cli-sync-panel {
padding: 1rem;
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
background: hsl(var(--card));
}
.cli-sync-panel .panel-header {
display: flex;
align-items: center;
gap: 0.5rem;
font-weight: 600;
margin-bottom: 1rem;
color: hsl(var(--primary));
}
.sync-config {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.sync-config label {
font-size: 0.875rem;
font-weight: 500;
color: hsl(var(--muted-foreground));
margin-bottom: 0.25rem;
}
.sync-config .sync-select,
.sync-config select {
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;
width: 100%;
}
.sync-config .sync-select:focus,
.sync-config select:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.1);
}
.sync-button {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.625rem;
background: hsl(var(--primary));
color: white;
border: none;
border-radius: 0.375rem;
font-weight: 500;
cursor: pointer;
transition: opacity 0.2s;
}
.sync-button:hover:not(:disabled) {
opacity: 0.9;
}
.sync-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.sync-progress {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem;
margin-top: 0.75rem;
background: hsl(var(--accent));
border-radius: 0.375rem;
font-size: 0.875rem;
color: hsl(var(--accent-foreground));
}
.sync-progress i {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* ========================================
* Empty State
* ======================================== */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: hsl(var(--muted-foreground));
text-align: center;
padding: 2rem;
}
.empty-state i {
margin-bottom: 1rem;
}
.empty-state p {
margin: 0;
font-size: 0.875rem;
}
/* ========================================
* File Type Icons
* ======================================== */
.file-icon {
flex-shrink: 0;
}
.file-icon.directory {
color: hsl(var(--primary));
}
.file-icon.markdown {
color: hsl(25, 95%, 53%);
}
.file-icon.code {
color: hsl(217, 91%, 60%);
}
.file-icon.json {
color: hsl(142, 71%, 45%);
}
.file-icon.css {
color: hsl(262, 83%, 58%);
}
.file-size {
margin-left: auto;
font-size: 0.7rem;
color: hsl(var(--muted-foreground));
opacity: 0.7;
}
/* Search Highlight */
.search-highlight {
background: hsl(45, 100%, 70%);
color: hsl(0, 0%, 10%);
font-weight: 600;
padding: 0.125rem 0.25rem;
border-radius: 0.125rem;
}
/* ========================================
* Create Dialog (Modal)
* ======================================== */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
animation: fadeIn 0.2s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.create-dialog {
background: hsl(var(--card));
border: 1px solid hsl(var(--border));
border-radius: 0.5rem;
padding: 1.5rem;
width: 90%;
max-width: 500px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
animation: slideUp 0.3s;
}
@keyframes slideUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.create-dialog h3 {
margin: 0 0 1.5rem 0;
color: hsl(var(--foreground));
font-size: 1.125rem;
font-weight: 600;
}
.dialog-form {
display: flex;
flex-direction: column;
gap: 1rem;
}
.dialog-form label {
display: block;
font-size: 0.875rem;
font-weight: 500;
margin-bottom: 0.5rem;
color: hsl(var(--muted-foreground));
}
.dialog-form input,
.dialog-form select {
width: 100%;
padding: 0.5rem 0.75rem;
border: 1px solid hsl(var(--border));
border-radius: 0.375rem;
background: hsl(var(--background));
color: hsl(var(--foreground));
font-size: 0.875rem;
}
.dialog-form input:focus,
.dialog-form select:focus {
outline: none;
border-color: hsl(var(--primary));
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.1);
}
.dialog-buttons {
display: flex;
gap: 0.75rem;
margin-top: 1.5rem;
}
.dialog-buttons button {
flex: 1;
}
/* ========================================
* Enhanced Markdown Content
* ======================================== */
.markdown-content a {
color: hsl(var(--primary));
text-decoration: underline;
}
.markdown-content a:hover {
opacity: 0.8;
}
.markdown-content table {
width: 100%;
border-collapse: collapse;
margin: 1rem 0;
font-size: 0.875rem;
}
.markdown-content table th,
.markdown-content table td {
padding: 0.5rem 0.75rem;
border: 1px solid hsl(var(--border));
}
.markdown-content table th {
background: hsl(var(--muted));
font-weight: 600;
}
.markdown-content pre {
background: hsl(var(--muted));
padding: 1rem;
border-radius: 0.375rem;
overflow-x: auto;
margin: 1rem 0;
}
.markdown-content pre code {
background: transparent;
padding: 0;
}
.markdown-content ul,
.markdown-content ol {
margin: 0.5rem 0;
padding-left: 1.5rem;
}
.markdown-content li {
margin: 0.25rem 0;
}
.task-list-item {
list-style: none;
margin-left: -1.5rem;
}
.task-list-item input[type="checkbox"] {
margin-right: 0.5rem;
}
/* ========================================
* Button Styles
* ======================================== */
.btn-danger {
background: hsl(0, 72%, 51%);
color: white;
border-color: hsl(0, 72%, 51%);
}
.btn-danger:hover:not(:disabled) {
background: hsl(0, 72%, 45%);
border-color: hsl(0, 72%, 45%);
}
/* ========================================
* Responsive Design
* ======================================== */
@media (max-width: 1400px) {
.claude-manager-columns {
grid-template-columns: 240px 1fr 280px;
}
}
@media (max-width: 1024px) {
.claude-manager-columns {
grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto;
}
.claude-manager-column.left {
max-height: 200px;
}
.claude-manager-column.right {
max-height: 300px;
}
}