mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
feat: 添加标签颜色变体和验证功能,增强工具配置管理
This commit is contained in:
@@ -284,6 +284,37 @@
|
|||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tag color variants */
|
||||||
|
.tag-item.tag-分析, .tool-tag.tag-分析 {
|
||||||
|
background: hsl(210 100% 50% / 0.15);
|
||||||
|
color: hsl(210 100% 45%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item.tag-编码, .tool-tag.tag-编码 {
|
||||||
|
background: hsl(142 76% 36% / 0.15);
|
||||||
|
color: hsl(142 76% 36%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item.tag-Debug, .tool-tag.tag-Debug {
|
||||||
|
background: hsl(0 84% 60% / 0.15);
|
||||||
|
color: hsl(0 84% 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item.tag-重构, .tool-tag.tag-重构 {
|
||||||
|
background: hsl(280 70% 50% / 0.15);
|
||||||
|
color: hsl(280 70% 45%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item.tag-测试, .tool-tag.tag-测试 {
|
||||||
|
background: hsl(45 93% 47% / 0.15);
|
||||||
|
color: hsl(45 93% 35%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-item.tag-文档, .tool-tag.tag-文档 {
|
||||||
|
background: hsl(180 70% 40% / 0.15);
|
||||||
|
color: hsl(180 70% 35%);
|
||||||
|
}
|
||||||
|
|
||||||
.tag-remove {
|
.tag-remove {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -334,6 +365,15 @@
|
|||||||
border-color: hsl(var(--primary) / 0.3);
|
border-color: hsl(var(--primary) / 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.predefined-tag-btn.selected,
|
||||||
|
.predefined-tag-btn:disabled {
|
||||||
|
background: hsl(var(--primary) / 0.1);
|
||||||
|
color: hsl(var(--muted-foreground));
|
||||||
|
border-color: hsl(var(--primary) / 0.2);
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.predefined-tag-btn i {
|
.predefined-tag-btn i {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ function buildToolConfigModalContent(tool, config, models, status) {
|
|||||||
'<h4>Tags <span class="text-muted">(optional labels)</span></h4>' +
|
'<h4>Tags <span class="text-muted">(optional labels)</span></h4>' +
|
||||||
'<div class="tags-unified-input" id="tagsUnifiedInput">' +
|
'<div class="tags-unified-input" id="tagsUnifiedInput">' +
|
||||||
(config.tags || []).map(function(tag) {
|
(config.tags || []).map(function(tag) {
|
||||||
return '<span class="tag-item">' + escapeHtml(tag) + '<button type="button" class="tag-remove" data-tag="' + escapeHtml(tag) + '">×</button></span>';
|
return '<span class="tag-item tag-' + escapeHtml(tag) + '">' + escapeHtml(tag) + '<button type="button" class="tag-remove" data-tag="' + escapeHtml(tag) + '">×</button></span>';
|
||||||
}).join('') +
|
}).join('') +
|
||||||
'<input type="text" id="tagInput" class="tag-inline-input" placeholder="输入标签按 Enter 添加" />' +
|
'<input type="text" id="tagInput" class="tag-inline-input" placeholder="输入标签按 Enter 添加" />' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
@@ -375,7 +375,7 @@ function initToolConfigModalEvents(tool, currentConfig, models) {
|
|||||||
// Insert tags before the input
|
// Insert tags before the input
|
||||||
currentTags.forEach(function(tag) {
|
currentTags.forEach(function(tag) {
|
||||||
var tagEl = document.createElement('span');
|
var tagEl = document.createElement('span');
|
||||||
tagEl.className = 'tag-item';
|
tagEl.className = 'tag-item tag-' + escapeHtml(tag);
|
||||||
tagEl.innerHTML = escapeHtml(tag) + '<button type="button" class="tag-remove" data-tag="' + escapeHtml(tag) + '">×</button>';
|
tagEl.innerHTML = escapeHtml(tag) + '<button type="button" class="tag-remove" data-tag="' + escapeHtml(tag) + '">×</button>';
|
||||||
container.insertBefore(tagEl, input);
|
container.insertBefore(tagEl, input);
|
||||||
});
|
});
|
||||||
@@ -389,6 +389,18 @@ function initToolConfigModalEvents(tool, currentConfig, models) {
|
|||||||
renderTags();
|
renderTags();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update predefined tag buttons state
|
||||||
|
document.querySelectorAll('.predefined-tag-btn').forEach(function(btn) {
|
||||||
|
var tag = btn.getAttribute('data-tag');
|
||||||
|
if (currentTags.indexOf(tag) !== -1) {
|
||||||
|
btn.classList.add('selected');
|
||||||
|
btn.disabled = true;
|
||||||
|
} else {
|
||||||
|
btn.classList.remove('selected');
|
||||||
|
btn.disabled = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Click on unified input container focuses the input
|
// Click on unified input container focuses the input
|
||||||
@@ -665,10 +677,10 @@ function renderToolsSection() {
|
|||||||
var toolConfig = cliToolConfig && cliToolConfig.tools ? cliToolConfig.tools[tool] : null;
|
var toolConfig = cliToolConfig && cliToolConfig.tools ? cliToolConfig.tools[tool] : null;
|
||||||
var tags = toolConfig && toolConfig.tags ? toolConfig.tags : [];
|
var tags = toolConfig && toolConfig.tags ? toolConfig.tags : [];
|
||||||
|
|
||||||
// Build tags HTML
|
// Build tags HTML with color classes
|
||||||
var tagsHtml = tags.length > 0
|
var tagsHtml = tags.length > 0
|
||||||
? '<div class="tool-tags">' + tags.map(function(tag) {
|
? '<div class="tool-tags">' + tags.map(function(tag) {
|
||||||
return '<span class="tool-tag">' + escapeHtml(tag) + '</span>';
|
return '<span class="tool-tag tag-' + escapeHtml(tag) + '">' + escapeHtml(tag) + '</span>';
|
||||||
}).join('') + '</div>'
|
}).join('') + '</div>'
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,24 @@ export function getToolConfig(baseDir: string, tool: string): CliToolConfig {
|
|||||||
return config.tools[tool] || DEFAULT_CONFIG.tools[tool];
|
return config.tools[tool] || DEFAULT_CONFIG.tools[tool];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and sanitize tags array
|
||||||
|
* @param tags - Raw tags array from user input
|
||||||
|
* @returns Sanitized tags array
|
||||||
|
*/
|
||||||
|
function validateTags(tags: string[] | undefined): string[] | undefined {
|
||||||
|
if (!tags || !Array.isArray(tags)) return undefined;
|
||||||
|
|
||||||
|
const MAX_TAGS = 10;
|
||||||
|
const MAX_TAG_LENGTH = 30;
|
||||||
|
|
||||||
|
return tags
|
||||||
|
.filter(tag => typeof tag === 'string')
|
||||||
|
.map(tag => tag.trim())
|
||||||
|
.filter(tag => tag.length > 0 && tag.length <= MAX_TAG_LENGTH)
|
||||||
|
.slice(0, MAX_TAGS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update configuration for a specific tool
|
* Update configuration for a specific tool
|
||||||
* Returns the updated tool config
|
* Returns the updated tool config
|
||||||
@@ -206,7 +224,7 @@ export function updateToolConfig(
|
|||||||
enabled: updates.enabled !== undefined ? updates.enabled : currentToolConfig.enabled,
|
enabled: updates.enabled !== undefined ? updates.enabled : currentToolConfig.enabled,
|
||||||
primaryModel: updates.primaryModel || currentToolConfig.primaryModel,
|
primaryModel: updates.primaryModel || currentToolConfig.primaryModel,
|
||||||
secondaryModel: updates.secondaryModel || currentToolConfig.secondaryModel,
|
secondaryModel: updates.secondaryModel || currentToolConfig.secondaryModel,
|
||||||
tags: updates.tags !== undefined ? updates.tags : currentToolConfig.tags
|
tags: updates.tags !== undefined ? validateTags(updates.tags) : currentToolConfig.tags
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save updated config
|
// Save updated config
|
||||||
|
|||||||
Reference in New Issue
Block a user