@siteboon/claude-code-ui 1.8.2 → 1.8.4
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/dist/assets/index-CeR_JfKq.js +895 -0
- package/dist/assets/index-Co7ALK3i.css +32 -0
- package/{index.html → dist/index.html} +2 -1
- package/package.json +6 -1
- package/server/database/auth.db +0 -0
- package/.env.example +0 -12
- package/.nvmrc +0 -1
- package/postcss.config.js +0 -6
- package/src/App.jsx +0 -751
- package/src/components/ChatInterface.jsx +0 -3485
- package/src/components/ClaudeLogo.jsx +0 -11
- package/src/components/ClaudeStatus.jsx +0 -107
- package/src/components/CodeEditor.jsx +0 -422
- package/src/components/CreateTaskModal.jsx +0 -88
- package/src/components/CursorLogo.jsx +0 -9
- package/src/components/DarkModeToggle.jsx +0 -35
- package/src/components/DiffViewer.jsx +0 -41
- package/src/components/ErrorBoundary.jsx +0 -73
- package/src/components/FileTree.jsx +0 -480
- package/src/components/GitPanel.jsx +0 -1283
- package/src/components/ImageViewer.jsx +0 -54
- package/src/components/LoginForm.jsx +0 -110
- package/src/components/MainContent.jsx +0 -577
- package/src/components/MicButton.jsx +0 -272
- package/src/components/MobileNav.jsx +0 -88
- package/src/components/NextTaskBanner.jsx +0 -695
- package/src/components/PRDEditor.jsx +0 -871
- package/src/components/ProtectedRoute.jsx +0 -44
- package/src/components/QuickSettingsPanel.jsx +0 -262
- package/src/components/Settings.jsx +0 -2023
- package/src/components/SetupForm.jsx +0 -135
- package/src/components/Shell.jsx +0 -663
- package/src/components/Sidebar.jsx +0 -1665
- package/src/components/StandaloneShell.jsx +0 -106
- package/src/components/TaskCard.jsx +0 -210
- package/src/components/TaskDetail.jsx +0 -406
- package/src/components/TaskIndicator.jsx +0 -108
- package/src/components/TaskList.jsx +0 -1054
- package/src/components/TaskMasterSetupWizard.jsx +0 -603
- package/src/components/TaskMasterStatus.jsx +0 -86
- package/src/components/TodoList.jsx +0 -91
- package/src/components/Tooltip.jsx +0 -91
- package/src/components/ui/badge.jsx +0 -31
- package/src/components/ui/button.jsx +0 -46
- package/src/components/ui/input.jsx +0 -19
- package/src/components/ui/scroll-area.jsx +0 -23
- package/src/contexts/AuthContext.jsx +0 -158
- package/src/contexts/TaskMasterContext.jsx +0 -324
- package/src/contexts/TasksSettingsContext.jsx +0 -95
- package/src/contexts/ThemeContext.jsx +0 -94
- package/src/contexts/WebSocketContext.jsx +0 -29
- package/src/hooks/useAudioRecorder.js +0 -109
- package/src/hooks/useVersionCheck.js +0 -39
- package/src/index.css +0 -822
- package/src/lib/utils.js +0 -6
- package/src/main.jsx +0 -10
- package/src/utils/api.js +0 -141
- package/src/utils/websocket.js +0 -109
- package/src/utils/whisper.js +0 -37
- package/tailwind.config.js +0 -63
- package/vite.config.js +0 -29
- /package/{public → dist}/convert-icons.md +0 -0
- /package/{public → dist}/favicon.png +0 -0
- /package/{public → dist}/favicon.svg +0 -0
- /package/{public → dist}/generate-icons.js +0 -0
- /package/{public → dist}/icons/claude-ai-icon.svg +0 -0
- /package/{public → dist}/icons/cursor.svg +0 -0
- /package/{public → dist}/icons/generate-icons.md +0 -0
- /package/{public → dist}/icons/icon-128x128.png +0 -0
- /package/{public → dist}/icons/icon-128x128.svg +0 -0
- /package/{public → dist}/icons/icon-144x144.png +0 -0
- /package/{public → dist}/icons/icon-144x144.svg +0 -0
- /package/{public → dist}/icons/icon-152x152.png +0 -0
- /package/{public → dist}/icons/icon-152x152.svg +0 -0
- /package/{public → dist}/icons/icon-192x192.png +0 -0
- /package/{public → dist}/icons/icon-192x192.svg +0 -0
- /package/{public → dist}/icons/icon-384x384.png +0 -0
- /package/{public → dist}/icons/icon-384x384.svg +0 -0
- /package/{public → dist}/icons/icon-512x512.png +0 -0
- /package/{public → dist}/icons/icon-512x512.svg +0 -0
- /package/{public → dist}/icons/icon-72x72.png +0 -0
- /package/{public → dist}/icons/icon-72x72.svg +0 -0
- /package/{public → dist}/icons/icon-96x96.png +0 -0
- /package/{public → dist}/icons/icon-96x96.svg +0 -0
- /package/{public → dist}/icons/icon-template.svg +0 -0
- /package/{public → dist}/logo.svg +0 -0
- /package/{public → dist}/manifest.json +0 -0
- /package/{public → dist}/screenshots/cli-selection.png +0 -0
- /package/{public → dist}/screenshots/desktop-main.png +0 -0
- /package/{public → dist}/screenshots/mobile-chat.png +0 -0
- /package/{public → dist}/screenshots/tools-modal.png +0 -0
- /package/{public → dist}/sw.js +0 -0
|
@@ -1,603 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import { X, ChevronRight, ChevronLeft, CheckCircle, AlertCircle, Settings, Server, FileText, Sparkles, ExternalLink, Copy } from 'lucide-react';
|
|
3
|
-
import { cn } from '../lib/utils';
|
|
4
|
-
import { api } from '../utils/api';
|
|
5
|
-
|
|
6
|
-
const TaskMasterSetupWizard = ({
|
|
7
|
-
isOpen = true,
|
|
8
|
-
onClose,
|
|
9
|
-
onComplete,
|
|
10
|
-
currentProject,
|
|
11
|
-
className = ''
|
|
12
|
-
}) => {
|
|
13
|
-
const [currentStep, setCurrentStep] = useState(1);
|
|
14
|
-
const [loading, setLoading] = useState(false);
|
|
15
|
-
const [error, setError] = useState(null);
|
|
16
|
-
const [setupData, setSetupData] = useState({
|
|
17
|
-
projectRoot: '',
|
|
18
|
-
initGit: true,
|
|
19
|
-
storeTasksInGit: true,
|
|
20
|
-
addAliases: true,
|
|
21
|
-
skipInstall: false,
|
|
22
|
-
rules: ['claude'],
|
|
23
|
-
mcpConfigured: false,
|
|
24
|
-
prdContent: ''
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const totalSteps = 4;
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
if (currentProject) {
|
|
31
|
-
setSetupData(prev => ({
|
|
32
|
-
...prev,
|
|
33
|
-
projectRoot: currentProject.path || ''
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
}, [currentProject]);
|
|
37
|
-
|
|
38
|
-
const steps = [
|
|
39
|
-
{
|
|
40
|
-
id: 1,
|
|
41
|
-
title: 'Project Configuration',
|
|
42
|
-
description: 'Configure basic TaskMaster settings for your project'
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
id: 2,
|
|
46
|
-
title: 'MCP Server Setup',
|
|
47
|
-
description: 'Ensure TaskMaster MCP server is properly configured'
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: 3,
|
|
51
|
-
title: 'PRD Creation',
|
|
52
|
-
description: 'Create or import a Product Requirements Document'
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
id: 4,
|
|
56
|
-
title: 'Complete Setup',
|
|
57
|
-
description: 'Initialize TaskMaster and generate initial tasks'
|
|
58
|
-
}
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
const handleNext = async () => {
|
|
62
|
-
setError(null);
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
if (currentStep === 1) {
|
|
66
|
-
// Validate project configuration
|
|
67
|
-
if (!setupData.projectRoot) {
|
|
68
|
-
setError('Project root path is required');
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
setCurrentStep(2);
|
|
72
|
-
} else if (currentStep === 2) {
|
|
73
|
-
// Check MCP server status
|
|
74
|
-
setLoading(true);
|
|
75
|
-
try {
|
|
76
|
-
const mcpStatus = await api.get('/mcp-utils/taskmaster-server');
|
|
77
|
-
setSetupData(prev => ({
|
|
78
|
-
...prev,
|
|
79
|
-
mcpConfigured: mcpStatus.hasMCPServer && mcpStatus.isConfigured
|
|
80
|
-
}));
|
|
81
|
-
setCurrentStep(3);
|
|
82
|
-
} catch (err) {
|
|
83
|
-
setError('Failed to check MCP server status. You can continue but some features may not work.');
|
|
84
|
-
setCurrentStep(3);
|
|
85
|
-
}
|
|
86
|
-
} else if (currentStep === 3) {
|
|
87
|
-
// Validate PRD step
|
|
88
|
-
if (!setupData.prdContent.trim()) {
|
|
89
|
-
setError('Please create or import a PRD to continue');
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
setCurrentStep(4);
|
|
93
|
-
} else if (currentStep === 4) {
|
|
94
|
-
// Complete setup
|
|
95
|
-
await completeSetup();
|
|
96
|
-
}
|
|
97
|
-
} catch (err) {
|
|
98
|
-
setError(err.message || 'An error occurred');
|
|
99
|
-
} finally {
|
|
100
|
-
setLoading(false);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const handlePrevious = () => {
|
|
105
|
-
if (currentStep > 1) {
|
|
106
|
-
setCurrentStep(currentStep - 1);
|
|
107
|
-
setError(null);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const completeSetup = async () => {
|
|
112
|
-
setLoading(true);
|
|
113
|
-
try {
|
|
114
|
-
// Initialize TaskMaster project
|
|
115
|
-
const initResponse = await api.post('/taskmaster/initialize', {
|
|
116
|
-
projectRoot: setupData.projectRoot,
|
|
117
|
-
initGit: setupData.initGit,
|
|
118
|
-
storeTasksInGit: setupData.storeTasksInGit,
|
|
119
|
-
addAliases: setupData.addAliases,
|
|
120
|
-
skipInstall: setupData.skipInstall,
|
|
121
|
-
rules: setupData.rules,
|
|
122
|
-
yes: true
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
if (!initResponse.ok) {
|
|
126
|
-
throw new Error('Failed to initialize TaskMaster project');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Save PRD content if provided
|
|
130
|
-
if (setupData.prdContent.trim()) {
|
|
131
|
-
const prdResponse = await api.post('/taskmaster/save-prd', {
|
|
132
|
-
projectRoot: setupData.projectRoot,
|
|
133
|
-
content: setupData.prdContent
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
if (!prdResponse.ok) {
|
|
137
|
-
console.warn('Failed to save PRD content');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Parse PRD to generate initial tasks
|
|
142
|
-
if (setupData.prdContent.trim()) {
|
|
143
|
-
const parseResponse = await api.post('/taskmaster/parse-prd', {
|
|
144
|
-
projectRoot: setupData.projectRoot,
|
|
145
|
-
input: '.taskmaster/docs/prd.txt',
|
|
146
|
-
numTasks: '10',
|
|
147
|
-
research: false,
|
|
148
|
-
force: false
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
if (!parseResponse.ok) {
|
|
152
|
-
console.warn('Failed to parse PRD and generate tasks');
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
onComplete?.();
|
|
157
|
-
onClose?.();
|
|
158
|
-
} catch (err) {
|
|
159
|
-
setError(err.message || 'Failed to complete TaskMaster setup');
|
|
160
|
-
} finally {
|
|
161
|
-
setLoading(false);
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const copyMCPConfig = () => {
|
|
166
|
-
const mcpConfig = `{
|
|
167
|
-
"mcpServers": {
|
|
168
|
-
"": {
|
|
169
|
-
"command": "npx",
|
|
170
|
-
"args": ["-y", "--package=task-master-ai", "task-master-ai"],
|
|
171
|
-
"env": {
|
|
172
|
-
"ANTHROPIC_API_KEY": "your_anthropic_key_here",
|
|
173
|
-
"PERPLEXITY_API_KEY": "your_perplexity_key_here"
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}`;
|
|
178
|
-
navigator.clipboard.writeText(mcpConfig);
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const renderStepContent = () => {
|
|
182
|
-
switch (currentStep) {
|
|
183
|
-
case 1:
|
|
184
|
-
return (
|
|
185
|
-
<div className="space-y-6">
|
|
186
|
-
<div className="text-center">
|
|
187
|
-
<Settings className="w-12 h-12 text-blue-600 mx-auto mb-4" />
|
|
188
|
-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
|
189
|
-
Project Configuration
|
|
190
|
-
</h3>
|
|
191
|
-
<p className="text-gray-600 dark:text-gray-400">
|
|
192
|
-
Configure TaskMaster settings for your project
|
|
193
|
-
</p>
|
|
194
|
-
</div>
|
|
195
|
-
|
|
196
|
-
<div className="space-y-4">
|
|
197
|
-
<div>
|
|
198
|
-
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
199
|
-
Project Root Path
|
|
200
|
-
</label>
|
|
201
|
-
<input
|
|
202
|
-
type="text"
|
|
203
|
-
value={setupData.projectRoot}
|
|
204
|
-
onChange={(e) => setSetupData(prev => ({ ...prev, projectRoot: e.target.value }))}
|
|
205
|
-
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-white"
|
|
206
|
-
placeholder="/path/to/your/project"
|
|
207
|
-
/>
|
|
208
|
-
</div>
|
|
209
|
-
|
|
210
|
-
<div className="space-y-3">
|
|
211
|
-
<h4 className="font-medium text-gray-900 dark:text-white">Options</h4>
|
|
212
|
-
|
|
213
|
-
<label className="flex items-center gap-3">
|
|
214
|
-
<input
|
|
215
|
-
type="checkbox"
|
|
216
|
-
checked={setupData.initGit}
|
|
217
|
-
onChange={(e) => setSetupData(prev => ({ ...prev, initGit: e.target.checked }))}
|
|
218
|
-
className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
219
|
-
/>
|
|
220
|
-
<span className="text-sm text-gray-700 dark:text-gray-300">Initialize Git repository</span>
|
|
221
|
-
</label>
|
|
222
|
-
|
|
223
|
-
<label className="flex items-center gap-3">
|
|
224
|
-
<input
|
|
225
|
-
type="checkbox"
|
|
226
|
-
checked={setupData.storeTasksInGit}
|
|
227
|
-
onChange={(e) => setSetupData(prev => ({ ...prev, storeTasksInGit: e.target.checked }))}
|
|
228
|
-
className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
229
|
-
/>
|
|
230
|
-
<span className="text-sm text-gray-700 dark:text-gray-300">Store tasks in Git</span>
|
|
231
|
-
</label>
|
|
232
|
-
|
|
233
|
-
<label className="flex items-center gap-3">
|
|
234
|
-
<input
|
|
235
|
-
type="checkbox"
|
|
236
|
-
checked={setupData.addAliases}
|
|
237
|
-
onChange={(e) => setSetupData(prev => ({ ...prev, addAliases: e.target.checked }))}
|
|
238
|
-
className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
239
|
-
/>
|
|
240
|
-
<span className="text-sm text-gray-700 dark:text-gray-300">Add shell aliases (tm, taskmaster)</span>
|
|
241
|
-
</label>
|
|
242
|
-
</div>
|
|
243
|
-
|
|
244
|
-
<div>
|
|
245
|
-
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
246
|
-
Rule Profiles
|
|
247
|
-
</label>
|
|
248
|
-
<div className="grid grid-cols-3 gap-2">
|
|
249
|
-
{['claude', 'cursor', 'vscode', 'roo', 'cline', 'windsurf'].map(rule => (
|
|
250
|
-
<label key={rule} className="flex items-center gap-2">
|
|
251
|
-
<input
|
|
252
|
-
type="checkbox"
|
|
253
|
-
checked={setupData.rules.includes(rule)}
|
|
254
|
-
onChange={(e) => {
|
|
255
|
-
if (e.target.checked) {
|
|
256
|
-
setSetupData(prev => ({ ...prev, rules: [...prev.rules, rule] }));
|
|
257
|
-
} else {
|
|
258
|
-
setSetupData(prev => ({ ...prev, rules: prev.rules.filter(r => r !== rule) }));
|
|
259
|
-
}
|
|
260
|
-
}}
|
|
261
|
-
className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
262
|
-
/>
|
|
263
|
-
<span className="text-sm text-gray-700 dark:text-gray-300 capitalize">{rule}</span>
|
|
264
|
-
</label>
|
|
265
|
-
))}
|
|
266
|
-
</div>
|
|
267
|
-
</div>
|
|
268
|
-
</div>
|
|
269
|
-
</div>
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
case 2:
|
|
273
|
-
return (
|
|
274
|
-
<div className="space-y-6">
|
|
275
|
-
<div className="text-center">
|
|
276
|
-
<Server className="w-12 h-12 text-purple-600 mx-auto mb-4" />
|
|
277
|
-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
|
278
|
-
MCP Server Setup
|
|
279
|
-
</h3>
|
|
280
|
-
<p className="text-gray-600 dark:text-gray-400">
|
|
281
|
-
TaskMaster works best with the MCP server configured
|
|
282
|
-
</p>
|
|
283
|
-
</div>
|
|
284
|
-
|
|
285
|
-
<div className="bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
|
|
286
|
-
<div className="flex items-start gap-3">
|
|
287
|
-
<AlertCircle className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5" />
|
|
288
|
-
<div>
|
|
289
|
-
<h4 className="font-medium text-blue-900 dark:text-blue-100 mb-1">
|
|
290
|
-
MCP Server Configuration
|
|
291
|
-
</h4>
|
|
292
|
-
<p className="text-sm text-blue-800 dark:text-blue-200 mb-3">
|
|
293
|
-
To enable full TaskMaster integration, add the MCP server configuration to your Claude settings.
|
|
294
|
-
</p>
|
|
295
|
-
|
|
296
|
-
<div className="bg-white dark:bg-gray-800 rounded border p-3 mb-3">
|
|
297
|
-
<div className="flex items-center justify-between mb-2">
|
|
298
|
-
<span className="text-sm font-mono text-gray-600 dark:text-gray-400">.mcp.json</span>
|
|
299
|
-
<button
|
|
300
|
-
onClick={copyMCPConfig}
|
|
301
|
-
className="flex items-center gap-1 px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors"
|
|
302
|
-
>
|
|
303
|
-
<Copy className="w-3 h-3" />
|
|
304
|
-
Copy
|
|
305
|
-
</button>
|
|
306
|
-
</div>
|
|
307
|
-
<pre className="text-xs text-gray-800 dark:text-gray-200 whitespace-pre-wrap">
|
|
308
|
-
{`{
|
|
309
|
-
"mcpServers": {
|
|
310
|
-
"task-master-ai": {
|
|
311
|
-
"command": "npx",
|
|
312
|
-
"args": ["-y", "--package=task-master-ai", "task-master-ai"],
|
|
313
|
-
"env": {
|
|
314
|
-
"ANTHROPIC_API_KEY": "your_anthropic_key_here",
|
|
315
|
-
"PERPLEXITY_API_KEY": "your_perplexity_key_here"
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}`}
|
|
320
|
-
</pre>
|
|
321
|
-
</div>
|
|
322
|
-
|
|
323
|
-
<div className="flex items-center gap-2 text-sm">
|
|
324
|
-
<a
|
|
325
|
-
href="https://docs.anthropic.com/en/docs/build-with-claude/tool-use/mcp-servers"
|
|
326
|
-
target="_blank"
|
|
327
|
-
rel="noopener noreferrer"
|
|
328
|
-
className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 flex items-center gap-1"
|
|
329
|
-
>
|
|
330
|
-
Learn about MCP setup
|
|
331
|
-
<ExternalLink className="w-3 h-3" />
|
|
332
|
-
</a>
|
|
333
|
-
</div>
|
|
334
|
-
</div>
|
|
335
|
-
</div>
|
|
336
|
-
</div>
|
|
337
|
-
|
|
338
|
-
<div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
|
|
339
|
-
<h4 className="font-medium text-gray-900 dark:text-white mb-2">Current Status</h4>
|
|
340
|
-
<div className="flex items-center gap-2">
|
|
341
|
-
{setupData.mcpConfigured ? (
|
|
342
|
-
<>
|
|
343
|
-
<CheckCircle className="w-4 h-4 text-green-500" />
|
|
344
|
-
<span className="text-sm text-green-700 dark:text-green-300">MCP server is configured</span>
|
|
345
|
-
</>
|
|
346
|
-
) : (
|
|
347
|
-
<>
|
|
348
|
-
<AlertCircle className="w-4 h-4 text-amber-500" />
|
|
349
|
-
<span className="text-sm text-amber-700 dark:text-amber-300">MCP server not detected (optional)</span>
|
|
350
|
-
</>
|
|
351
|
-
)}
|
|
352
|
-
</div>
|
|
353
|
-
</div>
|
|
354
|
-
</div>
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
case 3:
|
|
358
|
-
return (
|
|
359
|
-
<div className="space-y-6">
|
|
360
|
-
<div className="text-center">
|
|
361
|
-
<FileText className="w-12 h-12 text-green-600 mx-auto mb-4" />
|
|
362
|
-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
|
363
|
-
Product Requirements Document
|
|
364
|
-
</h3>
|
|
365
|
-
<p className="text-gray-600 dark:text-gray-400">
|
|
366
|
-
Create or import a PRD to generate initial tasks
|
|
367
|
-
</p>
|
|
368
|
-
</div>
|
|
369
|
-
|
|
370
|
-
<div className="space-y-4">
|
|
371
|
-
<div>
|
|
372
|
-
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
373
|
-
PRD Content
|
|
374
|
-
</label>
|
|
375
|
-
<textarea
|
|
376
|
-
value={setupData.prdContent}
|
|
377
|
-
onChange={(e) => setSetupData(prev => ({ ...prev, prdContent: e.target.value }))}
|
|
378
|
-
rows={12}
|
|
379
|
-
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white dark:bg-gray-800 text-gray-900 dark:text-white font-mono text-sm"
|
|
380
|
-
placeholder="# Product Requirements Document
|
|
381
|
-
|
|
382
|
-
## 1. Overview
|
|
383
|
-
Describe your project or feature...
|
|
384
|
-
|
|
385
|
-
## 2. Objectives
|
|
386
|
-
- Primary goal
|
|
387
|
-
- Success metrics
|
|
388
|
-
|
|
389
|
-
## 3. User Stories
|
|
390
|
-
- As a user, I want...
|
|
391
|
-
|
|
392
|
-
## 4. Requirements
|
|
393
|
-
- Feature requirements
|
|
394
|
-
- Technical requirements
|
|
395
|
-
|
|
396
|
-
## 5. Implementation Plan
|
|
397
|
-
- Phase 1: Core features
|
|
398
|
-
- Phase 2: Enhancements"
|
|
399
|
-
/>
|
|
400
|
-
</div>
|
|
401
|
-
|
|
402
|
-
<div className="bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
|
|
403
|
-
<div className="flex items-start gap-3">
|
|
404
|
-
<Sparkles className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5" />
|
|
405
|
-
<div>
|
|
406
|
-
<h4 className="font-medium text-blue-900 dark:text-blue-100 mb-1">
|
|
407
|
-
AI Task Generation
|
|
408
|
-
</h4>
|
|
409
|
-
<p className="text-sm text-blue-800 dark:text-blue-200">
|
|
410
|
-
TaskMaster will analyze your PRD and automatically generate a structured task list with dependencies, priorities, and implementation details.
|
|
411
|
-
</p>
|
|
412
|
-
</div>
|
|
413
|
-
</div>
|
|
414
|
-
</div>
|
|
415
|
-
</div>
|
|
416
|
-
</div>
|
|
417
|
-
);
|
|
418
|
-
|
|
419
|
-
case 4:
|
|
420
|
-
return (
|
|
421
|
-
<div className="space-y-6">
|
|
422
|
-
<div className="text-center">
|
|
423
|
-
<CheckCircle className="w-12 h-12 text-green-600 mx-auto mb-4" />
|
|
424
|
-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
|
425
|
-
Complete Setup
|
|
426
|
-
</h3>
|
|
427
|
-
<p className="text-gray-600 dark:text-gray-400">
|
|
428
|
-
Ready to initialize TaskMaster for your project
|
|
429
|
-
</p>
|
|
430
|
-
</div>
|
|
431
|
-
|
|
432
|
-
<div className="bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800 rounded-lg p-4">
|
|
433
|
-
<h4 className="font-medium text-green-900 dark:text-green-100 mb-3">
|
|
434
|
-
Setup Summary
|
|
435
|
-
</h4>
|
|
436
|
-
<ul className="space-y-2 text-sm text-green-800 dark:text-green-200">
|
|
437
|
-
<li className="flex items-center gap-2">
|
|
438
|
-
<CheckCircle className="w-4 h-4" />
|
|
439
|
-
Project: {setupData.projectRoot}
|
|
440
|
-
</li>
|
|
441
|
-
<li className="flex items-center gap-2">
|
|
442
|
-
<CheckCircle className="w-4 h-4" />
|
|
443
|
-
Rules: {setupData.rules.join(', ')}
|
|
444
|
-
</li>
|
|
445
|
-
{setupData.mcpConfigured && (
|
|
446
|
-
<li className="flex items-center gap-2">
|
|
447
|
-
<CheckCircle className="w-4 h-4" />
|
|
448
|
-
MCP server configured
|
|
449
|
-
</li>
|
|
450
|
-
)}
|
|
451
|
-
<li className="flex items-center gap-2">
|
|
452
|
-
<CheckCircle className="w-4 h-4" />
|
|
453
|
-
PRD content ready ({setupData.prdContent.length} characters)
|
|
454
|
-
</li>
|
|
455
|
-
</ul>
|
|
456
|
-
</div>
|
|
457
|
-
|
|
458
|
-
<div className="bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
|
|
459
|
-
<h4 className="font-medium text-blue-900 dark:text-blue-100 mb-2">
|
|
460
|
-
What happens next?
|
|
461
|
-
</h4>
|
|
462
|
-
<ol className="list-decimal list-inside space-y-1 text-sm text-blue-800 dark:text-blue-200">
|
|
463
|
-
<li>Initialize TaskMaster project structure</li>
|
|
464
|
-
<li>Save your PRD to <code>.taskmaster/docs/prd.txt</code></li>
|
|
465
|
-
<li>Generate initial tasks from your PRD</li>
|
|
466
|
-
<li>Set up project configuration and rules</li>
|
|
467
|
-
</ol>
|
|
468
|
-
</div>
|
|
469
|
-
</div>
|
|
470
|
-
);
|
|
471
|
-
|
|
472
|
-
default:
|
|
473
|
-
return null;
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
|
|
477
|
-
if (!isOpen) return null;
|
|
478
|
-
|
|
479
|
-
return (
|
|
480
|
-
<div className="modal-backdrop fixed inset-0 flex items-center justify-center z-[100] md:p-4 bg-black/50">
|
|
481
|
-
<div className={cn(
|
|
482
|
-
'bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 md:rounded-lg shadow-xl',
|
|
483
|
-
'w-full md:max-w-4xl h-full md:h-[90vh] flex flex-col',
|
|
484
|
-
className
|
|
485
|
-
)}>
|
|
486
|
-
{/* Header */}
|
|
487
|
-
<div className="flex items-center justify-between p-4 md:p-6 border-b border-gray-200 dark:border-gray-700 flex-shrink-0">
|
|
488
|
-
<div className="flex items-center gap-3">
|
|
489
|
-
<Sparkles className="w-6 h-6 text-blue-600" />
|
|
490
|
-
<div>
|
|
491
|
-
<h1 className="text-xl font-semibold text-gray-900 dark:text-white">
|
|
492
|
-
TaskMaster Setup Wizard
|
|
493
|
-
</h1>
|
|
494
|
-
<p className="text-sm text-gray-600 dark:text-gray-400">
|
|
495
|
-
Step {currentStep} of {totalSteps}: {steps[currentStep - 1]?.description}
|
|
496
|
-
</p>
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
499
|
-
|
|
500
|
-
<button
|
|
501
|
-
onClick={onClose}
|
|
502
|
-
className="p-2 text-gray-500 hover:text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-md transition-colors"
|
|
503
|
-
title="Close"
|
|
504
|
-
>
|
|
505
|
-
<X className="w-5 h-5" />
|
|
506
|
-
</button>
|
|
507
|
-
</div>
|
|
508
|
-
|
|
509
|
-
{/* Progress Bar */}
|
|
510
|
-
<div className="px-4 md:px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
|
511
|
-
<div className="flex items-center justify-between mb-2">
|
|
512
|
-
{steps.map((step, index) => (
|
|
513
|
-
<div key={step.id} className="flex items-center">
|
|
514
|
-
<div className={cn(
|
|
515
|
-
'w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium transition-colors',
|
|
516
|
-
currentStep > step.id
|
|
517
|
-
? 'bg-green-500 text-white'
|
|
518
|
-
: currentStep === step.id
|
|
519
|
-
? 'bg-blue-500 text-white'
|
|
520
|
-
: 'bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-400'
|
|
521
|
-
)}>
|
|
522
|
-
{currentStep > step.id ? (
|
|
523
|
-
<CheckCircle className="w-4 h-4" />
|
|
524
|
-
) : (
|
|
525
|
-
step.id
|
|
526
|
-
)}
|
|
527
|
-
</div>
|
|
528
|
-
{index < steps.length - 1 && (
|
|
529
|
-
<div className={cn(
|
|
530
|
-
'w-16 h-1 mx-2 rounded',
|
|
531
|
-
currentStep > step.id
|
|
532
|
-
? 'bg-green-500'
|
|
533
|
-
: 'bg-gray-200 dark:bg-gray-700'
|
|
534
|
-
)} />
|
|
535
|
-
)}
|
|
536
|
-
</div>
|
|
537
|
-
))}
|
|
538
|
-
</div>
|
|
539
|
-
<div className="flex justify-between text-xs text-gray-600 dark:text-gray-400">
|
|
540
|
-
{steps.map(step => (
|
|
541
|
-
<span key={step.id} className="text-center">
|
|
542
|
-
{step.title}
|
|
543
|
-
</span>
|
|
544
|
-
))}
|
|
545
|
-
</div>
|
|
546
|
-
</div>
|
|
547
|
-
|
|
548
|
-
{/* Content */}
|
|
549
|
-
<div className="flex-1 overflow-y-auto p-4 md:p-6">
|
|
550
|
-
{renderStepContent()}
|
|
551
|
-
|
|
552
|
-
{error && (
|
|
553
|
-
<div className="mt-4 bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800 rounded-lg p-4">
|
|
554
|
-
<div className="flex items-start gap-3">
|
|
555
|
-
<AlertCircle className="w-5 h-5 text-red-600 dark:text-red-400 mt-0.5" />
|
|
556
|
-
<div>
|
|
557
|
-
<h4 className="font-medium text-red-900 dark:text-red-100 mb-1">Error</h4>
|
|
558
|
-
<p className="text-sm text-red-800 dark:text-red-200">{error}</p>
|
|
559
|
-
</div>
|
|
560
|
-
</div>
|
|
561
|
-
</div>
|
|
562
|
-
)}
|
|
563
|
-
</div>
|
|
564
|
-
|
|
565
|
-
{/* Footer */}
|
|
566
|
-
<div className="flex items-center justify-between p-4 md:p-6 border-t border-gray-200 dark:border-gray-700 flex-shrink-0">
|
|
567
|
-
<button
|
|
568
|
-
onClick={handlePrevious}
|
|
569
|
-
disabled={currentStep === 1}
|
|
570
|
-
className="flex items-center gap-2 px-4 py-2 text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
|
571
|
-
>
|
|
572
|
-
<ChevronLeft className="w-4 h-4" />
|
|
573
|
-
Previous
|
|
574
|
-
</button>
|
|
575
|
-
|
|
576
|
-
<div className="text-sm text-gray-500 dark:text-gray-400">
|
|
577
|
-
{currentStep} of {totalSteps}
|
|
578
|
-
</div>
|
|
579
|
-
|
|
580
|
-
<button
|
|
581
|
-
onClick={handleNext}
|
|
582
|
-
disabled={loading}
|
|
583
|
-
className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
|
584
|
-
>
|
|
585
|
-
{loading ? (
|
|
586
|
-
<>
|
|
587
|
-
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
|
|
588
|
-
{currentStep === totalSteps ? 'Setting up...' : 'Processing...'}
|
|
589
|
-
</>
|
|
590
|
-
) : (
|
|
591
|
-
<>
|
|
592
|
-
{currentStep === totalSteps ? 'Complete Setup' : 'Next'}
|
|
593
|
-
<ChevronRight className="w-4 h-4" />
|
|
594
|
-
</>
|
|
595
|
-
)}
|
|
596
|
-
</button>
|
|
597
|
-
</div>
|
|
598
|
-
</div>
|
|
599
|
-
</div>
|
|
600
|
-
);
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
export default TaskMasterSetupWizard;
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useTaskMaster } from '../contexts/TaskMasterContext';
|
|
3
|
-
import TaskIndicator from './TaskIndicator';
|
|
4
|
-
|
|
5
|
-
const TaskMasterStatus = () => {
|
|
6
|
-
const {
|
|
7
|
-
currentProject,
|
|
8
|
-
projectTaskMaster,
|
|
9
|
-
mcpServerStatus,
|
|
10
|
-
isLoading,
|
|
11
|
-
isLoadingMCP,
|
|
12
|
-
error
|
|
13
|
-
} = useTaskMaster();
|
|
14
|
-
|
|
15
|
-
if (isLoading || isLoadingMCP) {
|
|
16
|
-
return (
|
|
17
|
-
<div className="flex items-center text-sm text-gray-500 dark:text-gray-400">
|
|
18
|
-
<div className="animate-spin w-3 h-3 border border-gray-300 border-t-blue-500 rounded-full mr-2"></div>
|
|
19
|
-
Loading TaskMaster status...
|
|
20
|
-
</div>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (error) {
|
|
25
|
-
return (
|
|
26
|
-
<div className="flex items-center text-sm text-red-500 dark:text-red-400">
|
|
27
|
-
<span className="w-2 h-2 bg-red-500 rounded-full mr-2"></span>
|
|
28
|
-
TaskMaster Error
|
|
29
|
-
</div>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Show MCP server status
|
|
34
|
-
const mcpConfigured = mcpServerStatus?.hasMCPServer && mcpServerStatus?.isConfigured;
|
|
35
|
-
|
|
36
|
-
// Show project TaskMaster status
|
|
37
|
-
const projectConfigured = currentProject?.taskmaster?.hasTaskmaster;
|
|
38
|
-
const taskCount = currentProject?.taskmaster?.metadata?.taskCount || 0;
|
|
39
|
-
const completedCount = currentProject?.taskmaster?.metadata?.completed || 0;
|
|
40
|
-
|
|
41
|
-
if (!currentProject) {
|
|
42
|
-
return (
|
|
43
|
-
<div className="flex items-center text-sm text-gray-500 dark:text-gray-400">
|
|
44
|
-
<span className="w-2 h-2 bg-gray-400 rounded-full mr-2"></span>
|
|
45
|
-
No project selected
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Determine overall status for TaskIndicator
|
|
51
|
-
let overallStatus = 'not-configured';
|
|
52
|
-
if (projectConfigured && mcpConfigured) {
|
|
53
|
-
overallStatus = 'fully-configured';
|
|
54
|
-
} else if (projectConfigured) {
|
|
55
|
-
overallStatus = 'taskmaster-only';
|
|
56
|
-
} else if (mcpConfigured) {
|
|
57
|
-
overallStatus = 'mcp-only';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<div className="flex items-center gap-3">
|
|
62
|
-
{/* TaskMaster Status Indicator */}
|
|
63
|
-
<TaskIndicator
|
|
64
|
-
status={overallStatus}
|
|
65
|
-
size="md"
|
|
66
|
-
showLabel={true}
|
|
67
|
-
/>
|
|
68
|
-
|
|
69
|
-
{/* Task Progress Info */}
|
|
70
|
-
{projectConfigured && (
|
|
71
|
-
<div className="text-xs text-gray-600 dark:text-gray-400">
|
|
72
|
-
<span className="font-medium">
|
|
73
|
-
{completedCount}/{taskCount} tasks
|
|
74
|
-
</span>
|
|
75
|
-
{taskCount > 0 && (
|
|
76
|
-
<span className="ml-2 opacity-75">
|
|
77
|
-
({Math.round((completedCount / taskCount) * 100)}%)
|
|
78
|
-
</span>
|
|
79
|
-
)}
|
|
80
|
-
</div>
|
|
81
|
-
)}
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export default TaskMasterStatus;
|