claude-code-workflow 6.3.48 → 6.3.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +6 -8
- package/.claude/agents/action-planning-agent.md +28 -45
- package/.claude/agents/cli-lite-planning-agent.md +93 -1
- package/.claude/agents/code-developer.md +144 -27
- package/.claude/commands/ccw-coordinator.md +175 -21
- package/.claude/commands/ccw-debug.md +832 -0
- package/.claude/commands/ccw.md +90 -9
- package/.claude/commands/cli/cli-init.md +1 -0
- package/.claude/commands/issue/convert-to-plan.md +718 -0
- package/.claude/commands/issue/from-brainstorm.md +382 -0
- package/.claude/commands/memory/tips.md +332 -0
- package/.claude/commands/workflow/analyze-with-file.md +804 -0
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +18 -43
- package/.claude/commands/workflow/brainstorm/role-analysis.md +705 -0
- package/.claude/commands/workflow/brainstorm-with-file.md +1153 -0
- package/.claude/commands/workflow/debug-with-file.md +7 -5
- package/.claude/commands/workflow/execute.md +6 -4
- package/.claude/commands/workflow/lite-plan.md +2 -2
- package/.claude/commands/workflow/plan-verify.md +162 -327
- package/.claude/commands/workflow/plan.md +162 -26
- package/.claude/commands/workflow/replan.md +78 -2
- package/.claude/commands/workflow/{review-fix.md → review-cycle-fix.md} +6 -6
- package/.claude/commands/workflow/review-module-cycle.md +2 -2
- package/.claude/commands/workflow/review-session-cycle.md +2 -2
- package/.claude/commands/workflow/tools/conflict-resolution.md +16 -26
- package/.claude/commands/workflow/tools/context-gather.md +81 -118
- package/.claude/commands/workflow/tools/task-generate-agent.md +94 -10
- package/.claude/skills/ccw-help/command.json +4 -4
- package/.claude/skills/lite-skill-generator/SKILL.md +650 -0
- package/.claude/skills/lite-skill-generator/templates/simple-skill.md +68 -0
- package/.claude/skills/lite-skill-generator/templates/style-guide.md +64 -0
- package/.claude/skills/skill-generator/SKILL.md +277 -85
- package/.claude/skills/skill-generator/phases/01-requirements-discovery.md +4 -15
- package/.claude/skills/skill-generator/phases/02-structure-generation.md +72 -17
- package/.claude/skills/skill-generator/phases/03-phase-generation.md +218 -51
- package/.claude/skills/skill-generator/phases/04-specs-templates.md +111 -41
- package/.claude/skills/skill-generator/phases/05-validation.md +139 -56
- package/.claude/skills/skill-generator/templates/autonomous-action.md +78 -268
- package/.claude/skills/skill-generator/templates/autonomous-orchestrator.md +14 -0
- package/.claude/skills/skill-generator/templates/code-analysis-action.md +12 -0
- package/.claude/skills/skill-generator/templates/llm-action.md +12 -0
- package/.claude/skills/skill-generator/templates/script-template.md +368 -0
- package/.claude/skills/skill-generator/templates/sequential-phase.md +14 -0
- package/.claude/skills/skill-generator/templates/skill-md.md +14 -0
- package/.claude/skills/skill-tuning/SKILL.md +130 -266
- package/.claude/skills/skill-tuning/phases/orchestrator.md +95 -283
- package/.claude/skills/skill-tuning/specs/problem-taxonomy.md +90 -198
- package/.claude/skills/skill-tuning/specs/tuning-strategies.md +193 -1345
- package/.claude/workflows/cli-templates/schemas/plan-verify-agent-schema.json +47 -0
- package/.claude/workflows/cli-templates/schemas/verify-json-schema.json +158 -0
- package/.claude/workflows/cli-tools-usage.md +1 -1
- package/.codex/AGENTS.md +1 -3
- package/.codex/prompts/analyze-with-file.md +607 -0
- package/.codex/prompts/brainstorm-to-cycle.md +455 -0
- package/.codex/prompts/brainstorm-with-file.md +933 -0
- package/.codex/prompts/debug-with-file.md +15 -20
- package/.codex/skills/ccw-cli-tools/SKILL.md +559 -0
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +29 -5
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/commands/issue.d.ts +2 -0
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +62 -20
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.js +5 -3
- package/ccw/dist/config/litellm-api-config-manager.js.map +1 -1
- package/ccw/dist/config/litellm-provider-models.d.ts +73 -0
- package/ccw/dist/config/litellm-provider-models.d.ts.map +1 -0
- package/ccw/dist/config/litellm-provider-models.js +172 -0
- package/ccw/dist/config/litellm-provider-models.js.map +1 -0
- package/ccw/dist/config/provider-models.d.ts +25 -51
- package/ccw/dist/config/provider-models.d.ts.map +1 -1
- package/ccw/dist/config/provider-models.js +84 -149
- package/ccw/dist/config/provider-models.js.map +1 -1
- package/ccw/dist/config/storage-paths.d.ts.map +1 -1
- package/ccw/dist/config/storage-paths.js +23 -5
- package/ccw/dist/config/storage-paths.js.map +1 -1
- package/ccw/dist/core/auth/csrf-middleware.js +3 -3
- package/ccw/dist/core/auth/csrf-middleware.js.map +1 -1
- package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
- package/ccw/dist/core/dashboard-generator.js +3 -1
- package/ccw/dist/core/dashboard-generator.js.map +1 -1
- package/ccw/dist/core/routes/claude-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/claude-routes.js +206 -14
- package/ccw/dist/core/routes/claude-routes.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/commands-routes.d.ts +7 -0
- package/ccw/dist/core/routes/commands-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/commands-routes.js +480 -0
- package/ccw/dist/core/routes/commands-routes.js.map +1 -0
- package/ccw/dist/core/routes/model-routes.d.ts +11 -0
- package/ccw/dist/core/routes/model-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/model-routes.js +112 -0
- package/ccw/dist/core/routes/model-routes.js.map +1 -0
- package/ccw/dist/core/routes/nav-status-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/nav-status-routes.js +84 -1
- package/ccw/dist/core/routes/nav-status-routes.js.map +1 -1
- package/ccw/dist/core/routes/provider-routes.d.ts +11 -0
- package/ccw/dist/core/routes/provider-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/provider-routes.js +67 -0
- package/ccw/dist/core/routes/provider-routes.js.map +1 -0
- package/ccw/dist/core/routes/skills-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/skills-routes.js +219 -7
- package/ccw/dist/core/routes/skills-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +58 -6
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/server.d.ts.map +1 -1
- package/ccw/dist/core/server.js +13 -0
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/mcp-server/index.js +2 -2
- package/ccw/dist/mcp-server/index.js.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.d.ts +48 -11
- package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.js +146 -50
- package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
- package/ccw/dist/tools/cli-config-manager.d.ts +1 -13
- package/ccw/dist/tools/cli-config-manager.d.ts.map +1 -1
- package/ccw/dist/tools/cli-config-manager.js +3 -27
- package/ccw/dist/tools/cli-config-manager.js.map +1 -1
- package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor-core.js +7 -2
- package/ccw/dist/tools/cli-executor-core.js.map +1 -1
- package/ccw/dist/tools/cli-executor-state.d.ts.map +1 -1
- package/ccw/dist/tools/cli-history-store.d.ts +11 -0
- package/ccw/dist/tools/cli-history-store.d.ts.map +1 -1
- package/ccw/dist/tools/cli-history-store.js +82 -2
- package/ccw/dist/tools/cli-history-store.js.map +1 -1
- package/ccw/dist/tools/command-registry.d.ts +7 -0
- package/ccw/dist/tools/command-registry.d.ts.map +1 -1
- package/ccw/dist/tools/command-registry.js +14 -1
- package/ccw/dist/tools/command-registry.js.map +1 -1
- package/ccw/dist/tools/generate-module-docs.d.ts.map +1 -1
- package/ccw/dist/tools/generate-module-docs.js +11 -7
- package/ccw/dist/tools/generate-module-docs.js.map +1 -1
- package/ccw/dist/tools/litellm-executor.d.ts +1 -0
- package/ccw/dist/tools/litellm-executor.d.ts.map +1 -1
- package/ccw/dist/tools/litellm-executor.js +11 -9
- package/ccw/dist/tools/litellm-executor.js.map +1 -1
- package/ccw/dist/types/skill-types.d.ts +97 -0
- package/ccw/dist/types/skill-types.d.ts.map +1 -0
- package/ccw/dist/types/skill-types.js +6 -0
- package/ccw/dist/types/skill-types.js.map +1 -0
- package/ccw/src/commands/cli.ts +36 -5
- package/ccw/src/commands/issue.ts +81 -26
- package/ccw/src/config/litellm-api-config-manager.ts +5 -3
- package/ccw/src/config/litellm-provider-models.ts +222 -0
- package/ccw/src/config/provider-models.ts +91 -190
- package/ccw/src/config/storage-paths.ts +20 -5
- package/ccw/src/core/auth/csrf-middleware.ts +3 -3
- package/ccw/src/core/dashboard-generator.ts +3 -1
- package/ccw/src/core/routes/claude-routes.ts +233 -15
- package/ccw/src/core/routes/cli-routes.ts +2 -3
- package/ccw/src/core/routes/commands-routes.ts +620 -0
- package/ccw/src/core/routes/nav-status-routes.ts +95 -1
- package/ccw/src/core/routes/provider-routes.ts +78 -0
- package/ccw/src/core/routes/skills-routes.ts +266 -45
- package/ccw/src/core/routes/system-routes.ts +102 -50
- package/ccw/src/core/server.ts +13 -0
- package/ccw/src/mcp-server/index.ts +2 -2
- package/ccw/src/templates/dashboard-css/18-cli-settings.css +35 -0
- package/ccw/src/templates/dashboard-css/37-commands.css +193 -0
- package/ccw/src/templates/dashboard-js/components/navigation.js +4 -0
- package/ccw/src/templates/dashboard-js/i18n.js +116 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +249 -4
- package/ccw/src/templates/dashboard-js/views/commands-manager.js +503 -0
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +7 -7
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +2 -7
- package/ccw/src/templates/dashboard-js/views/skills-manager.js +164 -23
- package/ccw/src/templates/dashboard.html +7 -0
- package/ccw/src/tools/claude-cli-tools.ts +170 -56
- package/ccw/src/tools/cli-config-manager.ts +2 -33
- package/ccw/src/tools/cli-executor-core.ts +8 -2
- package/ccw/src/tools/cli-history-store.ts +92 -2
- package/ccw/src/tools/command-registry.ts +16 -1
- package/ccw/src/tools/generate-module-docs.ts +11 -7
- package/ccw/src/tools/litellm-executor.ts +13 -9
- package/ccw/src/types/skill-types.ts +99 -0
- package/package.json +1 -1
- package/.claude/commands/enhance-prompt.md +0 -93
- package/.claude/commands/memory/code-map-memory.md +0 -687
- package/.claude/commands/memory/docs.md +0 -615
- package/.claude/commands/memory/load-skill-memory.md +0 -182
- package/.claude/commands/memory/skill-memory.md +0 -525
- package/.claude/commands/memory/swagger-docs.md +0 -773
- package/.claude/commands/memory/tech-research-rules.md +0 -310
- package/.claude/commands/memory/workflow-skill-memory.md +0 -517
- package/.claude/commands/task/breakdown.md +0 -208
- package/.claude/commands/task/create.md +0 -152
- package/.claude/commands/task/execute.md +0 -270
- package/.claude/commands/task/replan.md +0 -441
- package/.claude/commands/version.md +0 -254
- package/.claude/commands/workflow/action-plan-verify.md +0 -485
- package/.claude/commands/workflow/brainstorm/api-designer.md +0 -587
- package/.claude/commands/workflow/brainstorm/data-architect.md +0 -220
- package/.claude/commands/workflow/brainstorm/product-manager.md +0 -200
- package/.claude/commands/workflow/brainstorm/product-owner.md +0 -200
- package/.claude/commands/workflow/brainstorm/scrum-master.md +0 -200
- package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +0 -200
- package/.claude/commands/workflow/brainstorm/system-architect.md +0 -389
- package/.claude/commands/workflow/brainstorm/ui-designer.md +0 -221
- package/.claude/commands/workflow/brainstorm/ux-expert.md +0 -221
- package/.claude/commands/workflow/debug.md +0 -331
- package/.claude/commands/workflow/develop-with-file.md +0 -1044
- package/.claude/skills/ccw-loop/README.md +0 -303
- package/.claude/skills/skill-generator/templates/script-bash.md +0 -277
- package/.claude/skills/skill-generator/templates/script-python.md +0 -198
- package/.codex/prompts/debug.md +0 -318
- package/ccw/src/core/routes/mcp-routes.ts.backup +0 -549
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
// Commands Manager View
|
|
2
|
+
// Manages Claude Code commands (.claude/commands/)
|
|
3
|
+
|
|
4
|
+
// ========== Commands State ==========
|
|
5
|
+
var commandsData = {
|
|
6
|
+
groups: {}, // Organized by group name: { cli: [...], workflow: [...], memory: [...], task: [...], issue: [...] }
|
|
7
|
+
allCommands: [],
|
|
8
|
+
projectGroupsConfig: { groups: {}, assignments: {} },
|
|
9
|
+
userGroupsConfig: { groups: {}, assignments: {} }
|
|
10
|
+
};
|
|
11
|
+
var expandedGroups = {
|
|
12
|
+
cli: true,
|
|
13
|
+
workflow: true,
|
|
14
|
+
memory: true,
|
|
15
|
+
task: true,
|
|
16
|
+
issue: true
|
|
17
|
+
};
|
|
18
|
+
var showDisabledCommands = false;
|
|
19
|
+
var commandsLoading = false;
|
|
20
|
+
var currentLocation = 'project'; // 'project' or 'user'
|
|
21
|
+
|
|
22
|
+
// ========== Main Render Function ==========
|
|
23
|
+
async function renderCommandsManager() {
|
|
24
|
+
const container = document.getElementById('mainContent');
|
|
25
|
+
if (!container) return;
|
|
26
|
+
|
|
27
|
+
// Hide stats grid and search
|
|
28
|
+
const statsGrid = document.getElementById('statsGrid');
|
|
29
|
+
const searchInput = document.getElementById('searchInput');
|
|
30
|
+
if (statsGrid) statsGrid.style.display = 'none';
|
|
31
|
+
if (searchInput) searchInput.parentElement.style.display = 'none';
|
|
32
|
+
|
|
33
|
+
// Show loading state
|
|
34
|
+
container.innerHTML = '<div class="commands-manager loading">' +
|
|
35
|
+
'<div class="loading-spinner"><i data-lucide="loader-2" class="w-8 h-8 animate-spin"></i></div>' +
|
|
36
|
+
'<p>' + t('common.loading') + '</p>' +
|
|
37
|
+
'</div>';
|
|
38
|
+
|
|
39
|
+
// Load commands data
|
|
40
|
+
await loadCommandsData();
|
|
41
|
+
|
|
42
|
+
// Render the main view
|
|
43
|
+
renderCommandsView();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function loadCommandsData() {
|
|
47
|
+
commandsLoading = true;
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch('/api/commands?path=' + encodeURIComponent(projectPath));
|
|
50
|
+
if (!response.ok) throw new Error('Failed to load commands');
|
|
51
|
+
const data = await response.json();
|
|
52
|
+
|
|
53
|
+
// Store groups config
|
|
54
|
+
commandsData.projectGroupsConfig = data.projectGroupsConfig || { groups: {}, assignments: {} };
|
|
55
|
+
commandsData.userGroupsConfig = data.userGroupsConfig || { groups: {}, assignments: {} };
|
|
56
|
+
|
|
57
|
+
// Filter commands based on currentLocation
|
|
58
|
+
const allCommands = currentLocation === 'project'
|
|
59
|
+
? (data.projectCommands || [])
|
|
60
|
+
: (data.userCommands || []);
|
|
61
|
+
|
|
62
|
+
// Organize commands by group
|
|
63
|
+
commandsData.groups = {};
|
|
64
|
+
commandsData.allCommands = allCommands;
|
|
65
|
+
|
|
66
|
+
allCommands.forEach(cmd => {
|
|
67
|
+
const group = cmd.group || 'other';
|
|
68
|
+
if (!commandsData.groups[group]) {
|
|
69
|
+
commandsData.groups[group] = [];
|
|
70
|
+
}
|
|
71
|
+
commandsData.groups[group].push(cmd);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Update badge
|
|
75
|
+
updateCommandsBadge();
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.error('Failed to load commands:', err);
|
|
78
|
+
commandsData = {
|
|
79
|
+
groups: {},
|
|
80
|
+
allCommands: [],
|
|
81
|
+
projectGroupsConfig: { groups: {}, assignments: {} },
|
|
82
|
+
userGroupsConfig: { groups: {}, assignments: {} }
|
|
83
|
+
};
|
|
84
|
+
} finally {
|
|
85
|
+
commandsLoading = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function updateCommandsBadge() {
|
|
90
|
+
const badge = document.getElementById('badgeCommands');
|
|
91
|
+
if (badge) {
|
|
92
|
+
const enabledCount = commandsData.allCommands.filter(cmd => cmd.enabled).length;
|
|
93
|
+
badge.textContent = enabledCount;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function switchLocation(location) {
|
|
98
|
+
if (location === currentLocation) return;
|
|
99
|
+
currentLocation = location;
|
|
100
|
+
await loadCommandsData();
|
|
101
|
+
renderCommandsView();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function renderCommandsView() {
|
|
105
|
+
const container = document.getElementById('mainContent');
|
|
106
|
+
if (!container) return;
|
|
107
|
+
|
|
108
|
+
const groups = commandsData.groups || {};
|
|
109
|
+
|
|
110
|
+
// Dynamic groups: known groups first, then custom groups hierarchically sorted, 'other' last
|
|
111
|
+
const knownOrder = ['cli', 'workflow', 'memory', 'task', 'issue'];
|
|
112
|
+
const allGroupNames = Object.keys(groups);
|
|
113
|
+
|
|
114
|
+
// Separate top-level known groups and nested groups
|
|
115
|
+
const topLevelKnown = allGroupNames.filter(g => knownOrder.includes(g));
|
|
116
|
+
const nestedAndCustom = allGroupNames.filter(g => g !== 'other' && !knownOrder.includes(g));
|
|
117
|
+
|
|
118
|
+
// Sort nested/custom groups hierarchically
|
|
119
|
+
nestedAndCustom.sort((a, b) => {
|
|
120
|
+
// Split by path separator
|
|
121
|
+
const aParts = a.split('/');
|
|
122
|
+
const bParts = b.split('/');
|
|
123
|
+
|
|
124
|
+
// Compare level by level
|
|
125
|
+
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
|
|
126
|
+
if (aParts[i] !== bParts[i]) {
|
|
127
|
+
return aParts[i].localeCompare(bParts[i]);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// If all parts are equal, shorter path comes first
|
|
132
|
+
return aParts.length - bParts.length;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const groupNames = [...topLevelKnown.filter(g => groups[g] && groups[g].length > 0),
|
|
136
|
+
...nestedAndCustom.filter(g => groups[g] && groups[g].length > 0),
|
|
137
|
+
'other'].filter(g => groups[g] && groups[g].length > 0);
|
|
138
|
+
const totalEnabled = commandsData.allCommands.filter(cmd => cmd.enabled).length;
|
|
139
|
+
const totalDisabled = commandsData.allCommands.filter(cmd => !cmd.enabled).length;
|
|
140
|
+
|
|
141
|
+
container.innerHTML = `
|
|
142
|
+
<div class="commands-manager">
|
|
143
|
+
<!-- Header -->
|
|
144
|
+
<div class="commands-header mb-6">
|
|
145
|
+
<div class="flex items-center justify-between">
|
|
146
|
+
<div class="flex items-center gap-3">
|
|
147
|
+
<div class="w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center">
|
|
148
|
+
<i data-lucide="terminal" class="w-5 h-5 text-primary"></i>
|
|
149
|
+
</div>
|
|
150
|
+
<div>
|
|
151
|
+
<h2 class="text-lg font-semibold text-foreground">${t('commands.title') || 'Commands Manager'}</h2>
|
|
152
|
+
<p class="text-sm text-muted-foreground">${t('commands.description') || 'Enable/disable CCW commands'}</p>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
<div class="flex items-center gap-2">
|
|
156
|
+
<!-- Location Switcher -->
|
|
157
|
+
<div class="inline-flex bg-muted rounded-lg p-1">
|
|
158
|
+
<button class="px-3 py-1.5 text-sm rounded-md transition-all ${currentLocation === 'project' ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}"
|
|
159
|
+
onclick="switchLocation('project')">
|
|
160
|
+
<i data-lucide="folder" class="w-3.5 h-3.5 inline mr-1"></i>
|
|
161
|
+
${t('commands.locationProject') || 'Project'}
|
|
162
|
+
</button>
|
|
163
|
+
<button class="px-3 py-1.5 text-sm rounded-md transition-all ${currentLocation === 'user' ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}"
|
|
164
|
+
onclick="switchLocation('user')">
|
|
165
|
+
<i data-lucide="user" class="w-3.5 h-3.5 inline mr-1"></i>
|
|
166
|
+
${t('commands.locationUser') || 'Global'}
|
|
167
|
+
</button>
|
|
168
|
+
</div>
|
|
169
|
+
<!-- Show Disabled Toggle -->
|
|
170
|
+
<button class="px-4 py-2 text-sm ${showDisabledCommands ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'} rounded-lg hover:opacity-90 transition-opacity flex items-center gap-2"
|
|
171
|
+
onclick="toggleShowDisabledCommands()">
|
|
172
|
+
<i data-lucide="${showDisabledCommands ? 'eye' : 'eye-off'}" class="w-4 h-4"></i>
|
|
173
|
+
${showDisabledCommands ? (t('commands.hideDisabled') || 'Hide Disabled') : (t('commands.showDisabled') || 'Show Disabled')} (${totalDisabled})
|
|
174
|
+
</button>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<!-- Summary Stats -->
|
|
180
|
+
<div class="commands-stats mb-6">
|
|
181
|
+
<div class="grid grid-cols-3 gap-4">
|
|
182
|
+
<div class="bg-card border border-border rounded-lg p-4">
|
|
183
|
+
<div class="text-2xl font-bold text-foreground">${commandsData.allCommands.length}</div>
|
|
184
|
+
<div class="text-sm text-muted-foreground">${t('commands.totalCommands') || 'Total Commands'}</div>
|
|
185
|
+
</div>
|
|
186
|
+
<div class="bg-card border border-border rounded-lg p-4">
|
|
187
|
+
<div class="text-2xl font-bold text-success">${totalEnabled}</div>
|
|
188
|
+
<div class="text-sm text-muted-foreground">${t('commands.enabledCommands') || 'Enabled'}</div>
|
|
189
|
+
</div>
|
|
190
|
+
<div class="bg-card border border-border rounded-lg p-4">
|
|
191
|
+
<div class="text-2xl font-bold text-muted-foreground">${totalDisabled}</div>
|
|
192
|
+
<div class="text-sm text-muted-foreground">${t('commands.disabledCommands') || 'Disabled'}</div>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<!-- Accordion Groups -->
|
|
198
|
+
<div class="commands-accordion">
|
|
199
|
+
${groupNames.map(groupName => renderAccordionGroup(groupName, groups[groupName])).join('')}
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
`;
|
|
203
|
+
|
|
204
|
+
// Initialize Lucide icons
|
|
205
|
+
if (typeof lucide !== 'undefined') lucide.createIcons();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Format group name for display (e.g., 'workflow/review' -> 'Workflow > Review')
|
|
209
|
+
function formatGroupName(groupName) {
|
|
210
|
+
if (!groupName.includes('/')) {
|
|
211
|
+
return t('commands.group.' + groupName) || groupName;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Split path and translate each part
|
|
215
|
+
const parts = groupName.split('/');
|
|
216
|
+
const translatedParts = parts.map(part => t('commands.group.' + part) || part);
|
|
217
|
+
return translatedParts.join(' › ');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Get icon for a group (use top-level parent's icon for nested groups)
|
|
221
|
+
function getGroupIcon(groupName) {
|
|
222
|
+
const groupIcons = {
|
|
223
|
+
cli: 'terminal',
|
|
224
|
+
workflow: 'git-branch',
|
|
225
|
+
memory: 'brain',
|
|
226
|
+
task: 'clipboard-list',
|
|
227
|
+
issue: 'alert-circle',
|
|
228
|
+
other: 'folder'
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// For nested groups, use the top-level parent's icon
|
|
232
|
+
const topLevel = groupName.split('/')[0];
|
|
233
|
+
return groupIcons[topLevel] || 'folder';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Get color for a group (use top-level parent's color for nested groups)
|
|
237
|
+
function getGroupColor(groupName) {
|
|
238
|
+
const groupColors = {
|
|
239
|
+
cli: 'text-primary bg-primary/10',
|
|
240
|
+
workflow: 'text-success bg-success/10',
|
|
241
|
+
memory: 'text-indigo bg-indigo/10',
|
|
242
|
+
task: 'text-warning bg-warning/10',
|
|
243
|
+
issue: 'text-destructive bg-destructive/10',
|
|
244
|
+
other: 'text-muted-foreground bg-muted'
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// For nested groups, use the top-level parent's color
|
|
248
|
+
const topLevel = groupName.split('/')[0];
|
|
249
|
+
return groupColors[topLevel] || 'text-muted-foreground bg-muted';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function renderAccordionGroup(groupName, commands) {
|
|
253
|
+
// Default to expanded for new/custom groups
|
|
254
|
+
if (expandedGroups[groupName] === undefined) expandedGroups[groupName] = true;
|
|
255
|
+
const isExpanded = expandedGroups[groupName];
|
|
256
|
+
const enabledCommands = commands.filter(cmd => cmd.enabled);
|
|
257
|
+
const disabledCommands = commands.filter(cmd => !cmd.enabled);
|
|
258
|
+
|
|
259
|
+
// Filter commands based on showDisabledCommands
|
|
260
|
+
const visibleCommands = showDisabledCommands
|
|
261
|
+
? commands
|
|
262
|
+
: enabledCommands;
|
|
263
|
+
|
|
264
|
+
const icon = getGroupIcon(groupName);
|
|
265
|
+
const colorClass = getGroupColor(groupName);
|
|
266
|
+
const displayName = formatGroupName(groupName);
|
|
267
|
+
const indentLevel = (groupName.match(/\//g) || []).length;
|
|
268
|
+
const indentStyle = indentLevel > 0 ? `style="margin-left: ${indentLevel * 20}px;"` : '';
|
|
269
|
+
|
|
270
|
+
return `
|
|
271
|
+
<div class="accordion-group mb-4" ${indentStyle}>
|
|
272
|
+
<!-- Group Header -->
|
|
273
|
+
<div class="accordion-header flex items-center justify-between px-4 py-3 bg-card border border-border rounded-lg hover:bg-hover transition-colors">
|
|
274
|
+
<div class="flex items-center gap-3 flex-1 cursor-pointer" onclick="toggleAccordionGroup('${groupName}')">
|
|
275
|
+
<i data-lucide="${isExpanded ? 'chevron-down' : 'chevron-right'}" class="w-5 h-5 text-muted-foreground transition-transform"></i>
|
|
276
|
+
<div class="w-8 h-8 ${colorClass} rounded-lg flex items-center justify-center">
|
|
277
|
+
<i data-lucide="${icon}" class="w-4 h-4"></i>
|
|
278
|
+
</div>
|
|
279
|
+
<div>
|
|
280
|
+
<h3 class="text-base font-semibold text-foreground">${displayName}</h3>
|
|
281
|
+
<p class="text-xs text-muted-foreground">${enabledCommands.length}/${commands.length} ${t('commands.enabled') || 'enabled'}</p>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
<div class="flex items-center gap-3">
|
|
285
|
+
<!-- Group Toggle Switch -->
|
|
286
|
+
<label class="group-toggle-switch relative inline-flex items-center cursor-pointer" title="${enabledCommands.length === commands.length ? (t('commands.clickToDisableAll') || 'Click to disable all') : (t('commands.clickToEnableAll') || 'Click to enable all')}">
|
|
287
|
+
<input type="checkbox"
|
|
288
|
+
class="sr-only peer"
|
|
289
|
+
${enabledCommands.length === commands.length ? 'checked' : ''}
|
|
290
|
+
onchange="toggleGroupEnabled('${groupName}', ${enabledCommands.length === commands.length})">
|
|
291
|
+
<div class="w-11 h-6 bg-muted peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-success"></div>
|
|
292
|
+
</label>
|
|
293
|
+
<span class="text-xs px-2 py-1 bg-muted rounded-full text-muted-foreground">${commands.length}</span>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
<!-- Group Content (Compact Table) -->
|
|
298
|
+
${isExpanded ? `
|
|
299
|
+
<div class="accordion-content mt-3">
|
|
300
|
+
<div class="bg-card border border-border rounded-lg overflow-hidden">
|
|
301
|
+
<table class="w-full commands-table" style="table-layout: fixed;">
|
|
302
|
+
<colgroup>
|
|
303
|
+
<col style="width: 200px;">
|
|
304
|
+
<col style="width: auto;">
|
|
305
|
+
<col style="width: 100px;">
|
|
306
|
+
<col style="width: 80px;">
|
|
307
|
+
</colgroup>
|
|
308
|
+
<thead class="bg-muted/30 border-b border-border">
|
|
309
|
+
<tr>
|
|
310
|
+
<th class="px-4 py-2 text-left text-xs font-medium text-muted-foreground uppercase">${t('commands.name') || 'Name'}</th>
|
|
311
|
+
<th class="px-4 py-2 text-left text-xs font-medium text-muted-foreground uppercase">${t('commands.description') || 'Description'}</th>
|
|
312
|
+
<th class="px-4 py-2 text-center text-xs font-medium text-muted-foreground uppercase">${t('commands.scope') || 'Scope'}</th>
|
|
313
|
+
<th class="px-4 py-2 text-center text-xs font-medium text-muted-foreground uppercase">${t('commands.status') || 'Status'}</th>
|
|
314
|
+
</tr>
|
|
315
|
+
</thead>
|
|
316
|
+
<tbody class="divide-y divide-border">
|
|
317
|
+
${visibleCommands.map(cmd => renderCommandRow(cmd)).join('')}
|
|
318
|
+
</tbody>
|
|
319
|
+
</table>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
` : ''}
|
|
323
|
+
</div>
|
|
324
|
+
`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function renderCommandRow(command) {
|
|
328
|
+
const isDisabled = !command.enabled;
|
|
329
|
+
|
|
330
|
+
return `
|
|
331
|
+
<tr class="hover:bg-muted/20 transition-colors ${isDisabled ? 'opacity-60' : ''}">
|
|
332
|
+
<td class="px-4 py-3 text-sm font-medium text-foreground">
|
|
333
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
334
|
+
<span class="break-words">${escapeHtml(command.name)}</span>
|
|
335
|
+
${command.triggers && command.triggers.length > 0 ? `
|
|
336
|
+
<span class="text-xs px-1.5 py-0.5 bg-warning/10 text-warning rounded flex-shrink-0" title="${command.triggers.length} trigger(s)">
|
|
337
|
+
<i data-lucide="zap" class="w-3 h-3 inline mr-0.5"></i>${command.triggers.length}
|
|
338
|
+
</span>
|
|
339
|
+
` : ''}
|
|
340
|
+
</div>
|
|
341
|
+
</td>
|
|
342
|
+
<td class="px-4 py-3 text-sm text-muted-foreground">
|
|
343
|
+
<div class="line-clamp-3 break-words">${escapeHtml(command.description || t('commands.noDescription') || '-')}</div>
|
|
344
|
+
</td>
|
|
345
|
+
<td class="px-4 py-3 text-center text-xs text-muted-foreground">
|
|
346
|
+
<span class="whitespace-nowrap">${command.scope || 'project'}</span>
|
|
347
|
+
</td>
|
|
348
|
+
<td class="px-4 py-3">
|
|
349
|
+
<div class="flex justify-center">
|
|
350
|
+
<label class="command-toggle-switch relative inline-flex items-center cursor-pointer">
|
|
351
|
+
<input type="checkbox"
|
|
352
|
+
class="sr-only peer"
|
|
353
|
+
${command.enabled ? 'checked' : ''}
|
|
354
|
+
onchange="toggleCommandEnabled('${escapeHtml(command.name)}', ${command.enabled})"
|
|
355
|
+
data-command-toggle="${escapeHtml(command.name)}">
|
|
356
|
+
<div class="w-11 h-6 bg-muted peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
|
|
357
|
+
</label>
|
|
358
|
+
</div>
|
|
359
|
+
</td>
|
|
360
|
+
</tr>
|
|
361
|
+
`;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function getGroupBadgeClass(group) {
|
|
365
|
+
const classes = {
|
|
366
|
+
cli: 'bg-primary/10 text-primary',
|
|
367
|
+
workflow: 'bg-success/10 text-success',
|
|
368
|
+
memory: 'bg-indigo/10 text-indigo',
|
|
369
|
+
task: 'bg-warning/10 text-warning',
|
|
370
|
+
issue: 'bg-destructive/10 text-destructive',
|
|
371
|
+
other: 'bg-muted text-muted-foreground'
|
|
372
|
+
};
|
|
373
|
+
return classes[group] || classes.other;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function toggleAccordionGroup(groupName) {
|
|
377
|
+
expandedGroups[groupName] = !expandedGroups[groupName];
|
|
378
|
+
renderCommandsView();
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function toggleShowDisabledCommands() {
|
|
382
|
+
showDisabledCommands = !showDisabledCommands;
|
|
383
|
+
renderCommandsView();
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Track loading state for command toggle operations
|
|
387
|
+
var toggleLoadingCommands = {};
|
|
388
|
+
|
|
389
|
+
async function toggleCommandEnabled(commandName, currentlyEnabled) {
|
|
390
|
+
// Prevent double-click
|
|
391
|
+
var loadingKey = commandName;
|
|
392
|
+
if (toggleLoadingCommands[loadingKey]) return;
|
|
393
|
+
|
|
394
|
+
// Set loading state
|
|
395
|
+
toggleLoadingCommands[loadingKey] = true;
|
|
396
|
+
var toggleInput = document.querySelector('[data-command-toggle="' + commandName + '"]');
|
|
397
|
+
if (toggleInput) {
|
|
398
|
+
toggleInput.disabled = true;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
try {
|
|
402
|
+
var response = await fetch('/api/commands/' + encodeURIComponent(commandName) + '/toggle', {
|
|
403
|
+
method: 'POST',
|
|
404
|
+
headers: { 'Content-Type': 'application/json' },
|
|
405
|
+
body: JSON.stringify({
|
|
406
|
+
projectPath: projectPath,
|
|
407
|
+
location: currentLocation,
|
|
408
|
+
enable: !currentlyEnabled
|
|
409
|
+
})
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
if (!response.ok) {
|
|
413
|
+
// Robust JSON parsing with fallback
|
|
414
|
+
var errorMessage = 'Operation failed';
|
|
415
|
+
try {
|
|
416
|
+
var error = await response.json();
|
|
417
|
+
errorMessage = error.message || errorMessage;
|
|
418
|
+
} catch (jsonErr) {
|
|
419
|
+
errorMessage = response.statusText || errorMessage;
|
|
420
|
+
}
|
|
421
|
+
throw new Error(errorMessage);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Reload commands data
|
|
425
|
+
await loadCommandsData();
|
|
426
|
+
renderCommandsView();
|
|
427
|
+
|
|
428
|
+
if (window.showToast) {
|
|
429
|
+
var message = currentlyEnabled
|
|
430
|
+
? t('commands.disableSuccess', { name: commandName }) || `Command "${commandName}" disabled`
|
|
431
|
+
: t('commands.enableSuccess', { name: commandName }) || `Command "${commandName}" enabled`;
|
|
432
|
+
showToast(message, 'success');
|
|
433
|
+
}
|
|
434
|
+
} catch (err) {
|
|
435
|
+
console.error('Failed to toggle command:', err);
|
|
436
|
+
if (window.showToast) {
|
|
437
|
+
showToast(err.message || t('commands.toggleError') || 'Failed to toggle command', 'error');
|
|
438
|
+
}
|
|
439
|
+
// Reset toggle state on error
|
|
440
|
+
if (toggleInput) {
|
|
441
|
+
toggleInput.checked = currentlyEnabled;
|
|
442
|
+
}
|
|
443
|
+
} finally {
|
|
444
|
+
// Clear loading state
|
|
445
|
+
delete toggleLoadingCommands[loadingKey];
|
|
446
|
+
if (toggleInput) {
|
|
447
|
+
toggleInput.disabled = false;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async function toggleGroupEnabled(groupName, currentlyAllEnabled) {
|
|
453
|
+
const enable = !currentlyAllEnabled;
|
|
454
|
+
|
|
455
|
+
try {
|
|
456
|
+
const response = await fetch('/api/commands/group/' + encodeURIComponent(groupName) + '/toggle', {
|
|
457
|
+
method: 'POST',
|
|
458
|
+
headers: { 'Content-Type': 'application/json' },
|
|
459
|
+
body: JSON.stringify({
|
|
460
|
+
projectPath: projectPath,
|
|
461
|
+
location: currentLocation,
|
|
462
|
+
enable: enable
|
|
463
|
+
})
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
if (!response.ok) {
|
|
467
|
+
var errorMessage = 'Operation failed';
|
|
468
|
+
try {
|
|
469
|
+
var error = await response.json();
|
|
470
|
+
errorMessage = error.message || errorMessage;
|
|
471
|
+
} catch (jsonErr) {
|
|
472
|
+
errorMessage = response.statusText || errorMessage;
|
|
473
|
+
}
|
|
474
|
+
throw new Error(errorMessage);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Reload commands data
|
|
478
|
+
await loadCommandsData();
|
|
479
|
+
renderCommandsView();
|
|
480
|
+
|
|
481
|
+
if (window.showToast) {
|
|
482
|
+
const groupLabel = t('commands.group.' + groupName) || groupName;
|
|
483
|
+
const message = enable
|
|
484
|
+
? (t('commands.enableGroupSuccess', { group: groupLabel }) || `Group "${groupLabel}" enabled`)
|
|
485
|
+
: (t('commands.disableGroupSuccess', { group: groupLabel }) || `Group "${groupLabel}" disabled`);
|
|
486
|
+
showToast(message, 'success');
|
|
487
|
+
}
|
|
488
|
+
} catch (err) {
|
|
489
|
+
console.error('Failed to toggle group:', err);
|
|
490
|
+
if (window.showToast) {
|
|
491
|
+
showToast(err.message || t('commands.toggleError') || 'Failed to toggle group', 'error');
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function formatDisabledDate(isoString) {
|
|
497
|
+
try {
|
|
498
|
+
const date = new Date(isoString);
|
|
499
|
+
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
500
|
+
} catch {
|
|
501
|
+
return isoString;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
@@ -702,7 +702,7 @@ function renderQueueCard(queue, isActive) {
|
|
|
702
702
|
const completedCount = queue.completed_solutions || queue.completed_tasks || 0;
|
|
703
703
|
const progressPercent = itemCount > 0 ? Math.round((completedCount / itemCount) * 100) : 0;
|
|
704
704
|
const issueCount = queue.issue_ids?.length || 0;
|
|
705
|
-
const statusClass = queue.status
|
|
705
|
+
const statusClass = queue.status || '';
|
|
706
706
|
const safeQueueId = escapeHtml(queue.id || '');
|
|
707
707
|
|
|
708
708
|
return `
|
|
@@ -740,17 +740,17 @@ function renderQueueCard(queue, isActive) {
|
|
|
740
740
|
<button class="btn-sm" onclick="toggleQueueExpand('${safeQueueId}')" title="View details">
|
|
741
741
|
<i data-lucide="eye" class="w-3 h-3"></i>
|
|
742
742
|
</button>
|
|
743
|
-
${!isActive && queue.status !== '
|
|
743
|
+
${!isActive && queue.status !== 'archived' ? `
|
|
744
744
|
<button class="btn-sm btn-primary" onclick="activateQueue('${safeQueueId}')" title="Set as active">
|
|
745
745
|
<i data-lucide="check-circle" class="w-3 h-3"></i>
|
|
746
746
|
</button>
|
|
747
747
|
` : ''}
|
|
748
|
-
${queue.status !== '
|
|
748
|
+
${queue.status !== 'archived' ? `
|
|
749
749
|
<button class="btn-sm" onclick="showMergeQueueModal('${safeQueueId}')" title="Merge into another queue">
|
|
750
750
|
<i data-lucide="git-merge" class="w-3 h-3"></i>
|
|
751
751
|
</button>
|
|
752
752
|
` : ''}
|
|
753
|
-
${queue.status !== '
|
|
753
|
+
${queue.status !== 'archived' && issueCount > 1 ? `
|
|
754
754
|
<button class="btn-sm" onclick="showSplitQueueModal('${safeQueueId}')" title="Split queue into multiple queues">
|
|
755
755
|
<i data-lucide="git-branch" class="w-3 h-3"></i>
|
|
756
756
|
</button>
|
|
@@ -896,7 +896,7 @@ async function renderExpandedQueueView(queueId) {
|
|
|
896
896
|
</div>
|
|
897
897
|
</div>
|
|
898
898
|
<div class="queue-detail-actions">
|
|
899
|
-
${!isActive && queue.status !== '
|
|
899
|
+
${!isActive && queue.status !== 'archived' ? `
|
|
900
900
|
<button class="btn-primary" onclick="activateQueue('${safeQueueId}')">
|
|
901
901
|
<i data-lucide="check-circle" class="w-4 h-4"></i>
|
|
902
902
|
<span>${t('issues.activate') || 'Activate'}</span>
|
|
@@ -1141,7 +1141,7 @@ function showMergeQueueModal(sourceQueueId) {
|
|
|
1141
1141
|
}
|
|
1142
1142
|
|
|
1143
1143
|
const otherQueues = queueData.queues.filter(q =>
|
|
1144
|
-
q.id !== sourceQueueId && q.status !== '
|
|
1144
|
+
q.id !== sourceQueueId && q.status !== 'archived'
|
|
1145
1145
|
);
|
|
1146
1146
|
|
|
1147
1147
|
const safeSourceId = escapeHtml(sourceQueueId || '');
|
|
@@ -1170,7 +1170,7 @@ function showMergeQueueModal(sourceQueueId) {
|
|
|
1170
1170
|
</div>
|
|
1171
1171
|
<p class="text-sm text-muted-foreground mt-2">
|
|
1172
1172
|
<i data-lucide="info" class="w-4 h-4 inline mr-1"></i>
|
|
1173
|
-
Items from source queue will be appended to target queue. Source queue will be
|
|
1173
|
+
Items from source queue will be appended to target queue. Source queue will be archived.
|
|
1174
1174
|
</p>
|
|
1175
1175
|
`}
|
|
1176
1176
|
</div>
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
// MCP Manager View
|
|
2
2
|
// Renders the MCP server management interface
|
|
3
3
|
|
|
4
|
-
// CCW Tools available for MCP
|
|
4
|
+
// CCW Tools available for MCP (file operations + core memory only)
|
|
5
5
|
const CCW_MCP_TOOLS = [
|
|
6
6
|
// Core tools (always recommended)
|
|
7
7
|
{ name: 'write_file', desc: 'Write/create files', core: true },
|
|
8
8
|
{ name: 'edit_file', desc: 'Edit/replace content', core: true },
|
|
9
|
-
{ name: '
|
|
9
|
+
{ name: 'read_file', desc: 'Read file contents', core: true },
|
|
10
10
|
{ name: 'core_memory', desc: 'Core memory management', core: true },
|
|
11
|
-
// Optional tools
|
|
12
|
-
{ name: 'session_manager', desc: 'Workflow sessions', core: false },
|
|
13
|
-
{ name: 'generate_module_docs', desc: 'Generate docs', core: false },
|
|
14
|
-
{ name: 'update_module_claude', desc: 'Update CLAUDE.md', core: false },
|
|
15
|
-
{ name: 'cli_executor', desc: 'Gemini/Qwen/Codex CLI', core: false },
|
|
16
11
|
];
|
|
17
12
|
|
|
18
13
|
// Get currently enabled tools from installed config (Claude)
|