claude-code-workflow 6.0.5 → 6.1.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/agents/action-planning-agent.md +1 -1
- package/.claude/agents/cli-execution-agent.md +269 -269
- package/.claude/agents/cli-explore-agent.md +182 -182
- package/.claude/agents/context-search-agent.md +582 -582
- package/.claude/agents/memory-bridge.md +93 -93
- package/.claude/commands/cli/cli-init.md +1 -1
- package/.claude/commands/memory/docs-full-cli.md +471 -471
- package/.claude/commands/memory/docs-related-cli.md +386 -386
- package/.claude/commands/memory/docs.md +615 -615
- package/.claude/commands/memory/load.md +1 -1
- package/.claude/commands/memory/update-full.md +332 -332
- package/.claude/commands/memory/update-related.md +5 -5
- package/.claude/commands/workflow/init.md +1 -1
- package/.claude/commands/workflow/lite-fix.md +621 -621
- package/.claude/commands/workflow/lite-plan.md +592 -592
- package/.claude/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/commands/workflow/ui-design/generate.md +504 -504
- package/.claude/commands/workflow/ui-design/import-from-code.md +537 -537
- package/.claude/scripts/classify-folders.sh +4 -0
- package/.claude/scripts/convert_tokens_to_css.sh +4 -0
- package/.claude/scripts/detect_changed_modules.sh +5 -1
- package/.claude/scripts/discover-design-files.sh +87 -83
- package/.claude/scripts/generate_module_docs.sh +717 -713
- package/.claude/scripts/get_modules_by_depth.sh +5 -1
- package/.claude/scripts/ui-generate-preview.sh +4 -0
- package/.claude/scripts/ui-instantiate-prototypes.sh +4 -0
- package/.claude/scripts/update_module_claude.sh +4 -0
- package/.claude/skills/command-guide/index/all-commands.json +1 -12
- package/.claude/skills/command-guide/index/by-category.json +1 -12
- package/.claude/skills/command-guide/index/by-use-case.json +1 -12
- package/.claude/skills/command-guide/index/essential-commands.json +1 -12
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +127 -71
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +269 -269
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +182 -182
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +18 -38
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +582 -577
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
- package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +1 -1
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +615 -610
- package/.claude/skills/command-guide/reference/commands/memory/load.md +1 -1
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
- package/.claude/skills/command-guide/reference/commands/memory/update-related.md +5 -5
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +299 -451
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +14 -37
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +252 -350
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +2 -2
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +52 -0
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +621 -602
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +46 -36
- package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +18 -58
- package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +22 -52
- package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +19 -48
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +25 -5
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +7 -7
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +151 -11
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +4 -4
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +504 -504
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +537 -537
- package/.claude/workflows/context-search-strategy.md +77 -77
- package/.claude/workflows/tool-strategy.md +90 -71
- package/.claude/workflows/workflow-architecture.md +1 -1
- package/ccw/src/cli.js +7 -0
- package/ccw/src/commands/tool.js +181 -0
- package/ccw/src/core/dashboard-generator.js +18 -3
- package/ccw/src/core/lite-scanner.js +35 -11
- package/ccw/src/core/server.js +531 -46
- package/ccw/src/templates/dashboard-css/01-base.css +161 -0
- package/ccw/src/templates/dashboard-css/02-session.css +726 -0
- package/ccw/src/templates/dashboard-css/03-tasks.css +512 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +843 -0
- package/ccw/src/templates/dashboard-css/05-context.css +2206 -0
- package/ccw/src/templates/dashboard-css/06-cards.css +1570 -0
- package/ccw/src/templates/dashboard-css/07-managers.css +936 -0
- package/ccw/src/templates/dashboard-css/08-review.css +1266 -0
- package/ccw/src/templates/dashboard-css/09-explorer.css +1397 -0
- package/ccw/src/templates/dashboard-js/components/global-notifications.js +219 -0
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +10 -0
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +11 -1
- package/ccw/src/templates/dashboard-js/components/navigation.js +11 -5
- package/ccw/src/templates/dashboard-js/components/tabs-context.js +20 -20
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +11 -11
- package/ccw/src/templates/dashboard-js/components/theme.js +29 -1
- package/ccw/src/templates/dashboard-js/main.js +4 -0
- package/ccw/src/templates/dashboard-js/state.js +5 -0
- package/ccw/src/templates/dashboard-js/views/explorer.js +852 -0
- package/ccw/src/templates/dashboard-js/views/home.js +13 -9
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +8 -5
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +21 -16
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +90 -19
- package/ccw/src/templates/dashboard-js/views/project-overview.js +15 -11
- package/ccw/src/templates/dashboard-js/views/review-session.js +3 -3
- package/ccw/src/templates/dashboard-js/views/session-detail.js +38 -28
- package/ccw/src/templates/dashboard.html +129 -28
- package/ccw/src/tools/classify-folders.js +204 -0
- package/ccw/src/tools/convert-tokens-to-css.js +250 -0
- package/ccw/src/tools/detect-changed-modules.js +288 -0
- package/ccw/src/tools/discover-design-files.js +134 -0
- package/ccw/src/tools/edit-file.js +266 -0
- package/ccw/src/tools/generate-module-docs.js +416 -0
- package/ccw/src/tools/get-modules-by-depth.js +308 -0
- package/ccw/src/tools/index.js +176 -0
- package/ccw/src/tools/ui-generate-preview.js +327 -0
- package/ccw/src/tools/ui-instantiate-prototypes.js +301 -0
- package/ccw/src/tools/update-module-claude.js +380 -0
- package/package.json +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/status.md +0 -352
- package/ccw/src/core/server.js.bak +0 -385
- package/ccw/src/core/server_original.bak +0 -385
- package/ccw/src/templates/dashboard.css +0 -8187
- package/ccw/src/templates/dashboard_tailwind.html +0 -42
- package/ccw/src/templates/dashboard_test.html +0 -37
- package/ccw/src/templates/tailwind-base.css +0 -212
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
// ==========================================
|
|
2
|
+
// GLOBAL NOTIFICATION SYSTEM
|
|
3
|
+
// ==========================================
|
|
4
|
+
// Floating notification panel accessible from any view
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Initialize global notification panel
|
|
8
|
+
*/
|
|
9
|
+
function initGlobalNotifications() {
|
|
10
|
+
// Create FAB and panel if not exists
|
|
11
|
+
if (!document.getElementById('globalNotificationFab')) {
|
|
12
|
+
const fabHtml = `
|
|
13
|
+
<div class="global-notif-fab" id="globalNotificationFab" onclick="toggleGlobalNotifications()" title="Notifications">
|
|
14
|
+
<span class="fab-icon">🔔</span>
|
|
15
|
+
<span class="fab-badge" id="globalNotifBadge">0</span>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="global-notif-panel" id="globalNotificationPanel">
|
|
19
|
+
<div class="global-notif-header">
|
|
20
|
+
<span class="global-notif-title">🔔 Notifications</span>
|
|
21
|
+
<button class="global-notif-close" onclick="toggleGlobalNotifications()">×</button>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="global-notif-actions">
|
|
24
|
+
<button class="notif-action-btn" onclick="clearGlobalNotifications()">
|
|
25
|
+
<span>🗑️</span> Clear All
|
|
26
|
+
</button>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="global-notif-list" id="globalNotificationList">
|
|
29
|
+
<div class="global-notif-empty">
|
|
30
|
+
<span>No notifications</span>
|
|
31
|
+
<p>System events and task updates will appear here</p>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const container = document.createElement('div');
|
|
38
|
+
container.id = 'globalNotificationContainer';
|
|
39
|
+
container.innerHTML = fabHtml;
|
|
40
|
+
document.body.appendChild(container);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
renderGlobalNotifications();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Toggle notification panel visibility
|
|
48
|
+
*/
|
|
49
|
+
function toggleGlobalNotifications() {
|
|
50
|
+
isNotificationPanelVisible = !isNotificationPanelVisible;
|
|
51
|
+
const panel = document.getElementById('globalNotificationPanel');
|
|
52
|
+
const fab = document.getElementById('globalNotificationFab');
|
|
53
|
+
|
|
54
|
+
if (panel && fab) {
|
|
55
|
+
if (isNotificationPanelVisible) {
|
|
56
|
+
panel.classList.add('show');
|
|
57
|
+
fab.classList.add('active');
|
|
58
|
+
} else {
|
|
59
|
+
panel.classList.remove('show');
|
|
60
|
+
fab.classList.remove('active');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Add a global notification
|
|
67
|
+
* @param {string} type - 'info', 'success', 'warning', 'error'
|
|
68
|
+
* @param {string} message - Main notification message
|
|
69
|
+
* @param {string} details - Optional details
|
|
70
|
+
* @param {string} source - Optional source identifier (e.g., 'explorer', 'mcp')
|
|
71
|
+
*/
|
|
72
|
+
function addGlobalNotification(type, message, details = null, source = null) {
|
|
73
|
+
const notification = {
|
|
74
|
+
id: Date.now(),
|
|
75
|
+
type,
|
|
76
|
+
message,
|
|
77
|
+
details,
|
|
78
|
+
source,
|
|
79
|
+
timestamp: new Date().toISOString(),
|
|
80
|
+
read: false
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
globalNotificationQueue.unshift(notification);
|
|
84
|
+
|
|
85
|
+
// Keep only last 100 notifications
|
|
86
|
+
if (globalNotificationQueue.length > 100) {
|
|
87
|
+
globalNotificationQueue = globalNotificationQueue.slice(0, 100);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
renderGlobalNotifications();
|
|
91
|
+
updateGlobalNotifBadge();
|
|
92
|
+
|
|
93
|
+
// Show toast for important notifications
|
|
94
|
+
if (type === 'error' || type === 'success') {
|
|
95
|
+
showNotificationToast(notification);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Show a brief toast notification
|
|
101
|
+
*/
|
|
102
|
+
function showNotificationToast(notification) {
|
|
103
|
+
const typeIcon = {
|
|
104
|
+
'info': 'ℹ️',
|
|
105
|
+
'success': '✅',
|
|
106
|
+
'warning': '⚠️',
|
|
107
|
+
'error': '❌'
|
|
108
|
+
}[notification.type] || 'ℹ️';
|
|
109
|
+
|
|
110
|
+
// Remove existing toast
|
|
111
|
+
const existing = document.querySelector('.notif-toast');
|
|
112
|
+
if (existing) existing.remove();
|
|
113
|
+
|
|
114
|
+
const toast = document.createElement('div');
|
|
115
|
+
toast.className = `notif-toast type-${notification.type}`;
|
|
116
|
+
toast.innerHTML = `
|
|
117
|
+
<span class="toast-icon">${typeIcon}</span>
|
|
118
|
+
<span class="toast-message">${escapeHtml(notification.message)}</span>
|
|
119
|
+
`;
|
|
120
|
+
document.body.appendChild(toast);
|
|
121
|
+
|
|
122
|
+
// Animate in
|
|
123
|
+
requestAnimationFrame(() => toast.classList.add('show'));
|
|
124
|
+
|
|
125
|
+
// Auto-remove
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
toast.classList.remove('show');
|
|
128
|
+
setTimeout(() => toast.remove(), 300);
|
|
129
|
+
}, 3000);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Render notification list
|
|
134
|
+
*/
|
|
135
|
+
function renderGlobalNotifications() {
|
|
136
|
+
const listEl = document.getElementById('globalNotificationList');
|
|
137
|
+
if (!listEl) return;
|
|
138
|
+
|
|
139
|
+
if (globalNotificationQueue.length === 0) {
|
|
140
|
+
listEl.innerHTML = `
|
|
141
|
+
<div class="global-notif-empty">
|
|
142
|
+
<span>No notifications</span>
|
|
143
|
+
<p>System events and task updates will appear here</p>
|
|
144
|
+
</div>
|
|
145
|
+
`;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
listEl.innerHTML = globalNotificationQueue.map(notif => {
|
|
150
|
+
const typeIcon = {
|
|
151
|
+
'info': 'ℹ️',
|
|
152
|
+
'success': '✅',
|
|
153
|
+
'warning': '⚠️',
|
|
154
|
+
'error': '❌'
|
|
155
|
+
}[notif.type] || 'ℹ️';
|
|
156
|
+
|
|
157
|
+
const time = formatNotifTime(notif.timestamp);
|
|
158
|
+
const sourceLabel = notif.source ? `<span class="notif-source">${notif.source}</span>` : '';
|
|
159
|
+
|
|
160
|
+
return `
|
|
161
|
+
<div class="global-notif-item type-${notif.type} ${notif.read ? 'read' : ''}" data-id="${notif.id}">
|
|
162
|
+
<div class="notif-item-header">
|
|
163
|
+
<span class="notif-icon">${typeIcon}</span>
|
|
164
|
+
<span class="notif-message">${escapeHtml(notif.message)}</span>
|
|
165
|
+
${sourceLabel}
|
|
166
|
+
</div>
|
|
167
|
+
${notif.details ? `<div class="notif-details">${escapeHtml(notif.details)}</div>` : ''}
|
|
168
|
+
<div class="notif-meta">
|
|
169
|
+
<span class="notif-time">${time}</span>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
`;
|
|
173
|
+
}).join('');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Format notification time
|
|
178
|
+
*/
|
|
179
|
+
function formatNotifTime(timestamp) {
|
|
180
|
+
const date = new Date(timestamp);
|
|
181
|
+
const now = new Date();
|
|
182
|
+
const diff = now - date;
|
|
183
|
+
|
|
184
|
+
if (diff < 60000) return 'Just now';
|
|
185
|
+
if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
|
|
186
|
+
if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`;
|
|
187
|
+
return date.toLocaleDateString();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Update notification badge
|
|
192
|
+
*/
|
|
193
|
+
function updateGlobalNotifBadge() {
|
|
194
|
+
const badge = document.getElementById('globalNotifBadge');
|
|
195
|
+
if (badge) {
|
|
196
|
+
const unreadCount = globalNotificationQueue.filter(n => !n.read).length;
|
|
197
|
+
badge.textContent = unreadCount;
|
|
198
|
+
badge.style.display = unreadCount > 0 ? 'flex' : 'none';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Clear all notifications
|
|
204
|
+
*/
|
|
205
|
+
function clearGlobalNotifications() {
|
|
206
|
+
globalNotificationQueue = [];
|
|
207
|
+
renderGlobalNotifications();
|
|
208
|
+
updateGlobalNotifBadge();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Mark all as read
|
|
213
|
+
*/
|
|
214
|
+
function markAllNotificationsRead() {
|
|
215
|
+
globalNotificationQueue.forEach(n => n.read = true);
|
|
216
|
+
renderGlobalNotifications();
|
|
217
|
+
updateGlobalNotifBadge();
|
|
218
|
+
}
|
|
219
|
+
|
|
@@ -271,3 +271,13 @@ function getHookEventIcon(event) {
|
|
|
271
271
|
};
|
|
272
272
|
return icons[event] || '🪝';
|
|
273
273
|
}
|
|
274
|
+
|
|
275
|
+
function getHookEventIconLucide(event) {
|
|
276
|
+
const icons = {
|
|
277
|
+
'PreToolUse': '<i data-lucide="clock" class="w-5 h-5"></i>',
|
|
278
|
+
'PostToolUse': '<i data-lucide="check-circle" class="w-5 h-5"></i>',
|
|
279
|
+
'Notification': '<i data-lucide="bell" class="w-5 h-5"></i>',
|
|
280
|
+
'Stop': '<i data-lucide="octagon-x" class="w-5 h-5"></i>'
|
|
281
|
+
};
|
|
282
|
+
return icons[event] || '<i data-lucide="webhook" class="w-5 h-5"></i>';
|
|
283
|
+
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
// MCP Manager Component
|
|
2
|
-
// Manages MCP server configuration from
|
|
2
|
+
// Manages MCP server configuration from multiple sources:
|
|
3
|
+
// - Enterprise: managed-mcp.json (highest priority)
|
|
4
|
+
// - User: ~/.claude.json mcpServers
|
|
5
|
+
// - Project: .mcp.json in project root
|
|
6
|
+
// - Local: ~/.claude.json projects[path].mcpServers
|
|
3
7
|
|
|
4
8
|
// ========== MCP State ==========
|
|
5
9
|
let mcpConfig = null;
|
|
6
10
|
let mcpAllProjects = {};
|
|
7
11
|
let mcpGlobalServers = {};
|
|
12
|
+
let mcpUserServers = {};
|
|
13
|
+
let mcpEnterpriseServers = {};
|
|
8
14
|
let mcpCurrentProjectServers = {};
|
|
15
|
+
let mcpConfigSources = [];
|
|
9
16
|
let mcpCreateMode = 'form'; // 'form' or 'json'
|
|
10
17
|
|
|
11
18
|
// ========== Initialization ==========
|
|
@@ -33,6 +40,9 @@ async function loadMcpConfig() {
|
|
|
33
40
|
mcpConfig = data;
|
|
34
41
|
mcpAllProjects = data.projects || {};
|
|
35
42
|
mcpGlobalServers = data.globalServers || {};
|
|
43
|
+
mcpUserServers = data.userServers || {};
|
|
44
|
+
mcpEnterpriseServers = data.enterpriseServers || {};
|
|
45
|
+
mcpConfigSources = data.configSources || [];
|
|
36
46
|
|
|
37
47
|
// Get current project servers
|
|
38
48
|
const currentPath = projectPath.replace(/\//g, '\\');
|
|
@@ -96,6 +96,8 @@ function initNavigation() {
|
|
|
96
96
|
renderMcpManager();
|
|
97
97
|
} else if (currentView === 'project-overview') {
|
|
98
98
|
renderProjectOverview();
|
|
99
|
+
} else if (currentView === 'explorer') {
|
|
100
|
+
renderExplorer();
|
|
99
101
|
}
|
|
100
102
|
});
|
|
101
103
|
});
|
|
@@ -112,6 +114,8 @@ function updateContentTitle() {
|
|
|
112
114
|
titleEl.textContent = 'Project Overview';
|
|
113
115
|
} else if (currentView === 'mcp-manager') {
|
|
114
116
|
titleEl.textContent = 'MCP Server Management';
|
|
117
|
+
} else if (currentView === 'explorer') {
|
|
118
|
+
titleEl.textContent = 'File Explorer';
|
|
115
119
|
} else if (currentView === 'liteTasks') {
|
|
116
120
|
const names = { 'lite-plan': 'Lite Plan Sessions', 'lite-fix': 'Lite Fix Sessions' };
|
|
117
121
|
titleEl.textContent = names[currentLiteType] || 'Lite Tasks';
|
|
@@ -157,17 +161,19 @@ async function refreshWorkspace() {
|
|
|
157
161
|
// Reload data from server
|
|
158
162
|
const data = await loadDashboardData(projectPath);
|
|
159
163
|
if (data) {
|
|
160
|
-
//
|
|
161
|
-
sessionDataStore
|
|
162
|
-
liteTaskDataStore
|
|
164
|
+
// Clear and repopulate stores
|
|
165
|
+
Object.keys(sessionDataStore).forEach(k => delete sessionDataStore[k]);
|
|
166
|
+
Object.keys(liteTaskDataStore).forEach(k => delete liteTaskDataStore[k]);
|
|
163
167
|
|
|
164
168
|
// Populate stores
|
|
165
169
|
[...(data.activeSessions || []), ...(data.archivedSessions || [])].forEach(s => {
|
|
166
|
-
|
|
170
|
+
const sessionKey = `session-${s.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-');
|
|
171
|
+
sessionDataStore[sessionKey] = s;
|
|
167
172
|
});
|
|
168
173
|
|
|
169
174
|
[...(data.liteTasks?.litePlan || []), ...(data.liteTasks?.liteFix || [])].forEach(s => {
|
|
170
|
-
|
|
175
|
+
const sessionKey = `lite-${s.session_id}`.replace(/[^a-zA-Z0-9-]/g, '-');
|
|
176
|
+
liteTaskDataStore[sessionKey] = s;
|
|
171
177
|
});
|
|
172
178
|
|
|
173
179
|
// Update global data
|
|
@@ -12,7 +12,7 @@ function renderContextContent(context) {
|
|
|
12
12
|
if (!context) {
|
|
13
13
|
return `
|
|
14
14
|
<div class="tab-empty-state">
|
|
15
|
-
<div class="empty-icon"
|
|
15
|
+
<div class="empty-icon"><i data-lucide="package" class="w-12 h-12"></i></div>
|
|
16
16
|
<div class="empty-title">No Context Data</div>
|
|
17
17
|
<div class="empty-text">No context-package.json found for this session.</div>
|
|
18
18
|
</div>
|
|
@@ -39,9 +39,9 @@ function renderContextContent(context) {
|
|
|
39
39
|
<!-- Header Card -->
|
|
40
40
|
<div class="ctx-header-card">
|
|
41
41
|
<div class="ctx-header-content">
|
|
42
|
-
<h3 class="ctx-main-title"
|
|
42
|
+
<h3 class="ctx-main-title"><i data-lucide="package" class="w-5 h-5 inline mr-2"></i>Context Package</h3>
|
|
43
43
|
<button class="btn-view-modal" onclick="openMarkdownModal('context-package.json', window._currentContextJson, 'json')">
|
|
44
|
-
|
|
44
|
+
<i data-lucide="eye" class="w-4 h-4 inline mr-1"></i>View JSON
|
|
45
45
|
</button>
|
|
46
46
|
</div>
|
|
47
47
|
</div>
|
|
@@ -50,7 +50,7 @@ function renderContextContent(context) {
|
|
|
50
50
|
${metadata.task_description || metadata.session_id ? `
|
|
51
51
|
<div class="ctx-card">
|
|
52
52
|
<div class="ctx-card-header">
|
|
53
|
-
<span class="ctx-card-icon"
|
|
53
|
+
<span class="ctx-card-icon"><i data-lucide="clipboard-list" class="w-5 h-5"></i></span>
|
|
54
54
|
<h4 class="ctx-card-title">Task Metadata</h4>
|
|
55
55
|
</div>
|
|
56
56
|
<div class="ctx-card-body">
|
|
@@ -90,7 +90,7 @@ function renderContextContent(context) {
|
|
|
90
90
|
${architecturePatterns.length > 0 ? `
|
|
91
91
|
<div class="ctx-card">
|
|
92
92
|
<div class="ctx-card-header">
|
|
93
|
-
<span class="ctx-card-icon"
|
|
93
|
+
<span class="ctx-card-icon"><i data-lucide="building-2" class="w-5 h-5"></i></span>
|
|
94
94
|
<h4 class="ctx-card-title">Architecture Patterns</h4>
|
|
95
95
|
<span class="ctx-count-badge">${architecturePatterns.length}</span>
|
|
96
96
|
</div>
|
|
@@ -106,7 +106,7 @@ function renderContextContent(context) {
|
|
|
106
106
|
${Object.keys(techStack).length > 0 ? `
|
|
107
107
|
<div class="ctx-card">
|
|
108
108
|
<div class="ctx-card-header">
|
|
109
|
-
<span class="ctx-card-icon"
|
|
109
|
+
<span class="ctx-card-icon"><i data-lucide="code-2" class="w-5 h-5"></i></span>
|
|
110
110
|
<h4 class="ctx-card-title">Technology Stack</h4>
|
|
111
111
|
</div>
|
|
112
112
|
<div class="ctx-card-body">
|
|
@@ -119,7 +119,7 @@ function renderContextContent(context) {
|
|
|
119
119
|
${Object.keys(codingConventions).length > 0 ? `
|
|
120
120
|
<div class="ctx-card">
|
|
121
121
|
<div class="ctx-card-header">
|
|
122
|
-
<span class="ctx-card-icon"
|
|
122
|
+
<span class="ctx-card-icon"><i data-lucide="file-code" class="w-5 h-5"></i></span>
|
|
123
123
|
<h4 class="ctx-card-title">Coding Conventions</h4>
|
|
124
124
|
</div>
|
|
125
125
|
<div class="ctx-card-body">
|
|
@@ -145,7 +145,7 @@ function renderContextContent(context) {
|
|
|
145
145
|
${(dependencies.internal && dependencies.internal.length > 0) || (dependencies.external && dependencies.external.length > 0) ? `
|
|
146
146
|
<div class="ctx-card">
|
|
147
147
|
<div class="ctx-card-header">
|
|
148
|
-
<span class="ctx-card-icon"
|
|
148
|
+
<span class="ctx-card-icon"><i data-lucide="link" class="w-5 h-5"></i></span>
|
|
149
149
|
<h4 class="ctx-card-title">Dependencies</h4>
|
|
150
150
|
</div>
|
|
151
151
|
<div class="ctx-card-body">
|
|
@@ -158,7 +158,7 @@ function renderContextContent(context) {
|
|
|
158
158
|
${Object.keys(testContext).length > 0 ? `
|
|
159
159
|
<div class="ctx-card">
|
|
160
160
|
<div class="ctx-card-header">
|
|
161
|
-
<span class="ctx-card-icon"
|
|
161
|
+
<span class="ctx-card-icon"><i data-lucide="flask-conical" class="w-5 h-5"></i></span>
|
|
162
162
|
<h4 class="ctx-card-title">Test Context</h4>
|
|
163
163
|
</div>
|
|
164
164
|
<div class="ctx-card-body">
|
|
@@ -314,7 +314,7 @@ function renderAssetsCards(assets) {
|
|
|
314
314
|
sections.push(`
|
|
315
315
|
<div class="ctx-assets-category">
|
|
316
316
|
<div class="ctx-assets-cat-header">
|
|
317
|
-
<span class="ctx-assets-cat-icon"
|
|
317
|
+
<span class="ctx-assets-cat-icon"><i data-lucide="file-text" class="w-4 h-4"></i></span>
|
|
318
318
|
<span class="ctx-assets-cat-title">Documentation</span>
|
|
319
319
|
<span class="ctx-assets-cat-count">${assets.documentation.length}</span>
|
|
320
320
|
</div>
|
|
@@ -335,7 +335,7 @@ function renderAssetsCards(assets) {
|
|
|
335
335
|
sections.push(`
|
|
336
336
|
<div class="ctx-assets-category">
|
|
337
337
|
<div class="ctx-assets-cat-header">
|
|
338
|
-
<span class="ctx-assets-cat-icon"
|
|
338
|
+
<span class="ctx-assets-cat-icon"><i data-lucide="code-2" class="w-4 h-4"></i></span>
|
|
339
339
|
<span class="ctx-assets-cat-title">Source Code</span>
|
|
340
340
|
<span class="ctx-assets-cat-count">${assets.source_code.length}</span>
|
|
341
341
|
</div>
|
|
@@ -356,7 +356,7 @@ function renderAssetsCards(assets) {
|
|
|
356
356
|
sections.push(`
|
|
357
357
|
<div class="ctx-assets-category">
|
|
358
358
|
<div class="ctx-assets-cat-header">
|
|
359
|
-
<span class="ctx-assets-cat-icon"
|
|
359
|
+
<span class="ctx-assets-cat-icon"><i data-lucide="flask-conical" class="w-4 h-4"></i></span>
|
|
360
360
|
<span class="ctx-assets-cat-title">Tests</span>
|
|
361
361
|
<span class="ctx-assets-cat-count">${assets.tests.length}</span>
|
|
362
362
|
</div>
|
|
@@ -657,7 +657,7 @@ function renderAssetsSection(assets) {
|
|
|
657
657
|
if (assets.documentation && assets.documentation.length > 0) {
|
|
658
658
|
sections.push(`
|
|
659
659
|
<div class="asset-category">
|
|
660
|
-
<h5 class="asset-category-title"
|
|
660
|
+
<h5 class="asset-category-title"><i data-lucide="file-text" class="w-4 h-4 inline mr-1"></i>Documentation</h5>
|
|
661
661
|
<div class="asset-grid">
|
|
662
662
|
${assets.documentation.map(doc => `
|
|
663
663
|
<div class="asset-card">
|
|
@@ -684,7 +684,7 @@ function renderAssetsSection(assets) {
|
|
|
684
684
|
if (assets.source_code && assets.source_code.length > 0) {
|
|
685
685
|
sections.push(`
|
|
686
686
|
<div class="asset-category">
|
|
687
|
-
<h5 class="asset-category-title"
|
|
687
|
+
<h5 class="asset-category-title"><i data-lucide="code-2" class="w-4 h-4 inline mr-1"></i>Source Code</h5>
|
|
688
688
|
<div class="asset-grid">
|
|
689
689
|
${assets.source_code.map(src => `
|
|
690
690
|
<div class="asset-card">
|
|
@@ -712,7 +712,7 @@ function renderAssetsSection(assets) {
|
|
|
712
712
|
if (assets.tests && assets.tests.length > 0) {
|
|
713
713
|
sections.push(`
|
|
714
714
|
<div class="asset-category">
|
|
715
|
-
<h5 class="asset-category-title"
|
|
715
|
+
<h5 class="asset-category-title"><i data-lucide="flask-conical" class="w-4 h-4 inline mr-1"></i>Tests</h5>
|
|
716
716
|
<div class="asset-grid">
|
|
717
717
|
${assets.tests.map(test => `
|
|
718
718
|
<div class="asset-card">
|
|
@@ -764,7 +764,7 @@ function renderDependenciesSection(dependencies) {
|
|
|
764
764
|
if (dependencies.external && dependencies.external.length > 0) {
|
|
765
765
|
sections.push(`
|
|
766
766
|
<div class="dep-category">
|
|
767
|
-
<h5 class="dep-category-title"
|
|
767
|
+
<h5 class="dep-category-title"><i data-lucide="package" class="w-4 h-4 inline mr-1"></i>External Dependencies</h5>
|
|
768
768
|
<div class="dep-grid">
|
|
769
769
|
${dependencies.external.map(dep => `
|
|
770
770
|
<div class="dep-external-card">
|
|
@@ -836,7 +836,7 @@ function renderTestContextSection(testContext) {
|
|
|
836
836
|
|
|
837
837
|
sections.push(`
|
|
838
838
|
<div class="test-category">
|
|
839
|
-
<h5 class="test-category-title"
|
|
839
|
+
<h5 class="test-category-title"><i data-lucide="bar-chart-3" class="w-4 h-4 inline mr-1"></i>Test Statistics</h5>
|
|
840
840
|
<div class="test-stats-grid">
|
|
841
841
|
<div class="stat-card">
|
|
842
842
|
<div class="stat-value">${totalTests}</div>
|
|
@@ -930,7 +930,7 @@ function renderConflictDetectionSection(conflictDetection) {
|
|
|
930
930
|
if (conflictDetection.affected_modules && conflictDetection.affected_modules.length > 0) {
|
|
931
931
|
sections.push(`
|
|
932
932
|
<div class="conflict-category">
|
|
933
|
-
<h5 class="conflict-category-title"
|
|
933
|
+
<h5 class="conflict-category-title"><i data-lucide="package-open" class="w-4 h-4 inline mr-1"></i>Affected Modules</h5>
|
|
934
934
|
<div class="affected-modules-grid">
|
|
935
935
|
${conflictDetection.affected_modules.map(mod => `
|
|
936
936
|
<span class="affected-module-tag">${escapeHtml(mod)}</span>
|
|
@@ -996,7 +996,7 @@ function renderSessionContextContent(context, explorations, conflictResolution)
|
|
|
996
996
|
|
|
997
997
|
return `
|
|
998
998
|
<div class="tab-empty-state">
|
|
999
|
-
<div class="empty-icon"
|
|
999
|
+
<div class="empty-icon"><i data-lucide="package" class="w-12 h-12"></i></div>
|
|
1000
1000
|
<div class="empty-title">No Context Data</div>
|
|
1001
1001
|
<div class="empty-text">No context-package.json or exploration files found for this session.</div>
|
|
1002
1002
|
</div>
|
|
@@ -1033,7 +1033,7 @@ function renderConflictResolutionContext(conflictResolution) {
|
|
|
1033
1033
|
<div class="conflict-decisions-section collapsible-section">
|
|
1034
1034
|
<div class="collapsible-header">
|
|
1035
1035
|
<span class="collapse-icon">▶</span>
|
|
1036
|
-
<span class="section-label"
|
|
1036
|
+
<span class="section-label"><i data-lucide="target" class="w-4 h-4 inline mr-1"></i>User Decisions (${decisions.length})</span>
|
|
1037
1037
|
</div>
|
|
1038
1038
|
<div class="collapsible-content collapsed">
|
|
1039
1039
|
<div class="decisions-list">
|
|
@@ -11,7 +11,7 @@ function renderSummaryContent(summaries) {
|
|
|
11
11
|
if (!summaries || summaries.length === 0) {
|
|
12
12
|
return `
|
|
13
13
|
<div class="tab-empty-state">
|
|
14
|
-
<div class="empty-icon"
|
|
14
|
+
<div class="empty-icon"><i data-lucide="file-text" class="w-12 h-12"></i></div>
|
|
15
15
|
<div class="empty-title">No Summaries</div>
|
|
16
16
|
<div class="empty-text">No summaries found in .summaries/</div>
|
|
17
17
|
</div>
|
|
@@ -31,9 +31,9 @@ function renderSummaryContent(summaries) {
|
|
|
31
31
|
return `
|
|
32
32
|
<div class="summary-item-card">
|
|
33
33
|
<div class="summary-item-header">
|
|
34
|
-
<h4 class="summary-item-title"
|
|
34
|
+
<h4 class="summary-item-title"><i data-lucide="file-text" class="w-4 h-4 inline mr-1"></i>${escapeHtml(s.name || 'Summary')}</h4>
|
|
35
35
|
<button class="btn-view-modal" onclick="openMarkdownModal('${escapeHtml(s.name || 'Summary')}', window._currentSummaries[${idx}].content, 'markdown');">
|
|
36
|
-
|
|
36
|
+
<i data-lucide="eye" class="w-4 h-4 inline mr-1"></i>View
|
|
37
37
|
</button>
|
|
38
38
|
</div>
|
|
39
39
|
<div class="summary-item-preview">
|
|
@@ -54,7 +54,7 @@ function renderImplPlanContent(implPlan) {
|
|
|
54
54
|
if (!implPlan) {
|
|
55
55
|
return `
|
|
56
56
|
<div class="tab-empty-state">
|
|
57
|
-
<div class="empty-icon"
|
|
57
|
+
<div class="empty-icon"><i data-lucide="ruler" class="w-12 h-12"></i></div>
|
|
58
58
|
<div class="empty-title">No IMPL Plan</div>
|
|
59
59
|
<div class="empty-text">No IMPL_PLAN.md found for this session.</div>
|
|
60
60
|
</div>
|
|
@@ -73,9 +73,9 @@ function renderImplPlanContent(implPlan) {
|
|
|
73
73
|
<div class="impl-plan-tab-content">
|
|
74
74
|
<div class="impl-plan-card">
|
|
75
75
|
<div class="impl-plan-header">
|
|
76
|
-
<h3 class="impl-plan-title"
|
|
76
|
+
<h3 class="impl-plan-title"><i data-lucide="ruler" class="w-5 h-5 inline mr-2"></i>Implementation Plan</h3>
|
|
77
77
|
<button class="btn-view-modal" onclick="openMarkdownModal('IMPL_PLAN.md', window._currentImplPlan, 'markdown')">
|
|
78
|
-
|
|
78
|
+
<i data-lucide="eye" class="w-4 h-4 inline mr-1"></i>View
|
|
79
79
|
</button>
|
|
80
80
|
</div>
|
|
81
81
|
<div class="impl-plan-preview">
|
|
@@ -151,7 +151,7 @@ function renderLiteContextContent(context, explorations, session) {
|
|
|
151
151
|
|
|
152
152
|
return `
|
|
153
153
|
<div class="tab-empty-state">
|
|
154
|
-
<div class="empty-icon"
|
|
154
|
+
<div class="empty-icon"><i data-lucide="package" class="w-12 h-12"></i></div>
|
|
155
155
|
<div class="empty-title">No Context Data</div>
|
|
156
156
|
<div class="empty-text">No context-package.json or exploration files found for this session.</div>
|
|
157
157
|
</div>
|
|
@@ -187,10 +187,10 @@ function renderExplorationContext(explorations) {
|
|
|
187
187
|
// Render each exploration angle as collapsible section
|
|
188
188
|
const explorationOrder = ['architecture', 'dependencies', 'patterns', 'integration-points'];
|
|
189
189
|
const explorationTitles = {
|
|
190
|
-
'architecture': '
|
|
191
|
-
'dependencies': '
|
|
192
|
-
'patterns': '
|
|
193
|
-
'integration-points': '
|
|
190
|
+
'architecture': '<i data-lucide="blocks" class="w-4 h-4 inline mr-1"></i>Architecture',
|
|
191
|
+
'dependencies': '<i data-lucide="package" class="w-4 h-4 inline mr-1"></i>Dependencies',
|
|
192
|
+
'patterns': '<i data-lucide="git-branch" class="w-4 h-4 inline mr-1"></i>Patterns',
|
|
193
|
+
'integration-points': '<i data-lucide="plug" class="w-4 h-4 inline mr-1"></i>Integration Points'
|
|
194
194
|
};
|
|
195
195
|
|
|
196
196
|
for (const angle of explorationOrder) {
|
|
@@ -6,6 +6,7 @@ function initTheme() {
|
|
|
6
6
|
const saved = localStorage.getItem('theme') || 'light';
|
|
7
7
|
document.documentElement.setAttribute('data-theme', saved);
|
|
8
8
|
updateThemeIcon(saved);
|
|
9
|
+
updateHljsTheme(saved);
|
|
9
10
|
|
|
10
11
|
document.getElementById('themeToggle').addEventListener('click', () => {
|
|
11
12
|
const current = document.documentElement.getAttribute('data-theme');
|
|
@@ -13,9 +14,36 @@ function initTheme() {
|
|
|
13
14
|
document.documentElement.setAttribute('data-theme', next);
|
|
14
15
|
localStorage.setItem('theme', next);
|
|
15
16
|
updateThemeIcon(next);
|
|
17
|
+
updateHljsTheme(next);
|
|
16
18
|
});
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
function updateThemeIcon(theme) {
|
|
20
|
-
document.
|
|
22
|
+
const darkIcon = document.querySelector('.theme-icon-dark');
|
|
23
|
+
const lightIcon = document.querySelector('.theme-icon-light');
|
|
24
|
+
if (darkIcon && lightIcon) {
|
|
25
|
+
if (theme === 'light') {
|
|
26
|
+
darkIcon.classList.remove('hidden');
|
|
27
|
+
lightIcon.classList.add('hidden');
|
|
28
|
+
} else {
|
|
29
|
+
darkIcon.classList.add('hidden');
|
|
30
|
+
lightIcon.classList.remove('hidden');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function updateHljsTheme(theme) {
|
|
36
|
+
// Toggle highlight.js theme stylesheets
|
|
37
|
+
const darkTheme = document.getElementById('hljs-theme-dark');
|
|
38
|
+
const lightTheme = document.getElementById('hljs-theme-light');
|
|
39
|
+
|
|
40
|
+
if (darkTheme && lightTheme) {
|
|
41
|
+
if (theme === 'dark') {
|
|
42
|
+
darkTheme.disabled = false;
|
|
43
|
+
lightTheme.disabled = true;
|
|
44
|
+
} else {
|
|
45
|
+
darkTheme.disabled = true;
|
|
46
|
+
lightTheme.disabled = false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
21
49
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// Initializes all components and sets up global event handlers
|
|
3
3
|
|
|
4
4
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
5
|
+
// Initialize Lucide icons (must be first to render SVG icons)
|
|
6
|
+
try { lucide.createIcons(); } catch (e) { console.error('Lucide icons init failed:', e); }
|
|
7
|
+
|
|
5
8
|
// Initialize components with error handling to prevent cascading failures
|
|
6
9
|
try { initTheme(); } catch (e) { console.error('Theme init failed:', e); }
|
|
7
10
|
try { initSidebar(); } catch (e) { console.error('Sidebar init failed:', e); }
|
|
@@ -12,6 +15,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|
|
12
15
|
try { initCarousel(); } catch (e) { console.error('Carousel init failed:', e); }
|
|
13
16
|
try { initMcpManager(); } catch (e) { console.error('MCP Manager init failed:', e); }
|
|
14
17
|
try { initHookManager(); } catch (e) { console.error('Hook Manager init failed:', e); }
|
|
18
|
+
try { initGlobalNotifications(); } catch (e) { console.error('Global notifications init failed:', e); }
|
|
15
19
|
|
|
16
20
|
// Initialize real-time features (WebSocket + auto-refresh)
|
|
17
21
|
try { initWebSocket(); } catch (e) { console.log('WebSocket not available:', e.message); }
|
|
@@ -35,3 +35,8 @@ const liteTaskDataStore = {};
|
|
|
35
35
|
// Store task JSON data in a global map instead of inline script tags
|
|
36
36
|
// Key: unique task ID, Value: raw task JSON data
|
|
37
37
|
const taskJsonStore = {};
|
|
38
|
+
|
|
39
|
+
// ========== Global Notification Queue ==========
|
|
40
|
+
// Notification queue visible from any view
|
|
41
|
+
let globalNotificationQueue = [];
|
|
42
|
+
let isNotificationPanelVisible = false;
|