claude-code-workflow 6.2.7 → 6.3.0
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 +16 -1
- package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +11 -4
- package/.claude/workflows/cli-templates/protocols/write-protocol.md +10 -75
- package/.claude/workflows/cli-tools-usage.md +14 -24
- package/.codex/AGENTS.md +51 -1
- package/.codex/prompts/compact.md +378 -0
- package/.gemini/GEMINI.md +57 -20
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +21 -8
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/cli.d.ts +2 -0
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +129 -8
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/commands/hook.d.ts.map +1 -1
- package/ccw/dist/commands/hook.js +3 -2
- package/ccw/dist/commands/hook.js.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.d.ts +180 -0
- package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -0
- package/ccw/dist/config/litellm-api-config-manager.js +770 -0
- package/ccw/dist/config/litellm-api-config-manager.js.map +1 -0
- package/ccw/dist/config/provider-models.d.ts +73 -0
- package/ccw/dist/config/provider-models.d.ts.map +1 -0
- package/ccw/dist/config/provider-models.js +172 -0
- package/ccw/dist/config/provider-models.js.map +1 -0
- package/ccw/dist/core/cache-manager.d.ts.map +1 -1
- package/ccw/dist/core/cache-manager.js +3 -5
- package/ccw/dist/core/cache-manager.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/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js +169 -0
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.js +234 -18
- package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
- package/ccw/dist/core/routes/hooks-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/hooks-routes.js +30 -32
- package/ccw/dist/core/routes/hooks-routes.js.map +1 -1
- package/ccw/dist/core/routes/litellm-api-routes.d.ts +21 -0
- package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/litellm-api-routes.js +780 -0
- package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -0
- package/ccw/dist/core/routes/litellm-routes.d.ts +20 -0
- package/ccw/dist/core/routes/litellm-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/litellm-routes.js +85 -0
- package/ccw/dist/core/routes/litellm-routes.js.map +1 -0
- package/ccw/dist/core/routes/mcp-routes.js +2 -2
- package/ccw/dist/core/routes/mcp-routes.js.map +1 -1
- package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/status-routes.js +39 -0
- package/ccw/dist/core/routes/status-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +1 -1
- 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 +15 -1
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/mcp-server/index.js +1 -1
- package/ccw/dist/mcp-server/index.js.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.d.ts +82 -0
- package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -0
- package/ccw/dist/tools/claude-cli-tools.js +216 -0
- package/ccw/dist/tools/claude-cli-tools.js.map +1 -0
- package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor.js +76 -14
- package/ccw/dist/tools/cli-executor.js.map +1 -1
- package/ccw/dist/tools/codex-lens.d.ts +9 -2
- package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens.js +114 -9
- package/ccw/dist/tools/codex-lens.js.map +1 -1
- package/ccw/dist/tools/context-cache-store.d.ts +136 -0
- package/ccw/dist/tools/context-cache-store.d.ts.map +1 -0
- package/ccw/dist/tools/context-cache-store.js +256 -0
- package/ccw/dist/tools/context-cache-store.js.map +1 -0
- package/ccw/dist/tools/context-cache.d.ts +56 -0
- package/ccw/dist/tools/context-cache.d.ts.map +1 -0
- package/ccw/dist/tools/context-cache.js +294 -0
- package/ccw/dist/tools/context-cache.js.map +1 -0
- package/ccw/dist/tools/core-memory.d.ts.map +1 -1
- package/ccw/dist/tools/core-memory.js +33 -19
- package/ccw/dist/tools/core-memory.js.map +1 -1
- package/ccw/dist/tools/index.d.ts.map +1 -1
- package/ccw/dist/tools/index.js +2 -0
- package/ccw/dist/tools/index.js.map +1 -1
- package/ccw/dist/tools/litellm-client.d.ts +85 -0
- package/ccw/dist/tools/litellm-client.d.ts.map +1 -0
- package/ccw/dist/tools/litellm-client.js +188 -0
- package/ccw/dist/tools/litellm-client.js.map +1 -0
- package/ccw/dist/tools/litellm-executor.d.ts +34 -0
- package/ccw/dist/tools/litellm-executor.d.ts.map +1 -0
- package/ccw/dist/tools/litellm-executor.js +192 -0
- package/ccw/dist/tools/litellm-executor.js.map +1 -0
- package/ccw/dist/tools/pattern-parser.d.ts +55 -0
- package/ccw/dist/tools/pattern-parser.d.ts.map +1 -0
- package/ccw/dist/tools/pattern-parser.js +237 -0
- package/ccw/dist/tools/pattern-parser.js.map +1 -0
- package/ccw/dist/tools/smart-search.d.ts +1 -0
- package/ccw/dist/tools/smart-search.d.ts.map +1 -1
- package/ccw/dist/tools/smart-search.js +117 -41
- package/ccw/dist/tools/smart-search.js.map +1 -1
- package/ccw/dist/types/litellm-api-config.d.ts +294 -0
- package/ccw/dist/types/litellm-api-config.d.ts.map +1 -0
- package/ccw/dist/types/litellm-api-config.js +8 -0
- package/ccw/dist/types/litellm-api-config.js.map +1 -0
- package/ccw/src/cli.ts +258 -244
- package/ccw/src/commands/cli.ts +153 -9
- package/ccw/src/commands/hook.ts +3 -2
- package/ccw/src/config/.litellm-api-config-manager.ts.2025-12-23T11-57-43-727Z.bak +441 -0
- package/ccw/src/config/litellm-api-config-manager.ts +1012 -0
- package/ccw/src/config/provider-models.ts +222 -0
- package/ccw/src/core/cache-manager.ts +292 -294
- package/ccw/src/core/dashboard-generator.ts +3 -1
- package/ccw/src/core/routes/cli-routes.ts +192 -0
- package/ccw/src/core/routes/codexlens-routes.ts +241 -19
- package/ccw/src/core/routes/hooks-routes.ts +399 -405
- package/ccw/src/core/routes/litellm-api-routes.ts +930 -0
- package/ccw/src/core/routes/litellm-routes.ts +107 -0
- package/ccw/src/core/routes/mcp-routes.ts +1271 -1271
- package/ccw/src/core/routes/status-routes.ts +51 -0
- package/ccw/src/core/routes/system-routes.ts +1 -1
- package/ccw/src/core/server.ts +15 -1
- package/ccw/src/mcp-server/index.ts +1 -1
- package/ccw/src/templates/dashboard-css/12-cli-legacy.css +44 -0
- package/ccw/src/templates/dashboard-css/31-api-settings.css +2265 -0
- package/ccw/src/templates/dashboard-js/components/cli-history.js +15 -8
- package/ccw/src/templates/dashboard-js/components/cli-status.js +323 -9
- package/ccw/src/templates/dashboard-js/components/navigation.js +329 -313
- package/ccw/src/templates/dashboard-js/i18n.js +583 -1
- package/ccw/src/templates/dashboard-js/views/api-settings.js +3362 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +199 -24
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +1265 -27
- package/ccw/src/templates/dashboard.html +840 -831
- package/ccw/src/tools/claude-cli-tools.ts +300 -0
- package/ccw/src/tools/cli-executor.ts +83 -14
- package/ccw/src/tools/codex-lens.ts +146 -9
- package/ccw/src/tools/context-cache-store.ts +368 -0
- package/ccw/src/tools/context-cache.ts +393 -0
- package/ccw/src/tools/core-memory.ts +33 -19
- package/ccw/src/tools/index.ts +2 -0
- package/ccw/src/tools/litellm-client.ts +246 -0
- package/ccw/src/tools/litellm-executor.ts +241 -0
- package/ccw/src/tools/pattern-parser.ts +329 -0
- package/ccw/src/tools/smart-search.ts +142 -41
- package/ccw/src/types/litellm-api-config.ts +402 -0
- package/ccw-litellm/README.md +180 -0
- package/ccw-litellm/pyproject.toml +35 -0
- package/ccw-litellm/src/ccw_litellm/__init__.py +47 -0
- package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/__pycache__/cli.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/cli.py +108 -0
- package/ccw-litellm/src/ccw_litellm/clients/__init__.py +12 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +251 -0
- package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +165 -0
- package/ccw-litellm/src/ccw_litellm/config/__init__.py +22 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/loader.py +316 -0
- package/ccw-litellm/src/ccw_litellm/config/models.py +130 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__init__.py +14 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/embedder.py +52 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/llm.py +45 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +378 -23
- package/codex-lens/src/codexlens/cli/embedding_manager.py +660 -56
- package/codex-lens/src/codexlens/cli/model_manager.py +31 -18
- package/codex-lens/src/codexlens/cli/output.py +12 -1
- package/codex-lens/src/codexlens/config.py +93 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/chain_search.py +6 -2
- package/codex-lens/src/codexlens/search/hybrid_search.py +44 -21
- package/codex-lens/src/codexlens/search/ranking.py +1 -1
- package/codex-lens/src/codexlens/semantic/__init__.py +42 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/base.py +61 -0
- package/codex-lens/src/codexlens/semantic/chunker.py +43 -20
- package/codex-lens/src/codexlens/semantic/embedder.py +60 -13
- package/codex-lens/src/codexlens/semantic/factory.py +98 -0
- package/codex-lens/src/codexlens/semantic/gpu_support.py +225 -3
- package/codex-lens/src/codexlens/semantic/litellm_embedder.py +144 -0
- package/codex-lens/src/codexlens/semantic/rotational_embedder.py +434 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +33 -8
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/path_mapper.py +27 -1
- package/package.json +15 -5
- package/.codex/prompts.zip +0 -0
- package/ccw/package.json +0 -65
|
@@ -33,9 +33,13 @@ async function loadCliHistory(options = {}) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// Load native session content for a specific execution
|
|
36
|
-
async function loadNativeSessionContent(executionId) {
|
|
36
|
+
async function loadNativeSessionContent(executionId, sourceDir) {
|
|
37
37
|
try {
|
|
38
|
-
|
|
38
|
+
// If sourceDir provided, use it to build the correct path
|
|
39
|
+
const basePath = sourceDir && sourceDir !== '.'
|
|
40
|
+
? projectPath + '/' + sourceDir
|
|
41
|
+
: projectPath;
|
|
42
|
+
const url = `/api/cli/native-session?path=${encodeURIComponent(basePath)}&id=${encodeURIComponent(executionId)}`;
|
|
39
43
|
const response = await fetch(url);
|
|
40
44
|
if (!response.ok) return null;
|
|
41
45
|
return await response.json();
|
|
@@ -133,9 +137,12 @@ function renderCliHistory() {
|
|
|
133
137
|
</span>`
|
|
134
138
|
: '';
|
|
135
139
|
|
|
140
|
+
// Escape sourceDir for use in onclick
|
|
141
|
+
const sourceDirEscaped = exec.sourceDir ? exec.sourceDir.replace(/'/g, "\\'") : '';
|
|
142
|
+
|
|
136
143
|
return `
|
|
137
144
|
<div class="cli-history-item ${hasNative ? 'has-native' : ''}">
|
|
138
|
-
<div class="cli-history-item-content" onclick="showExecutionDetail('${exec.id}')">
|
|
145
|
+
<div class="cli-history-item-content" onclick="showExecutionDetail('${exec.id}', '${sourceDirEscaped}')">
|
|
139
146
|
<div class="cli-history-item-header">
|
|
140
147
|
<span class="cli-tool-tag cli-tool-${exec.tool}">${exec.tool.toUpperCase()}</span>
|
|
141
148
|
<span class="cli-mode-tag">${exec.mode || 'analysis'}</span>
|
|
@@ -154,14 +161,14 @@ function renderCliHistory() {
|
|
|
154
161
|
</div>
|
|
155
162
|
<div class="cli-history-actions">
|
|
156
163
|
${hasNative ? `
|
|
157
|
-
<button class="btn-icon" onclick="event.stopPropagation(); showNativeSessionDetail('${exec.id}')" title="View Native Session">
|
|
164
|
+
<button class="btn-icon" onclick="event.stopPropagation(); showNativeSessionDetail('${exec.id}', '${sourceDirEscaped}')" title="View Native Session">
|
|
158
165
|
<i data-lucide="file-json" class="w-3.5 h-3.5"></i>
|
|
159
166
|
</button>
|
|
160
167
|
` : ''}
|
|
161
|
-
<button class="btn-icon" onclick="event.stopPropagation(); showExecutionDetail('${exec.id}')" title="View Details">
|
|
168
|
+
<button class="btn-icon" onclick="event.stopPropagation(); showExecutionDetail('${exec.id}', '${sourceDirEscaped}')" title="View Details">
|
|
162
169
|
<i data-lucide="eye" class="w-3.5 h-3.5"></i>
|
|
163
170
|
</button>
|
|
164
|
-
<button class="btn-icon btn-danger" onclick="event.stopPropagation(); confirmDeleteExecution('${exec.id}')" title="Delete">
|
|
171
|
+
<button class="btn-icon btn-danger" onclick="event.stopPropagation(); confirmDeleteExecution('${exec.id}', '${sourceDirEscaped}')" title="Delete">
|
|
165
172
|
<i data-lucide="trash-2" class="w-3.5 h-3.5"></i>
|
|
166
173
|
</button>
|
|
167
174
|
</div>
|
|
@@ -650,9 +657,9 @@ async function copyConcatenatedPrompt(executionId) {
|
|
|
650
657
|
/**
|
|
651
658
|
* Show native session detail modal with full conversation content
|
|
652
659
|
*/
|
|
653
|
-
async function showNativeSessionDetail(executionId) {
|
|
660
|
+
async function showNativeSessionDetail(executionId, sourceDir) {
|
|
654
661
|
// Load native session content
|
|
655
|
-
const nativeSession = await loadNativeSessionContent(executionId);
|
|
662
|
+
const nativeSession = await loadNativeSessionContent(executionId, sourceDir);
|
|
656
663
|
|
|
657
664
|
if (!nativeSession) {
|
|
658
665
|
showRefreshToast('Native session not found', 'error');
|
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
let cliToolStatus = { gemini: {}, qwen: {}, codex: {}, claude: {} };
|
|
6
6
|
let codexLensStatus = { ready: false };
|
|
7
7
|
let semanticStatus = { available: false };
|
|
8
|
+
let ccwInstallStatus = { installed: true, workflowsInstalled: true, missingFiles: [], installPath: '' };
|
|
8
9
|
let defaultCliTool = 'gemini';
|
|
9
10
|
let promptConcatFormat = localStorage.getItem('ccw-prompt-format') || 'plain'; // plain, yaml, json
|
|
11
|
+
let cliToolsConfig = {}; // CLI tools enable/disable config
|
|
12
|
+
let apiEndpoints = []; // API endpoints from LiteLLM config
|
|
10
13
|
|
|
11
14
|
// Smart Context settings
|
|
12
15
|
let smartContextEnabled = localStorage.getItem('ccw-smart-context') === 'true';
|
|
@@ -38,10 +41,18 @@ async function loadAllStatuses() {
|
|
|
38
41
|
cliToolStatus = data.cli || { gemini: {}, qwen: {}, codex: {}, claude: {} };
|
|
39
42
|
codexLensStatus = data.codexLens || { ready: false };
|
|
40
43
|
semanticStatus = data.semantic || { available: false };
|
|
44
|
+
ccwInstallStatus = data.ccwInstall || { installed: true, workflowsInstalled: true, missingFiles: [], installPath: '' };
|
|
45
|
+
|
|
46
|
+
// Load CLI tools config and API endpoints
|
|
47
|
+
await Promise.all([
|
|
48
|
+
loadCliToolsConfig(),
|
|
49
|
+
loadApiEndpoints()
|
|
50
|
+
]);
|
|
41
51
|
|
|
42
52
|
// Update badges
|
|
43
53
|
updateCliBadge();
|
|
44
54
|
updateCodexLensBadge();
|
|
55
|
+
updateCcwInstallBadge();
|
|
45
56
|
|
|
46
57
|
return data;
|
|
47
58
|
} catch (err) {
|
|
@@ -118,6 +129,54 @@ async function loadCodexLensStatus() {
|
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Load CodexLens dashboard data using aggregated endpoint (single API call)
|
|
134
|
+
* This is optimized for the CodexLens Manager page initialization
|
|
135
|
+
* @returns {Promise<object|null>} Dashboard init data or null on error
|
|
136
|
+
*/
|
|
137
|
+
async function loadCodexLensDashboardInit() {
|
|
138
|
+
try {
|
|
139
|
+
const response = await fetch('/api/codexlens/dashboard-init');
|
|
140
|
+
if (!response.ok) throw new Error('Failed to load CodexLens dashboard init');
|
|
141
|
+
const data = await response.json();
|
|
142
|
+
|
|
143
|
+
// Update status variables from aggregated response
|
|
144
|
+
codexLensStatus = data.status || { ready: false };
|
|
145
|
+
semanticStatus = data.semantic || { available: false };
|
|
146
|
+
|
|
147
|
+
// Expose to window for other modules
|
|
148
|
+
if (!window.cliToolsStatus) {
|
|
149
|
+
window.cliToolsStatus = {};
|
|
150
|
+
}
|
|
151
|
+
window.cliToolsStatus.codexlens = {
|
|
152
|
+
installed: data.installed || false,
|
|
153
|
+
version: data.status?.version || null,
|
|
154
|
+
installedModels: [],
|
|
155
|
+
config: data.config || {},
|
|
156
|
+
semantic: data.semantic || {}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Store config globally for easy access
|
|
160
|
+
window.codexLensConfig = data.config || {};
|
|
161
|
+
window.codexLensStatusData = data.statusData || {};
|
|
162
|
+
|
|
163
|
+
// Update badges
|
|
164
|
+
updateCodexLensBadge();
|
|
165
|
+
|
|
166
|
+
console.log('[CLI Status] CodexLens dashboard init loaded:', {
|
|
167
|
+
installed: data.installed,
|
|
168
|
+
version: data.status?.version,
|
|
169
|
+
semanticAvailable: data.semantic?.available
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
return data;
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error('Failed to load CodexLens dashboard init:', err);
|
|
175
|
+
// Fallback to individual calls
|
|
176
|
+
return await loadCodexLensStatus();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
121
180
|
/**
|
|
122
181
|
* Legacy: Load semantic status individually
|
|
123
182
|
*/
|
|
@@ -165,6 +224,67 @@ async function loadInstalledModels() {
|
|
|
165
224
|
}
|
|
166
225
|
}
|
|
167
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Load CLI tools config from .claude/cli-tools.json (project or global fallback)
|
|
229
|
+
*/
|
|
230
|
+
async function loadCliToolsConfig() {
|
|
231
|
+
try {
|
|
232
|
+
const response = await fetch('/api/cli/tools-config');
|
|
233
|
+
if (!response.ok) return null;
|
|
234
|
+
const data = await response.json();
|
|
235
|
+
// Store full config and extract tools for backward compatibility
|
|
236
|
+
cliToolsConfig = data.tools || {};
|
|
237
|
+
window.claudeCliToolsConfig = data; // Full config available globally
|
|
238
|
+
|
|
239
|
+
// Load default tool from config
|
|
240
|
+
if (data.defaultTool) {
|
|
241
|
+
defaultCliTool = data.defaultTool;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log('[CLI Config] Loaded from:', data._configInfo?.source || 'unknown', '| Default:', data.defaultTool);
|
|
245
|
+
return data;
|
|
246
|
+
} catch (err) {
|
|
247
|
+
console.error('Failed to load CLI tools config:', err);
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Update CLI tool enabled status
|
|
254
|
+
*/
|
|
255
|
+
async function updateCliToolEnabled(tool, enabled) {
|
|
256
|
+
try {
|
|
257
|
+
const response = await fetch('/api/cli/tools-config/' + tool, {
|
|
258
|
+
method: 'PUT',
|
|
259
|
+
headers: { 'Content-Type': 'application/json' },
|
|
260
|
+
body: JSON.stringify({ enabled: enabled })
|
|
261
|
+
});
|
|
262
|
+
if (!response.ok) throw new Error('Failed to update');
|
|
263
|
+
showRefreshToast(tool + (enabled ? ' enabled' : ' disabled'), 'success');
|
|
264
|
+
return await response.json();
|
|
265
|
+
} catch (err) {
|
|
266
|
+
console.error('Failed to update CLI tool:', err);
|
|
267
|
+
showRefreshToast('Failed to update ' + tool, 'error');
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Load API endpoints from LiteLLM config
|
|
274
|
+
*/
|
|
275
|
+
async function loadApiEndpoints() {
|
|
276
|
+
try {
|
|
277
|
+
const response = await fetch('/api/litellm-api/endpoints');
|
|
278
|
+
if (!response.ok) return [];
|
|
279
|
+
const data = await response.json();
|
|
280
|
+
apiEndpoints = data.endpoints || [];
|
|
281
|
+
return apiEndpoints;
|
|
282
|
+
} catch (err) {
|
|
283
|
+
console.error('Failed to load API endpoints:', err);
|
|
284
|
+
return [];
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
168
288
|
// ========== Badge Update ==========
|
|
169
289
|
function updateCliBadge() {
|
|
170
290
|
const badge = document.getElementById('badgeCliTools');
|
|
@@ -187,6 +307,25 @@ function updateCodexLensBadge() {
|
|
|
187
307
|
}
|
|
188
308
|
}
|
|
189
309
|
|
|
310
|
+
function updateCcwInstallBadge() {
|
|
311
|
+
const badge = document.getElementById('badgeCcwInstall');
|
|
312
|
+
if (badge) {
|
|
313
|
+
if (ccwInstallStatus.installed) {
|
|
314
|
+
badge.textContent = t('status.installed');
|
|
315
|
+
badge.classList.add('text-success');
|
|
316
|
+
badge.classList.remove('text-warning', 'text-destructive');
|
|
317
|
+
} else if (ccwInstallStatus.workflowsInstalled === false) {
|
|
318
|
+
badge.textContent = t('status.incomplete');
|
|
319
|
+
badge.classList.add('text-warning');
|
|
320
|
+
badge.classList.remove('text-success', 'text-destructive');
|
|
321
|
+
} else {
|
|
322
|
+
badge.textContent = t('status.notInstalled');
|
|
323
|
+
badge.classList.add('text-destructive');
|
|
324
|
+
badge.classList.remove('text-success', 'text-warning');
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
190
329
|
// ========== Rendering ==========
|
|
191
330
|
function renderCliStatus() {
|
|
192
331
|
const container = document.getElementById('cli-status-panel');
|
|
@@ -212,25 +351,41 @@ function renderCliStatus() {
|
|
|
212
351
|
const status = cliToolStatus[tool] || {};
|
|
213
352
|
const isAvailable = status.available;
|
|
214
353
|
const isDefault = defaultCliTool === tool;
|
|
354
|
+
const config = cliToolsConfig[tool] || { enabled: true };
|
|
355
|
+
const isEnabled = config.enabled !== false;
|
|
356
|
+
const canSetDefault = isAvailable && isEnabled && !isDefault;
|
|
215
357
|
|
|
216
358
|
return `
|
|
217
|
-
<div class="cli-tool-card tool-${tool} ${isAvailable ? 'available' : 'unavailable'}">
|
|
359
|
+
<div class="cli-tool-card tool-${tool} ${isAvailable ? 'available' : 'unavailable'} ${!isEnabled ? 'disabled' : ''}">
|
|
218
360
|
<div class="cli-tool-header">
|
|
219
|
-
<span class="cli-tool-status ${isAvailable ? 'status-available' : 'status-unavailable'}"></span>
|
|
361
|
+
<span class="cli-tool-status ${isAvailable && isEnabled ? 'status-available' : 'status-unavailable'}"></span>
|
|
220
362
|
<span class="cli-tool-name">${tool.charAt(0).toUpperCase() + tool.slice(1)}</span>
|
|
221
363
|
${isDefault ? '<span class="cli-tool-badge">Default</span>' : ''}
|
|
364
|
+
${!isEnabled && isAvailable ? '<span class="cli-tool-badge-disabled">Disabled</span>' : ''}
|
|
222
365
|
</div>
|
|
223
366
|
<div class="cli-tool-desc text-xs text-muted-foreground mt-1">
|
|
224
367
|
${toolDescriptions[tool]}
|
|
225
368
|
</div>
|
|
226
|
-
<div class="cli-tool-info mt-2">
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
369
|
+
<div class="cli-tool-info mt-2 flex items-center justify-between">
|
|
370
|
+
<div>
|
|
371
|
+
${isAvailable
|
|
372
|
+
? (isEnabled
|
|
373
|
+
? `<span class="text-success flex items-center gap-1"><i data-lucide="check-circle" class="w-3 h-3"></i> Ready</span>`
|
|
374
|
+
: `<span class="text-warning flex items-center gap-1"><i data-lucide="pause-circle" class="w-3 h-3"></i> Disabled</span>`)
|
|
375
|
+
: `<span class="text-muted-foreground flex items-center gap-1"><i data-lucide="circle-dashed" class="w-3 h-3"></i> Not Installed</span>`
|
|
376
|
+
}
|
|
377
|
+
</div>
|
|
231
378
|
</div>
|
|
232
|
-
<div class="cli-tool-actions mt-3">
|
|
233
|
-
${isAvailable
|
|
379
|
+
<div class="cli-tool-actions mt-3 flex gap-2">
|
|
380
|
+
${isAvailable ? (isEnabled
|
|
381
|
+
? `<button class="btn-sm btn-outline-warning flex items-center gap-1" onclick="toggleCliTool('${tool}', false)">
|
|
382
|
+
<i data-lucide="pause" class="w-3 h-3"></i> Disable
|
|
383
|
+
</button>`
|
|
384
|
+
: `<button class="btn-sm btn-outline-success flex items-center gap-1" onclick="toggleCliTool('${tool}', true)">
|
|
385
|
+
<i data-lucide="play" class="w-3 h-3"></i> Enable
|
|
386
|
+
</button>`
|
|
387
|
+
) : ''}
|
|
388
|
+
${canSetDefault
|
|
234
389
|
? `<button class="btn-sm btn-outline flex items-center gap-1" onclick="setDefaultCliTool('${tool}')">
|
|
235
390
|
<i data-lucide="star" class="w-3 h-3"></i> Set Default
|
|
236
391
|
</button>`
|
|
@@ -310,11 +465,75 @@ function renderCliStatus() {
|
|
|
310
465
|
</div>
|
|
311
466
|
` : '';
|
|
312
467
|
|
|
468
|
+
// CCW Installation Status card (show warning if not fully installed)
|
|
469
|
+
const ccwInstallHtml = !ccwInstallStatus.installed ? `
|
|
470
|
+
<div class="cli-tool-card tool-ccw-install unavailable" style="border: 1px solid var(--warning); background: rgba(var(--warning-rgb), 0.05);">
|
|
471
|
+
<div class="cli-tool-header">
|
|
472
|
+
<span class="cli-tool-status status-unavailable" style="background: var(--warning);"></span>
|
|
473
|
+
<span class="cli-tool-name">${t('status.ccwInstall')}</span>
|
|
474
|
+
<span class="badge px-1.5 py-0.5 text-xs rounded bg-warning/20 text-warning">${t('status.required')}</span>
|
|
475
|
+
</div>
|
|
476
|
+
<div class="cli-tool-desc text-xs text-muted-foreground mt-1">
|
|
477
|
+
${t('status.ccwInstallDesc')}
|
|
478
|
+
</div>
|
|
479
|
+
<div class="cli-tool-info mt-2">
|
|
480
|
+
<span class="text-warning flex items-center gap-1">
|
|
481
|
+
<i data-lucide="alert-triangle" class="w-3 h-3"></i>
|
|
482
|
+
${ccwInstallStatus.missingFiles.length} ${t('status.filesMissing')}
|
|
483
|
+
</span>
|
|
484
|
+
</div>
|
|
485
|
+
<div class="cli-tool-actions flex flex-col gap-2 mt-3">
|
|
486
|
+
<div class="text-xs text-muted-foreground">
|
|
487
|
+
<p class="mb-1">${t('status.missingFiles')}:</p>
|
|
488
|
+
<ul class="list-disc list-inside text-xs opacity-70">
|
|
489
|
+
${ccwInstallStatus.missingFiles.slice(0, 3).map(f => `<li>${f}</li>`).join('')}
|
|
490
|
+
${ccwInstallStatus.missingFiles.length > 3 ? `<li>+${ccwInstallStatus.missingFiles.length - 3} more...</li>` : ''}
|
|
491
|
+
</ul>
|
|
492
|
+
</div>
|
|
493
|
+
<div class="bg-muted/50 rounded p-2 mt-2">
|
|
494
|
+
<p class="text-xs font-medium mb-1">${t('status.runToFix')}:</p>
|
|
495
|
+
<code class="text-xs bg-background px-2 py-1 rounded block">ccw install</code>
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
</div>
|
|
499
|
+
` : '';
|
|
500
|
+
|
|
501
|
+
// API Endpoints section
|
|
502
|
+
const apiEndpointsHtml = apiEndpoints.length > 0 ? `
|
|
503
|
+
<div class="cli-api-endpoints-section" style="margin-top: 1.5rem;">
|
|
504
|
+
<div class="cli-section-header" style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem;">
|
|
505
|
+
<h4 style="display: flex; align-items: center; gap: 0.5rem; font-weight: 600; margin: 0;">
|
|
506
|
+
<i data-lucide="link" class="w-4 h-4"></i> API Endpoints
|
|
507
|
+
</h4>
|
|
508
|
+
<span class="badge" style="padding: 0.125rem 0.5rem; font-size: 0.75rem; border-radius: 0.25rem; background: var(--muted); color: var(--muted-foreground);">${apiEndpoints.length}</span>
|
|
509
|
+
</div>
|
|
510
|
+
<div class="cli-endpoints-list" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 0.75rem;">
|
|
511
|
+
${apiEndpoints.map(ep => `
|
|
512
|
+
<div class="cli-endpoint-card ${ep.enabled ? 'available' : 'unavailable'}" style="padding: 0.75rem; border: 1px solid var(--border); border-radius: 0.5rem; background: var(--card);">
|
|
513
|
+
<div class="cli-endpoint-header" style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;">
|
|
514
|
+
<span class="cli-tool-status ${ep.enabled ? 'status-available' : 'status-unavailable'}" style="width: 8px; height: 8px; border-radius: 50%; background: ${ep.enabled ? 'var(--success)' : 'var(--muted-foreground)'}; flex-shrink: 0;"></span>
|
|
515
|
+
<span class="cli-endpoint-id" style="font-weight: 500; font-size: 0.875rem;">${ep.id}</span>
|
|
516
|
+
</div>
|
|
517
|
+
<div class="cli-endpoint-info" style="margin-top: 0.25rem;">
|
|
518
|
+
<span class="text-xs text-muted-foreground" style="font-size: 0.75rem; color: var(--muted-foreground);">${ep.model}</span>
|
|
519
|
+
</div>
|
|
520
|
+
</div>
|
|
521
|
+
`).join('')}
|
|
522
|
+
</div>
|
|
523
|
+
</div>
|
|
524
|
+
` : '';
|
|
525
|
+
|
|
526
|
+
// Config source info
|
|
527
|
+
const configInfo = window.claudeCliToolsConfig?._configInfo || {};
|
|
528
|
+
const configSourceLabel = configInfo.source === 'project' ? 'Project' : configInfo.source === 'global' ? 'Global' : 'Default';
|
|
529
|
+
const configSourceClass = configInfo.source === 'project' ? 'text-success' : configInfo.source === 'global' ? 'text-primary' : 'text-muted-foreground';
|
|
530
|
+
|
|
313
531
|
// CLI Settings section
|
|
314
532
|
const settingsHtml = `
|
|
315
533
|
<div class="cli-settings-section">
|
|
316
534
|
<div class="cli-settings-header">
|
|
317
535
|
<h4><i data-lucide="settings" class="w-3.5 h-3.5"></i> Settings</h4>
|
|
536
|
+
<span class="badge text-xs ${configSourceClass}" title="${configInfo.activePath || ''}">${configSourceLabel}</span>
|
|
318
537
|
</div>
|
|
319
538
|
<div class="cli-settings-grid">
|
|
320
539
|
<div class="cli-setting-item">
|
|
@@ -381,6 +600,20 @@ function renderCliStatus() {
|
|
|
381
600
|
</div>
|
|
382
601
|
<p class="cli-setting-desc">Maximum files to include in smart context</p>
|
|
383
602
|
</div>
|
|
603
|
+
<div class="cli-setting-item">
|
|
604
|
+
<label class="cli-setting-label">
|
|
605
|
+
<i data-lucide="hard-drive" class="w-3 h-3"></i>
|
|
606
|
+
Cache Injection
|
|
607
|
+
</label>
|
|
608
|
+
<div class="cli-setting-control">
|
|
609
|
+
<select class="cli-setting-select" onchange="setCacheInjectionMode(this.value)">
|
|
610
|
+
<option value="auto" ${getCacheInjectionMode() === 'auto' ? 'selected' : ''}>Auto</option>
|
|
611
|
+
<option value="manual" ${getCacheInjectionMode() === 'manual' ? 'selected' : ''}>Manual</option>
|
|
612
|
+
<option value="disabled" ${getCacheInjectionMode() === 'disabled' ? 'selected' : ''}>Disabled</option>
|
|
613
|
+
</select>
|
|
614
|
+
</div>
|
|
615
|
+
<p class="cli-setting-desc">Cache prefix/suffix injection mode for prompts</p>
|
|
616
|
+
</div>
|
|
384
617
|
</div>
|
|
385
618
|
</div>
|
|
386
619
|
`;
|
|
@@ -392,11 +625,13 @@ function renderCliStatus() {
|
|
|
392
625
|
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
|
|
393
626
|
</button>
|
|
394
627
|
</div>
|
|
628
|
+
${ccwInstallHtml}
|
|
395
629
|
<div class="cli-tools-grid">
|
|
396
630
|
${toolsHtml}
|
|
397
631
|
${codexLensHtml}
|
|
398
632
|
${semanticHtml}
|
|
399
633
|
</div>
|
|
634
|
+
${apiEndpointsHtml}
|
|
400
635
|
${settingsHtml}
|
|
401
636
|
`;
|
|
402
637
|
|
|
@@ -408,7 +643,30 @@ function renderCliStatus() {
|
|
|
408
643
|
|
|
409
644
|
// ========== Actions ==========
|
|
410
645
|
function setDefaultCliTool(tool) {
|
|
646
|
+
// Validate: tool must be available and enabled
|
|
647
|
+
const status = cliToolStatus[tool] || {};
|
|
648
|
+
const config = cliToolsConfig[tool] || { enabled: true };
|
|
649
|
+
|
|
650
|
+
if (!status.available) {
|
|
651
|
+
showRefreshToast(`Cannot set ${tool} as default: not installed`, 'error');
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
if (config.enabled === false) {
|
|
656
|
+
showRefreshToast(`Cannot set ${tool} as default: tool is disabled`, 'error');
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
|
|
411
660
|
defaultCliTool = tool;
|
|
661
|
+
// Save to config
|
|
662
|
+
if (window.claudeCliToolsConfig) {
|
|
663
|
+
window.claudeCliToolsConfig.defaultTool = tool;
|
|
664
|
+
fetch('/api/cli/tools-config', {
|
|
665
|
+
method: 'PUT',
|
|
666
|
+
headers: { 'Content-Type': 'application/json' },
|
|
667
|
+
body: JSON.stringify({ defaultTool: tool })
|
|
668
|
+
}).catch(err => console.error('Failed to save default tool:', err));
|
|
669
|
+
}
|
|
412
670
|
renderCliStatus();
|
|
413
671
|
showRefreshToast(`Default CLI tool set to ${tool}`, 'success');
|
|
414
672
|
}
|
|
@@ -449,11 +707,67 @@ function setRecursiveQueryEnabled(enabled) {
|
|
|
449
707
|
showRefreshToast(`Recursive Query ${enabled ? 'enabled' : 'disabled'}`, 'success');
|
|
450
708
|
}
|
|
451
709
|
|
|
710
|
+
function getCacheInjectionMode() {
|
|
711
|
+
if (window.claudeCliToolsConfig && window.claudeCliToolsConfig.settings) {
|
|
712
|
+
return window.claudeCliToolsConfig.settings.cache?.injectionMode || 'auto';
|
|
713
|
+
}
|
|
714
|
+
return localStorage.getItem('ccw-cache-injection-mode') || 'auto';
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
async function setCacheInjectionMode(mode) {
|
|
718
|
+
try {
|
|
719
|
+
const response = await fetch('/api/cli/tools-config/cache', {
|
|
720
|
+
method: 'PUT',
|
|
721
|
+
headers: { 'Content-Type': 'application/json' },
|
|
722
|
+
body: JSON.stringify({ injectionMode: mode })
|
|
723
|
+
});
|
|
724
|
+
if (response.ok) {
|
|
725
|
+
localStorage.setItem('ccw-cache-injection-mode', mode);
|
|
726
|
+
if (window.claudeCliToolsConfig) {
|
|
727
|
+
window.claudeCliToolsConfig.settings.cache.injectionMode = mode;
|
|
728
|
+
}
|
|
729
|
+
showRefreshToast(`Cache injection mode set to ${mode}`, 'success');
|
|
730
|
+
} else {
|
|
731
|
+
showRefreshToast('Failed to update cache settings', 'error');
|
|
732
|
+
}
|
|
733
|
+
} catch (err) {
|
|
734
|
+
console.error('Failed to update cache settings:', err);
|
|
735
|
+
showRefreshToast('Failed to update cache settings', 'error');
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
452
739
|
async function refreshAllCliStatus() {
|
|
453
740
|
await loadAllStatuses();
|
|
454
741
|
renderCliStatus();
|
|
455
742
|
}
|
|
456
743
|
|
|
744
|
+
async function toggleCliTool(tool, enabled) {
|
|
745
|
+
// If disabling the current default tool, switch to another available+enabled tool
|
|
746
|
+
if (!enabled && defaultCliTool === tool) {
|
|
747
|
+
const tools = ['gemini', 'qwen', 'codex', 'claude'];
|
|
748
|
+
const newDefault = tools.find(t => {
|
|
749
|
+
if (t === tool) return false;
|
|
750
|
+
const status = cliToolStatus[t] || {};
|
|
751
|
+
const config = cliToolsConfig[t] || { enabled: true };
|
|
752
|
+
return status.available && config.enabled !== false;
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
if (newDefault) {
|
|
756
|
+
defaultCliTool = newDefault;
|
|
757
|
+
if (window.claudeCliToolsConfig) {
|
|
758
|
+
window.claudeCliToolsConfig.defaultTool = newDefault;
|
|
759
|
+
}
|
|
760
|
+
showRefreshToast(`Default tool switched to ${newDefault}`, 'info');
|
|
761
|
+
} else {
|
|
762
|
+
showRefreshToast(`Warning: No other enabled tool available for default`, 'warning');
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
await updateCliToolEnabled(tool, enabled);
|
|
767
|
+
await loadAllStatuses();
|
|
768
|
+
renderCliStatus();
|
|
769
|
+
}
|
|
770
|
+
|
|
457
771
|
function installCodexLens() {
|
|
458
772
|
openCodexLensInstallWizard();
|
|
459
773
|
}
|