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.
Files changed (208) hide show
  1. package/.claude/CLAUDE.md +16 -1
  2. package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +11 -4
  3. package/.claude/workflows/cli-templates/protocols/write-protocol.md +10 -75
  4. package/.claude/workflows/cli-tools-usage.md +14 -24
  5. package/.codex/AGENTS.md +51 -1
  6. package/.codex/prompts/compact.md +378 -0
  7. package/.gemini/GEMINI.md +57 -20
  8. package/ccw/dist/cli.d.ts.map +1 -1
  9. package/ccw/dist/cli.js +21 -8
  10. package/ccw/dist/cli.js.map +1 -1
  11. package/ccw/dist/commands/cli.d.ts +2 -0
  12. package/ccw/dist/commands/cli.d.ts.map +1 -1
  13. package/ccw/dist/commands/cli.js +129 -8
  14. package/ccw/dist/commands/cli.js.map +1 -1
  15. package/ccw/dist/commands/hook.d.ts.map +1 -1
  16. package/ccw/dist/commands/hook.js +3 -2
  17. package/ccw/dist/commands/hook.js.map +1 -1
  18. package/ccw/dist/config/litellm-api-config-manager.d.ts +180 -0
  19. package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -0
  20. package/ccw/dist/config/litellm-api-config-manager.js +770 -0
  21. package/ccw/dist/config/litellm-api-config-manager.js.map +1 -0
  22. package/ccw/dist/config/provider-models.d.ts +73 -0
  23. package/ccw/dist/config/provider-models.d.ts.map +1 -0
  24. package/ccw/dist/config/provider-models.js +172 -0
  25. package/ccw/dist/config/provider-models.js.map +1 -0
  26. package/ccw/dist/core/cache-manager.d.ts.map +1 -1
  27. package/ccw/dist/core/cache-manager.js +3 -5
  28. package/ccw/dist/core/cache-manager.js.map +1 -1
  29. package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
  30. package/ccw/dist/core/dashboard-generator.js +3 -1
  31. package/ccw/dist/core/dashboard-generator.js.map +1 -1
  32. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  33. package/ccw/dist/core/routes/cli-routes.js +169 -0
  34. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  35. package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
  36. package/ccw/dist/core/routes/codexlens-routes.js +234 -18
  37. package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
  38. package/ccw/dist/core/routes/hooks-routes.d.ts.map +1 -1
  39. package/ccw/dist/core/routes/hooks-routes.js +30 -32
  40. package/ccw/dist/core/routes/hooks-routes.js.map +1 -1
  41. package/ccw/dist/core/routes/litellm-api-routes.d.ts +21 -0
  42. package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -0
  43. package/ccw/dist/core/routes/litellm-api-routes.js +780 -0
  44. package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -0
  45. package/ccw/dist/core/routes/litellm-routes.d.ts +20 -0
  46. package/ccw/dist/core/routes/litellm-routes.d.ts.map +1 -0
  47. package/ccw/dist/core/routes/litellm-routes.js +85 -0
  48. package/ccw/dist/core/routes/litellm-routes.js.map +1 -0
  49. package/ccw/dist/core/routes/mcp-routes.js +2 -2
  50. package/ccw/dist/core/routes/mcp-routes.js.map +1 -1
  51. package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
  52. package/ccw/dist/core/routes/status-routes.js +39 -0
  53. package/ccw/dist/core/routes/status-routes.js.map +1 -1
  54. package/ccw/dist/core/routes/system-routes.js +1 -1
  55. package/ccw/dist/core/routes/system-routes.js.map +1 -1
  56. package/ccw/dist/core/server.d.ts.map +1 -1
  57. package/ccw/dist/core/server.js +15 -1
  58. package/ccw/dist/core/server.js.map +1 -1
  59. package/ccw/dist/mcp-server/index.js +1 -1
  60. package/ccw/dist/mcp-server/index.js.map +1 -1
  61. package/ccw/dist/tools/claude-cli-tools.d.ts +82 -0
  62. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -0
  63. package/ccw/dist/tools/claude-cli-tools.js +216 -0
  64. package/ccw/dist/tools/claude-cli-tools.js.map +1 -0
  65. package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
  66. package/ccw/dist/tools/cli-executor.js +76 -14
  67. package/ccw/dist/tools/cli-executor.js.map +1 -1
  68. package/ccw/dist/tools/codex-lens.d.ts +9 -2
  69. package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
  70. package/ccw/dist/tools/codex-lens.js +114 -9
  71. package/ccw/dist/tools/codex-lens.js.map +1 -1
  72. package/ccw/dist/tools/context-cache-store.d.ts +136 -0
  73. package/ccw/dist/tools/context-cache-store.d.ts.map +1 -0
  74. package/ccw/dist/tools/context-cache-store.js +256 -0
  75. package/ccw/dist/tools/context-cache-store.js.map +1 -0
  76. package/ccw/dist/tools/context-cache.d.ts +56 -0
  77. package/ccw/dist/tools/context-cache.d.ts.map +1 -0
  78. package/ccw/dist/tools/context-cache.js +294 -0
  79. package/ccw/dist/tools/context-cache.js.map +1 -0
  80. package/ccw/dist/tools/core-memory.d.ts.map +1 -1
  81. package/ccw/dist/tools/core-memory.js +33 -19
  82. package/ccw/dist/tools/core-memory.js.map +1 -1
  83. package/ccw/dist/tools/index.d.ts.map +1 -1
  84. package/ccw/dist/tools/index.js +2 -0
  85. package/ccw/dist/tools/index.js.map +1 -1
  86. package/ccw/dist/tools/litellm-client.d.ts +85 -0
  87. package/ccw/dist/tools/litellm-client.d.ts.map +1 -0
  88. package/ccw/dist/tools/litellm-client.js +188 -0
  89. package/ccw/dist/tools/litellm-client.js.map +1 -0
  90. package/ccw/dist/tools/litellm-executor.d.ts +34 -0
  91. package/ccw/dist/tools/litellm-executor.d.ts.map +1 -0
  92. package/ccw/dist/tools/litellm-executor.js +192 -0
  93. package/ccw/dist/tools/litellm-executor.js.map +1 -0
  94. package/ccw/dist/tools/pattern-parser.d.ts +55 -0
  95. package/ccw/dist/tools/pattern-parser.d.ts.map +1 -0
  96. package/ccw/dist/tools/pattern-parser.js +237 -0
  97. package/ccw/dist/tools/pattern-parser.js.map +1 -0
  98. package/ccw/dist/tools/smart-search.d.ts +1 -0
  99. package/ccw/dist/tools/smart-search.d.ts.map +1 -1
  100. package/ccw/dist/tools/smart-search.js +117 -41
  101. package/ccw/dist/tools/smart-search.js.map +1 -1
  102. package/ccw/dist/types/litellm-api-config.d.ts +294 -0
  103. package/ccw/dist/types/litellm-api-config.d.ts.map +1 -0
  104. package/ccw/dist/types/litellm-api-config.js +8 -0
  105. package/ccw/dist/types/litellm-api-config.js.map +1 -0
  106. package/ccw/src/cli.ts +258 -244
  107. package/ccw/src/commands/cli.ts +153 -9
  108. package/ccw/src/commands/hook.ts +3 -2
  109. package/ccw/src/config/.litellm-api-config-manager.ts.2025-12-23T11-57-43-727Z.bak +441 -0
  110. package/ccw/src/config/litellm-api-config-manager.ts +1012 -0
  111. package/ccw/src/config/provider-models.ts +222 -0
  112. package/ccw/src/core/cache-manager.ts +292 -294
  113. package/ccw/src/core/dashboard-generator.ts +3 -1
  114. package/ccw/src/core/routes/cli-routes.ts +192 -0
  115. package/ccw/src/core/routes/codexlens-routes.ts +241 -19
  116. package/ccw/src/core/routes/hooks-routes.ts +399 -405
  117. package/ccw/src/core/routes/litellm-api-routes.ts +930 -0
  118. package/ccw/src/core/routes/litellm-routes.ts +107 -0
  119. package/ccw/src/core/routes/mcp-routes.ts +1271 -1271
  120. package/ccw/src/core/routes/status-routes.ts +51 -0
  121. package/ccw/src/core/routes/system-routes.ts +1 -1
  122. package/ccw/src/core/server.ts +15 -1
  123. package/ccw/src/mcp-server/index.ts +1 -1
  124. package/ccw/src/templates/dashboard-css/12-cli-legacy.css +44 -0
  125. package/ccw/src/templates/dashboard-css/31-api-settings.css +2265 -0
  126. package/ccw/src/templates/dashboard-js/components/cli-history.js +15 -8
  127. package/ccw/src/templates/dashboard-js/components/cli-status.js +323 -9
  128. package/ccw/src/templates/dashboard-js/components/navigation.js +329 -313
  129. package/ccw/src/templates/dashboard-js/i18n.js +583 -1
  130. package/ccw/src/templates/dashboard-js/views/api-settings.js +3362 -0
  131. package/ccw/src/templates/dashboard-js/views/cli-manager.js +199 -24
  132. package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +1265 -27
  133. package/ccw/src/templates/dashboard.html +840 -831
  134. package/ccw/src/tools/claude-cli-tools.ts +300 -0
  135. package/ccw/src/tools/cli-executor.ts +83 -14
  136. package/ccw/src/tools/codex-lens.ts +146 -9
  137. package/ccw/src/tools/context-cache-store.ts +368 -0
  138. package/ccw/src/tools/context-cache.ts +393 -0
  139. package/ccw/src/tools/core-memory.ts +33 -19
  140. package/ccw/src/tools/index.ts +2 -0
  141. package/ccw/src/tools/litellm-client.ts +246 -0
  142. package/ccw/src/tools/litellm-executor.ts +241 -0
  143. package/ccw/src/tools/pattern-parser.ts +329 -0
  144. package/ccw/src/tools/smart-search.ts +142 -41
  145. package/ccw/src/types/litellm-api-config.ts +402 -0
  146. package/ccw-litellm/README.md +180 -0
  147. package/ccw-litellm/pyproject.toml +35 -0
  148. package/ccw-litellm/src/ccw_litellm/__init__.py +47 -0
  149. package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-313.pyc +0 -0
  150. package/ccw-litellm/src/ccw_litellm/__pycache__/cli.cpython-313.pyc +0 -0
  151. package/ccw-litellm/src/ccw_litellm/cli.py +108 -0
  152. package/ccw-litellm/src/ccw_litellm/clients/__init__.py +12 -0
  153. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-313.pyc +0 -0
  154. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
  155. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-313.pyc +0 -0
  156. package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +251 -0
  157. package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +165 -0
  158. package/ccw-litellm/src/ccw_litellm/config/__init__.py +22 -0
  159. package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-313.pyc +0 -0
  160. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-313.pyc +0 -0
  161. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-313.pyc +0 -0
  162. package/ccw-litellm/src/ccw_litellm/config/loader.py +316 -0
  163. package/ccw-litellm/src/ccw_litellm/config/models.py +130 -0
  164. package/ccw-litellm/src/ccw_litellm/interfaces/__init__.py +14 -0
  165. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-313.pyc +0 -0
  166. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-313.pyc +0 -0
  167. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-313.pyc +0 -0
  168. package/ccw-litellm/src/ccw_litellm/interfaces/embedder.py +52 -0
  169. package/ccw-litellm/src/ccw_litellm/interfaces/llm.py +45 -0
  170. package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
  171. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
  172. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
  173. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
  174. package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
  175. package/codex-lens/src/codexlens/cli/commands.py +378 -23
  176. package/codex-lens/src/codexlens/cli/embedding_manager.py +660 -56
  177. package/codex-lens/src/codexlens/cli/model_manager.py +31 -18
  178. package/codex-lens/src/codexlens/cli/output.py +12 -1
  179. package/codex-lens/src/codexlens/config.py +93 -0
  180. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
  181. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
  182. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
  183. package/codex-lens/src/codexlens/search/chain_search.py +6 -2
  184. package/codex-lens/src/codexlens/search/hybrid_search.py +44 -21
  185. package/codex-lens/src/codexlens/search/ranking.py +1 -1
  186. package/codex-lens/src/codexlens/semantic/__init__.py +42 -0
  187. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
  188. package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-313.pyc +0 -0
  189. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
  190. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
  191. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-313.pyc +0 -0
  192. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-313.pyc +0 -0
  193. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
  194. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
  195. package/codex-lens/src/codexlens/semantic/base.py +61 -0
  196. package/codex-lens/src/codexlens/semantic/chunker.py +43 -20
  197. package/codex-lens/src/codexlens/semantic/embedder.py +60 -13
  198. package/codex-lens/src/codexlens/semantic/factory.py +98 -0
  199. package/codex-lens/src/codexlens/semantic/gpu_support.py +225 -3
  200. package/codex-lens/src/codexlens/semantic/litellm_embedder.py +144 -0
  201. package/codex-lens/src/codexlens/semantic/rotational_embedder.py +434 -0
  202. package/codex-lens/src/codexlens/semantic/vector_store.py +33 -8
  203. package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
  204. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
  205. package/codex-lens/src/codexlens/storage/path_mapper.py +27 -1
  206. package/package.json +15 -5
  207. package/.codex/prompts.zip +0 -0
  208. package/ccw/package.json +0 -65
@@ -1,313 +1,329 @@
1
- // Navigation and Routing
2
- // Manages navigation events, active state, content title updates, search, and path selector
3
-
4
- // Path Selector
5
- function initPathSelector() {
6
- const btn = document.getElementById('pathButton');
7
- const menu = document.getElementById('pathMenu');
8
- const recentContainer = document.getElementById('recentPaths');
9
-
10
- // Render recent paths
11
- if (recentPaths && recentPaths.length > 0) {
12
- recentPaths.forEach(path => {
13
- const item = document.createElement('div');
14
- item.className = 'path-item' + (path === projectPath ? ' active' : '');
15
- item.dataset.path = path;
16
-
17
- // Path text
18
- const pathText = document.createElement('span');
19
- pathText.className = 'path-text';
20
- pathText.textContent = path;
21
- pathText.addEventListener('click', () => selectPath(path));
22
- item.appendChild(pathText);
23
-
24
- // Delete button (only for non-current paths)
25
- if (path !== projectPath) {
26
- const deleteBtn = document.createElement('button');
27
- deleteBtn.className = 'path-delete-btn';
28
- deleteBtn.innerHTML = '×';
29
- deleteBtn.title = 'Remove from recent';
30
- deleteBtn.addEventListener('click', async (e) => {
31
- e.stopPropagation();
32
- await removeRecentPathFromList(path);
33
- });
34
- item.appendChild(deleteBtn);
35
- }
36
-
37
- recentContainer.appendChild(item);
38
- });
39
- }
40
-
41
- btn.addEventListener('click', (e) => {
42
- e.stopPropagation();
43
- menu.classList.toggle('hidden');
44
- });
45
-
46
- document.addEventListener('click', () => {
47
- menu.classList.add('hidden');
48
- });
49
-
50
- document.getElementById('browsePath').addEventListener('click', async () => {
51
- await browseForFolder();
52
- });
53
- }
54
-
55
- // Cleanup function for view transitions
56
- function cleanupPreviousView() {
57
- // Cleanup graph explorer
58
- if (currentView === 'graph-explorer' && typeof window.cleanupGraphExplorer === 'function') {
59
- window.cleanupGraphExplorer();
60
- }
61
- // Hide storage card when leaving cli-manager
62
- var storageCard = document.getElementById('storageCard');
63
- if (storageCard) {
64
- storageCard.style.display = 'none';
65
- }
66
- }
67
-
68
- // Navigation
69
- function initNavigation() {
70
- document.querySelectorAll('.nav-item[data-filter]').forEach(item => {
71
- item.addEventListener('click', () => {
72
- cleanupPreviousView();
73
-
74
- setActiveNavItem(item);
75
- currentFilter = item.dataset.filter;
76
- currentLiteType = null;
77
- currentView = 'sessions';
78
- currentSessionDetailKey = null;
79
- updateContentTitle();
80
- showStatsAndSearch();
81
- renderSessions();
82
- });
83
- });
84
-
85
- // Lite Tasks Navigation
86
- document.querySelectorAll('.nav-item[data-lite]').forEach(item => {
87
- item.addEventListener('click', () => {
88
- cleanupPreviousView();
89
-
90
- setActiveNavItem(item);
91
- currentLiteType = item.dataset.lite;
92
- currentFilter = null;
93
- currentView = 'liteTasks';
94
- currentSessionDetailKey = null;
95
- updateContentTitle();
96
- showStatsAndSearch();
97
- renderLiteTasks();
98
- });
99
- });
100
-
101
- // View Navigation (Project Overview, MCP Manager, etc.)
102
- document.querySelectorAll('.nav-item[data-view]').forEach(item => {
103
- item.addEventListener('click', () => {
104
- cleanupPreviousView();
105
-
106
- setActiveNavItem(item);
107
- currentView = item.dataset.view;
108
- currentFilter = null;
109
- currentLiteType = null;
110
- currentSessionDetailKey = null;
111
- updateContentTitle();
112
-
113
- // Route to appropriate view
114
- if (currentView === 'mcp-manager') {
115
- renderMcpManager();
116
- } else if (currentView === 'project-overview') {
117
- renderProjectOverview();
118
- } else if (currentView === 'explorer') {
119
- renderExplorer();
120
- } else if (currentView === 'cli-manager') {
121
- renderCliManager();
122
- } else if (currentView === 'cli-history') {
123
- renderCliHistoryView();
124
- } else if (currentView === 'hook-manager') {
125
- renderHookManager();
126
- } else if (currentView === 'memory') {
127
- renderMemoryView();
128
- } else if (currentView === 'prompt-history') {
129
- renderPromptHistoryView();
130
- } else if (currentView === 'skills-manager') {
131
- renderSkillsManager();
132
- } else if (currentView === 'rules-manager') {
133
- renderRulesManager();
134
- } else if (currentView === 'claude-manager') {
135
- renderClaudeManager();
136
- } else if (currentView === 'graph-explorer') {
137
- renderGraphExplorer();
138
- } else if (currentView === 'help') {
139
- renderHelpView();
140
- } else if (currentView === 'core-memory') {
141
- if (typeof renderCoreMemoryView === 'function') {
142
- renderCoreMemoryView();
143
- } else {
144
- console.error('renderCoreMemoryView not defined - please refresh the page');
145
- }
146
- }
147
- });
148
- });
149
- }
150
-
151
- function setActiveNavItem(item) {
152
- document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
153
- item.classList.add('active');
154
- }
155
-
156
- function updateContentTitle() {
157
- const titleEl = document.getElementById('contentTitle');
158
- if (currentView === 'project-overview') {
159
- titleEl.textContent = t('title.projectOverview');
160
- } else if (currentView === 'mcp-manager') {
161
- titleEl.textContent = t('title.mcpManagement');
162
- } else if (currentView === 'explorer') {
163
- titleEl.textContent = t('title.fileExplorer');
164
- } else if (currentView === 'cli-manager') {
165
- titleEl.textContent = t('title.cliTools');
166
- } else if (currentView === 'cli-history') {
167
- titleEl.textContent = t('title.cliHistory');
168
- } else if (currentView === 'hook-manager') {
169
- titleEl.textContent = t('title.hookManager');
170
- } else if (currentView === 'memory') {
171
- titleEl.textContent = t('title.memoryModule');
172
- } else if (currentView === 'prompt-history') {
173
- titleEl.textContent = t('title.promptHistory');
174
- } else if (currentView === 'skills-manager') {
175
- titleEl.textContent = t('title.skillsManager');
176
- } else if (currentView === 'rules-manager') {
177
- titleEl.textContent = t('title.rulesManager');
178
- } else if (currentView === 'claude-manager') {
179
- titleEl.textContent = t('title.claudeManager');
180
- } else if (currentView === 'graph-explorer') {
181
- titleEl.textContent = t('title.graphExplorer');
182
- } else if (currentView === 'help') {
183
- titleEl.textContent = t('title.helpGuide');
184
- } else if (currentView === 'core-memory') {
185
- titleEl.textContent = t('title.coreMemory');
186
- } else if (currentView === 'liteTasks') {
187
- const names = { 'lite-plan': t('title.litePlanSessions'), 'lite-fix': t('title.liteFixSessions') };
188
- titleEl.textContent = names[currentLiteType] || t('title.liteTasks');
189
- } else if (currentView === 'sessionDetail') {
190
- titleEl.textContent = t('title.sessionDetail');
191
- } else if (currentView === 'liteTaskDetail') {
192
- titleEl.textContent = t('title.liteTaskDetail');
193
- } else {
194
- const names = { 'all': t('title.allSessions'), 'active': t('title.activeSessions'), 'archived': t('title.archivedSessions') };
195
- titleEl.textContent = names[currentFilter] || t('title.sessions');
196
- }
197
- }
198
-
199
- // Search
200
- function initSearch() {
201
- const input = document.getElementById('searchInput');
202
- input.addEventListener('input', (e) => {
203
- const query = e.target.value.toLowerCase();
204
- document.querySelectorAll('.session-card').forEach(card => {
205
- const text = card.textContent.toLowerCase();
206
- card.style.display = text.includes(query) ? '' : 'none';
207
- });
208
- });
209
- }
210
-
211
- // Refresh Workspace
212
- function initRefreshButton() {
213
- const btn = document.getElementById('refreshWorkspace');
214
- if (btn) {
215
- btn.addEventListener('click', refreshWorkspace);
216
- }
217
- }
218
-
219
- async function refreshWorkspace() {
220
- const btn = document.getElementById('refreshWorkspace');
221
-
222
- // Add spinning animation
223
- btn.classList.add('refreshing');
224
- btn.disabled = true;
225
-
226
- try {
227
- if (window.SERVER_MODE) {
228
- // Reload data from server
229
- const data = await loadDashboardData(projectPath);
230
- if (data) {
231
- // Clear and repopulate stores
232
- Object.keys(sessionDataStore).forEach(k => delete sessionDataStore[k]);
233
- Object.keys(liteTaskDataStore).forEach(k => delete liteTaskDataStore[k]);
234
-
235
- // Populate stores
236
- [...(data.activeSessions || []), ...(data.archivedSessions || [])].forEach(s => {
237
- const sessionKey = `session-${s.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-');
238
- sessionDataStore[sessionKey] = s;
239
- });
240
-
241
- [...(data.liteTasks?.litePlan || []), ...(data.liteTasks?.liteFix || [])].forEach(s => {
242
- const sessionKey = `lite-${s.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-');
243
- liteTaskDataStore[sessionKey] = s;
244
- });
245
-
246
- // Update global data
247
- window.workflowData = data;
248
-
249
- // Update sidebar counts
250
- updateSidebarCounts(data);
251
-
252
- // Re-render current view
253
- if (currentView === 'sessions') {
254
- renderSessions();
255
- } else if (currentView === 'liteTasks') {
256
- renderLiteTasks();
257
- } else if (currentView === 'sessionDetail' && currentSessionDetailKey) {
258
- showSessionDetailPage(currentSessionDetailKey);
259
- } else if (currentView === 'liteTaskDetail' && currentSessionDetailKey) {
260
- showLiteTaskDetailPage(currentSessionDetailKey);
261
- } else if (currentView === 'project-overview') {
262
- renderProjectOverview();
263
- }
264
-
265
- showRefreshToast(t('toast.workspaceRefreshed'), 'success');
266
- }
267
- } else {
268
- // Non-server mode: just reload page
269
- window.location.reload();
270
- }
271
- } catch (error) {
272
- console.error('Refresh failed:', error);
273
- showRefreshToast(t('toast.refreshFailed', { error: error.message }), 'error');
274
- } finally {
275
- btn.classList.remove('refreshing');
276
- btn.disabled = false;
277
- }
278
- }
279
-
280
- function updateSidebarCounts(data) {
281
- // Update session counts
282
- const activeCount = document.querySelector('.nav-item[data-filter="active"] .nav-count');
283
- const archivedCount = document.querySelector('.nav-item[data-filter="archived"] .nav-count');
284
- const allCount = document.querySelector('.nav-item[data-filter="all"] .nav-count');
285
-
286
- if (activeCount) activeCount.textContent = data.activeSessions?.length || 0;
287
- if (archivedCount) archivedCount.textContent = data.archivedSessions?.length || 0;
288
- if (allCount) allCount.textContent = (data.activeSessions?.length || 0) + (data.archivedSessions?.length || 0);
289
-
290
- // Update lite task counts
291
- const litePlanCount = document.querySelector('.nav-item[data-lite="lite-plan"] .nav-count');
292
- const liteFixCount = document.querySelector('.nav-item[data-lite="lite-fix"] .nav-count');
293
-
294
- if (litePlanCount) litePlanCount.textContent = data.liteTasks?.litePlan?.length || 0;
295
- if (liteFixCount) liteFixCount.textContent = data.liteTasks?.liteFix?.length || 0;
296
- }
297
-
298
- function showRefreshToast(message, type) {
299
- // Remove existing toast
300
- const existing = document.querySelector('.status-toast');
301
- if (existing) existing.remove();
302
-
303
- const toast = document.createElement('div');
304
- toast.className = `status-toast ${type}`;
305
- toast.textContent = message;
306
- document.body.appendChild(toast);
307
-
308
- // Increase display time to 3.5 seconds for better visibility
309
- setTimeout(() => {
310
- toast.classList.add('fade-out');
311
- setTimeout(() => toast.remove(), 300);
312
- }, 3500);
313
- }
1
+ // Navigation and Routing
2
+ // Manages navigation events, active state, content title updates, search, and path selector
3
+
4
+ // Path Selector
5
+ function initPathSelector() {
6
+ const btn = document.getElementById('pathButton');
7
+ const menu = document.getElementById('pathMenu');
8
+ const recentContainer = document.getElementById('recentPaths');
9
+
10
+ // Render recent paths
11
+ if (recentPaths && recentPaths.length > 0) {
12
+ recentPaths.forEach(path => {
13
+ const item = document.createElement('div');
14
+ item.className = 'path-item' + (path === projectPath ? ' active' : '');
15
+ item.dataset.path = path;
16
+
17
+ // Path text
18
+ const pathText = document.createElement('span');
19
+ pathText.className = 'path-text';
20
+ pathText.textContent = path;
21
+ pathText.addEventListener('click', () => selectPath(path));
22
+ item.appendChild(pathText);
23
+
24
+ // Delete button (only for non-current paths)
25
+ if (path !== projectPath) {
26
+ const deleteBtn = document.createElement('button');
27
+ deleteBtn.className = 'path-delete-btn';
28
+ deleteBtn.innerHTML = '×';
29
+ deleteBtn.title = 'Remove from recent';
30
+ deleteBtn.addEventListener('click', async (e) => {
31
+ e.stopPropagation();
32
+ await removeRecentPathFromList(path);
33
+ });
34
+ item.appendChild(deleteBtn);
35
+ }
36
+
37
+ recentContainer.appendChild(item);
38
+ });
39
+ }
40
+
41
+ btn.addEventListener('click', (e) => {
42
+ e.stopPropagation();
43
+ menu.classList.toggle('hidden');
44
+ });
45
+
46
+ document.addEventListener('click', () => {
47
+ menu.classList.add('hidden');
48
+ });
49
+
50
+ document.getElementById('browsePath').addEventListener('click', async () => {
51
+ await browseForFolder();
52
+ });
53
+ }
54
+
55
+ // Cleanup function for view transitions
56
+ function cleanupPreviousView() {
57
+ // Cleanup graph explorer
58
+ if (currentView === 'graph-explorer' && typeof window.cleanupGraphExplorer === 'function') {
59
+ window.cleanupGraphExplorer();
60
+ }
61
+ // Hide storage card when leaving cli-manager
62
+ var storageCard = document.getElementById('storageCard');
63
+ if (storageCard) {
64
+ storageCard.style.display = 'none';
65
+ }
66
+ }
67
+
68
+ // Navigation
69
+ function initNavigation() {
70
+ document.querySelectorAll('.nav-item[data-filter]').forEach(item => {
71
+ item.addEventListener('click', () => {
72
+ cleanupPreviousView();
73
+
74
+ setActiveNavItem(item);
75
+ currentFilter = item.dataset.filter;
76
+ currentLiteType = null;
77
+ currentView = 'sessions';
78
+ currentSessionDetailKey = null;
79
+ updateContentTitle();
80
+ showStatsAndSearch();
81
+ renderSessions();
82
+ });
83
+ });
84
+
85
+ // Lite Tasks Navigation
86
+ document.querySelectorAll('.nav-item[data-lite]').forEach(item => {
87
+ item.addEventListener('click', () => {
88
+ cleanupPreviousView();
89
+
90
+ setActiveNavItem(item);
91
+ currentLiteType = item.dataset.lite;
92
+ currentFilter = null;
93
+ currentView = 'liteTasks';
94
+ currentSessionDetailKey = null;
95
+ updateContentTitle();
96
+ showStatsAndSearch();
97
+ renderLiteTasks();
98
+ });
99
+ });
100
+
101
+ // View Navigation (Project Overview, MCP Manager, etc.)
102
+ document.querySelectorAll('.nav-item[data-view]').forEach(item => {
103
+ item.addEventListener('click', () => {
104
+ cleanupPreviousView();
105
+
106
+ setActiveNavItem(item);
107
+ currentView = item.dataset.view;
108
+ currentFilter = null;
109
+ currentLiteType = null;
110
+ currentSessionDetailKey = null;
111
+ updateContentTitle();
112
+
113
+ // Route to appropriate view
114
+ if (currentView === 'mcp-manager') {
115
+ renderMcpManager();
116
+ } else if (currentView === 'project-overview') {
117
+ renderProjectOverview();
118
+ } else if (currentView === 'explorer') {
119
+ renderExplorer();
120
+ } else if (currentView === 'cli-manager') {
121
+ renderCliManager();
122
+ } else if (currentView === 'cli-history') {
123
+ renderCliHistoryView();
124
+ } else if (currentView === 'hook-manager') {
125
+ renderHookManager();
126
+ } else if (currentView === 'memory') {
127
+ renderMemoryView();
128
+ } else if (currentView === 'prompt-history') {
129
+ renderPromptHistoryView();
130
+ } else if (currentView === 'skills-manager') {
131
+ renderSkillsManager();
132
+ } else if (currentView === 'rules-manager') {
133
+ renderRulesManager();
134
+ } else if (currentView === 'claude-manager') {
135
+ renderClaudeManager();
136
+ } else if (currentView === 'graph-explorer') {
137
+ renderGraphExplorer();
138
+ } else if (currentView === 'help') {
139
+ renderHelpView();
140
+ } else if (currentView === 'core-memory') {
141
+ if (typeof renderCoreMemoryView === 'function') {
142
+ renderCoreMemoryView();
143
+ } else {
144
+ console.error('renderCoreMemoryView not defined - please refresh the page');
145
+ }
146
+ } else if (currentView === 'codexlens-manager') {
147
+ if (typeof renderCodexLensManager === 'function') {
148
+ renderCodexLensManager();
149
+ } else {
150
+ console.error('renderCodexLensManager not defined - please refresh the page');
151
+ }
152
+ } else if (currentView === 'api-settings') {
153
+ if (typeof renderApiSettings === 'function') {
154
+ renderApiSettings();
155
+ } else {
156
+ console.error('renderApiSettings not defined - please refresh the page');
157
+ }
158
+ }
159
+ });
160
+ });
161
+ }
162
+
163
+ function setActiveNavItem(item) {
164
+ document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
165
+ item.classList.add('active');
166
+ }
167
+
168
+ function updateContentTitle() {
169
+ const titleEl = document.getElementById('contentTitle');
170
+ if (currentView === 'project-overview') {
171
+ titleEl.textContent = t('title.projectOverview');
172
+ } else if (currentView === 'mcp-manager') {
173
+ titleEl.textContent = t('title.mcpManagement');
174
+ } else if (currentView === 'explorer') {
175
+ titleEl.textContent = t('title.fileExplorer');
176
+ } else if (currentView === 'cli-manager') {
177
+ titleEl.textContent = t('title.cliTools');
178
+ } else if (currentView === 'cli-history') {
179
+ titleEl.textContent = t('title.cliHistory');
180
+ } else if (currentView === 'hook-manager') {
181
+ titleEl.textContent = t('title.hookManager');
182
+ } else if (currentView === 'memory') {
183
+ titleEl.textContent = t('title.memoryModule');
184
+ } else if (currentView === 'prompt-history') {
185
+ titleEl.textContent = t('title.promptHistory');
186
+ } else if (currentView === 'skills-manager') {
187
+ titleEl.textContent = t('title.skillsManager');
188
+ } else if (currentView === 'rules-manager') {
189
+ titleEl.textContent = t('title.rulesManager');
190
+ } else if (currentView === 'claude-manager') {
191
+ titleEl.textContent = t('title.claudeManager');
192
+ } else if (currentView === 'graph-explorer') {
193
+ titleEl.textContent = t('title.graphExplorer');
194
+ } else if (currentView === 'help') {
195
+ titleEl.textContent = t('title.helpGuide');
196
+ } else if (currentView === 'core-memory') {
197
+ titleEl.textContent = t('title.coreMemory');
198
+ } else if (currentView === 'codexlens-manager') {
199
+ titleEl.textContent = t('title.codexLensManager');
200
+ } else if (currentView === 'api-settings') {
201
+ titleEl.textContent = t('title.apiSettings');
202
+ } else if (currentView === 'liteTasks') {
203
+ const names = { 'lite-plan': t('title.litePlanSessions'), 'lite-fix': t('title.liteFixSessions') };
204
+ titleEl.textContent = names[currentLiteType] || t('title.liteTasks');
205
+ } else if (currentView === 'sessionDetail') {
206
+ titleEl.textContent = t('title.sessionDetail');
207
+ } else if (currentView === 'liteTaskDetail') {
208
+ titleEl.textContent = t('title.liteTaskDetail');
209
+ } else {
210
+ const names = { 'all': t('title.allSessions'), 'active': t('title.activeSessions'), 'archived': t('title.archivedSessions') };
211
+ titleEl.textContent = names[currentFilter] || t('title.sessions');
212
+ }
213
+ }
214
+
215
+ // Search
216
+ function initSearch() {
217
+ const input = document.getElementById('searchInput');
218
+ input.addEventListener('input', (e) => {
219
+ const query = e.target.value.toLowerCase();
220
+ document.querySelectorAll('.session-card').forEach(card => {
221
+ const text = card.textContent.toLowerCase();
222
+ card.style.display = text.includes(query) ? '' : 'none';
223
+ });
224
+ });
225
+ }
226
+
227
+ // Refresh Workspace
228
+ function initRefreshButton() {
229
+ const btn = document.getElementById('refreshWorkspace');
230
+ if (btn) {
231
+ btn.addEventListener('click', refreshWorkspace);
232
+ }
233
+ }
234
+
235
+ async function refreshWorkspace() {
236
+ const btn = document.getElementById('refreshWorkspace');
237
+
238
+ // Add spinning animation
239
+ btn.classList.add('refreshing');
240
+ btn.disabled = true;
241
+
242
+ try {
243
+ if (window.SERVER_MODE) {
244
+ // Reload data from server
245
+ const data = await loadDashboardData(projectPath);
246
+ if (data) {
247
+ // Clear and repopulate stores
248
+ Object.keys(sessionDataStore).forEach(k => delete sessionDataStore[k]);
249
+ Object.keys(liteTaskDataStore).forEach(k => delete liteTaskDataStore[k]);
250
+
251
+ // Populate stores
252
+ [...(data.activeSessions || []), ...(data.archivedSessions || [])].forEach(s => {
253
+ const sessionKey = `session-${s.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-');
254
+ sessionDataStore[sessionKey] = s;
255
+ });
256
+
257
+ [...(data.liteTasks?.litePlan || []), ...(data.liteTasks?.liteFix || [])].forEach(s => {
258
+ const sessionKey = `lite-${s.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-');
259
+ liteTaskDataStore[sessionKey] = s;
260
+ });
261
+
262
+ // Update global data
263
+ window.workflowData = data;
264
+
265
+ // Update sidebar counts
266
+ updateSidebarCounts(data);
267
+
268
+ // Re-render current view
269
+ if (currentView === 'sessions') {
270
+ renderSessions();
271
+ } else if (currentView === 'liteTasks') {
272
+ renderLiteTasks();
273
+ } else if (currentView === 'sessionDetail' && currentSessionDetailKey) {
274
+ showSessionDetailPage(currentSessionDetailKey);
275
+ } else if (currentView === 'liteTaskDetail' && currentSessionDetailKey) {
276
+ showLiteTaskDetailPage(currentSessionDetailKey);
277
+ } else if (currentView === 'project-overview') {
278
+ renderProjectOverview();
279
+ }
280
+
281
+ showRefreshToast(t('toast.workspaceRefreshed'), 'success');
282
+ }
283
+ } else {
284
+ // Non-server mode: just reload page
285
+ window.location.reload();
286
+ }
287
+ } catch (error) {
288
+ console.error('Refresh failed:', error);
289
+ showRefreshToast(t('toast.refreshFailed', { error: error.message }), 'error');
290
+ } finally {
291
+ btn.classList.remove('refreshing');
292
+ btn.disabled = false;
293
+ }
294
+ }
295
+
296
+ function updateSidebarCounts(data) {
297
+ // Update session counts
298
+ const activeCount = document.querySelector('.nav-item[data-filter="active"] .nav-count');
299
+ const archivedCount = document.querySelector('.nav-item[data-filter="archived"] .nav-count');
300
+ const allCount = document.querySelector('.nav-item[data-filter="all"] .nav-count');
301
+
302
+ if (activeCount) activeCount.textContent = data.activeSessions?.length || 0;
303
+ if (archivedCount) archivedCount.textContent = data.archivedSessions?.length || 0;
304
+ if (allCount) allCount.textContent = (data.activeSessions?.length || 0) + (data.archivedSessions?.length || 0);
305
+
306
+ // Update lite task counts
307
+ const litePlanCount = document.querySelector('.nav-item[data-lite="lite-plan"] .nav-count');
308
+ const liteFixCount = document.querySelector('.nav-item[data-lite="lite-fix"] .nav-count');
309
+
310
+ if (litePlanCount) litePlanCount.textContent = data.liteTasks?.litePlan?.length || 0;
311
+ if (liteFixCount) liteFixCount.textContent = data.liteTasks?.liteFix?.length || 0;
312
+ }
313
+
314
+ function showRefreshToast(message, type) {
315
+ // Remove existing toast
316
+ const existing = document.querySelector('.status-toast');
317
+ if (existing) existing.remove();
318
+
319
+ const toast = document.createElement('div');
320
+ toast.className = `status-toast ${type}`;
321
+ toast.textContent = message;
322
+ document.body.appendChild(toast);
323
+
324
+ // Increase display time to 3.5 seconds for better visibility
325
+ setTimeout(() => {
326
+ toast.classList.add('fade-out');
327
+ setTimeout(() => toast.remove(), 300);
328
+ }, 3500);
329
+ }