@programinglive/dev-workflow-mcp-server 1.3.12 → 1.4.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/.github/workflows/npm-publish.yml +3 -0
- package/CHANGELOG.md +108 -0
- package/README.md +1 -1
- package/docs/PLESK_DEPLOYMENT.md +170 -0
- package/docs/WORKFLOW-BEST-PRACTICES.md +14 -0
- package/docs/release-notes/RELEASE_NOTES.md +26 -0
- package/package.json +7 -6
- package/release-wrapper.js +68 -33
- package/tests/build.test.js +3 -3
- package/tests/handlers.test.js +78 -0
- package/tests/release-wrapper.test.js +2 -0
- package/tests/workflowState.test.js +7 -4
- package/tools/definitions.js +2 -2
- package/tools/handlers.js +2 -2
- package/vite.web.config.js +23 -0
- package/web/README.md +36 -0
- package/web/app/api/docs/route.ts +32 -0
- package/web/app/api/history/route.ts +19 -0
- package/web/app/api/npm-downloads/route.ts +21 -0
- package/web/app/api/summary/route.ts +15 -0
- package/web/app/api/version/route.ts +15 -0
- package/web/app/docs/page.tsx +202 -0
- package/web/app/favicon.ico +0 -0
- package/web/app/globals.css +91 -0
- package/web/app/layout.tsx +36 -0
- package/web/app/page.tsx +15 -0
- package/web/components/ApiReference.tsx +20 -0
- package/web/components/Features.tsx +61 -0
- package/web/components/Footer.tsx +9 -0
- package/web/components/Hero.tsx +91 -0
- package/web/components/History.tsx +143 -0
- package/web/components/Navbar.tsx +64 -0
- package/web/components/Terminal.tsx +114 -0
- package/web/eslint.config.mjs +18 -0
- package/web/lib/db.js +131 -0
- package/web/lib/docs.js +73 -0
- package/web/next.config.ts +8 -0
- package/web/package-lock.json +6971 -0
- package/web/package.json +29 -0
- package/web/postcss.config.mjs +9 -0
- package/web/public/assets/android-chrome-192x192.png +0 -0
- package/web/public/assets/android-chrome-512x512.png +0 -0
- package/web/public/assets/apple-touch-icon.png +0 -0
- package/web/public/assets/favicon-16x16.png +0 -0
- package/web/public/assets/favicon-32x32.png +0 -0
- package/web/public/assets/favicon.ico +0 -0
- package/web/public/assets/favicon.png +0 -0
- package/web/public/assets/logo.png +0 -0
- package/web/public/assets/og-preview.png +0 -0
- package/web/public/assets/site.webmanifest +1 -0
- package/web/public/file.svg +1 -0
- package/web/public/globe.svg +1 -0
- package/web/public/next.svg +1 -0
- package/web/public/vercel.svg +1 -0
- package/web/public/window.svg +1 -0
- package/web/server.js +30 -158
- package/web/tailwind.config.ts +19 -0
- package/web/tsconfig.json +42 -0
- package/web-legacy/public/assets/android-chrome-192x192.png +0 -0
- package/web-legacy/public/assets/android-chrome-512x512.png +0 -0
- package/web-legacy/public/assets/apple-touch-icon.png +0 -0
- package/web-legacy/public/assets/favicon-16x16.png +0 -0
- package/web-legacy/public/assets/favicon-32x32.png +0 -0
- package/web-legacy/public/assets/favicon.ico +0 -0
- package/web-legacy/public/assets/favicon.png +0 -0
- package/web-legacy/public/assets/logo.png +0 -0
- package/web-legacy/public/assets/og-preview.png +0 -0
- package/web-legacy/public/assets/site.webmanifest +1 -0
- package/{dist → web-legacy/public}/docs/EXAMPLES.html +87 -2
- package/{dist → web-legacy/public}/docs/GETTING-STARTED.html +87 -2
- package/{dist → web-legacy/public}/docs/README.html +87 -2
- package/{dist → web-legacy/public}/docs/RELEASE_NOTES.html +92 -2
- package/{dist → web-legacy/public}/docs/TROUBLESHOOTING.html +87 -2
- package/{dist → web-legacy/public}/docs/WORKFLOW-TEMPLATES.html +87 -2
- package/{dist → web-legacy/public}/docs/web-dashboard.html +87 -2
- package/web-legacy/public/index.html +223 -0
- package/web-legacy/public/input.css +80 -0
- package/web-legacy/public/main.js +167 -0
- package/web-legacy/public/output.css +1559 -0
- package/web-legacy/server.js +207 -0
- package/workflow-state.js +11 -25
- package/web/public/index.html +0 -1046
- package/web/public/input.css +0 -3
- package/web/public/output.css +0 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<div class="flex items-center gap-2">
|
|
4
|
+
<img src="/assets/logo.png" alt="Dev Workflow" class="w-8 h-8 rounded-lg">
|
|
5
|
+
<span class="text-lg font-bold">Dev Workflow</span>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="hidden md:flex items-center gap-6">
|
|
8
|
+
<a href="#features" class="text-gray-300 hover:text-white transition">Features</a>
|
|
9
|
+
<a href="#history" class="text-gray-300 hover:text-white transition">History</a>
|
|
10
|
+
<a href="#api" class="text-gray-300 hover:text-white transition">API</a>
|
|
11
|
+
<a href="docs.html?doc=README.md" class="text-gray-300 hover:text-white transition">Docs</a>
|
|
12
|
+
<a href="https://github.com/programinglive/dev-workflow-mcp-server" target="_blank"
|
|
13
|
+
class="flex items-center gap-2 px-4 py-2 bg-white/5 hover:bg-white/10 rounded-lg transition">
|
|
14
|
+
<i data-lucide="github" class="w-4 h-4"></i>
|
|
15
|
+
GitHub
|
|
16
|
+
</a>
|
|
17
|
+
</div>
|
|
18
|
+
<button id="mobileMenuBtn" class="md:hidden p-2 rounded-lg hover:bg-white/5">
|
|
19
|
+
<i data-lucide="menu" class="w-6 h-6"></i>
|
|
20
|
+
</button>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
<!-- Mobile Menu -->
|
|
24
|
+
<div id="mobileMenu" class="hidden border-t border-white/10 bg-[#0a0a0f]">
|
|
25
|
+
<div class="px-4 py-4 space-y-3">
|
|
26
|
+
<a href="#features" class="block text-gray-300 hover:text-white transition">Features</a>
|
|
27
|
+
<a href="#history" class="block text-gray-300 hover:text-white transition">History</a>
|
|
28
|
+
<a href="#api" class="block text-gray-300 hover:text-white transition">API</a>
|
|
29
|
+
<a href="docs.html?doc=README.md" class="block text-gray-300 hover:text-white transition">Docs</a>
|
|
30
|
+
<a href="https://github.com/programinglive/dev-workflow-mcp-server" target="_blank"
|
|
31
|
+
class="flex items-center gap-2 text-gray-300 hover:text-white transition">
|
|
32
|
+
<i data-lucide="github" class="w-4 h-4"></i>
|
|
33
|
+
GitHub
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</nav>
|
|
38
|
+
|
|
39
|
+
<!-- Hero Section -->
|
|
40
|
+
<section class="min-h-screen flex items-center justify-center px-4 pt-16 relative overflow-hidden">
|
|
41
|
+
<div class="absolute inset-0 bg-gradient-to-br from-indigo-500/10 via-purple-500/10 to-pink-500/10"></div>
|
|
42
|
+
<div class="max-w-7xl mx-auto grid lg:grid-cols-2 gap-12 items-center relative z-10">
|
|
43
|
+
<!-- Left Column - Content -->
|
|
44
|
+
<div>
|
|
45
|
+
<div class="animate-fade-in-up" style="animation-delay: 0.1s;">
|
|
46
|
+
<div
|
|
47
|
+
class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-emerald-400 text-sm mb-8">
|
|
48
|
+
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
|
49
|
+
<span id="versionBadge">v1.3.12 - Active</span>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<h1 class="text-5xl md:text-6xl lg:text-7xl font-bold mb-6 leading-tight animate-fade-in-up"
|
|
54
|
+
style="animation-delay: 0.2s;">
|
|
55
|
+
Master Your<br><span
|
|
56
|
+
class="bg-gradient-to-r from-indigo-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">Workflow</span>
|
|
57
|
+
</h1>
|
|
58
|
+
<p class="text-lg md:text-xl text-gray-400 mb-8 max-w-xl animate-fade-in-up" style="animation-delay: 0.3s;">
|
|
59
|
+
An MCP server that acts as your coding conscience. Enforce test-driven development, ensure documentation, and
|
|
60
|
+
never skip a step in your release process.
|
|
61
|
+
</p>
|
|
62
|
+
<div class="flex flex-col sm:flex-row gap-4 mb-8 animate-fade-in-up" style="animation-delay: 0.4s;">
|
|
63
|
+
<a href="#history"
|
|
64
|
+
class="px-6 py-3 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg font-semibold hover:shadow-lg hover:shadow-indigo-500/50 transition inline-flex items-center justify-center gap-2">
|
|
65
|
+
View History <i data-lucide="arrow-right" class="w-4 h-4"></i>
|
|
66
|
+
</a>
|
|
67
|
+
<a href="docs.html?doc=README.md"
|
|
68
|
+
class="px-6 py-3 bg-white/5 border border-white/10 rounded-lg font-semibold hover:bg-white/10 transition text-center">
|
|
69
|
+
Documentation
|
|
70
|
+
</a>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="flex items-center gap-8 text-sm animate-fade-in-up" style="animation-delay: 0.5s;">
|
|
73
|
+
<div>
|
|
74
|
+
<div class="text-2xl font-bold" id="versionNum">1.3.12</div>
|
|
75
|
+
<div class="text-gray-500">Latest Version</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div>
|
|
78
|
+
<div class="text-2xl font-bold">MIT</div>
|
|
79
|
+
<div class="text-gray-500">License</div>
|
|
80
|
+
</div>
|
|
81
|
+
<div>
|
|
82
|
+
<div class="text-2xl font-bold">Node 18+</div>
|
|
83
|
+
<div class="text-gray-500">Compatibility</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
<!-- Right Column - Terminal -->
|
|
88
|
+
<div class="hidden lg:block">
|
|
89
|
+
<div class="relative">
|
|
90
|
+
<div class="absolute inset-0 bg-gradient-to-r from-indigo-500/20 to-purple-500/20 blur-3xl"></div>
|
|
91
|
+
<div class="relative bg-[#1a1a24] rounded-xl border border-white/10 p-6 shadow-2xl">
|
|
92
|
+
<div class="flex items-center gap-2 mb-4">
|
|
93
|
+
<div class="w-3 h-3 rounded-full bg-red-500"></div>
|
|
94
|
+
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
|
|
95
|
+
<div class="w-3 h-3 rounded-full bg-green-500"></div>
|
|
96
|
+
<span class="ml-auto text-xs text-gray-500">terminal</span>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="font-mono text-sm space-y-2" id="terminalContent">
|
|
99
|
+
<!-- Content will be generated by JS -->
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</section>
|
|
106
|
+
|
|
107
|
+
<!-- Features Section -->
|
|
108
|
+
<section id="features" class="py-20 px-4">
|
|
109
|
+
<div class="max-w-7xl mx-auto">
|
|
110
|
+
<h2 class="text-3xl md:text-4xl font-bold text-center mb-16">Your Coding Conscience</h2>
|
|
111
|
+
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
112
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 transition">
|
|
113
|
+
<div class="w-12 h-12 rounded-lg bg-indigo-500/20 flex items-center justify-center mb-4">
|
|
114
|
+
<i data-lucide="shield-check" class="w-6 h-6 text-indigo-400"></i>
|
|
115
|
+
</div>
|
|
116
|
+
<h3 class="text-xl font-semibold mb-2">Enforced Discipline</h3>
|
|
117
|
+
<p class="text-gray-400">Won't let you skip important steps. Follows a strict, proven development workflow.
|
|
118
|
+
</p>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 transition">
|
|
121
|
+
<div class="w-12 h-12 rounded-lg bg-purple-500/20 flex items-center justify-center mb-4">
|
|
122
|
+
<i data-lucide="test-tube" class="w-6 h-6 text-purple-400"></i>
|
|
123
|
+
</div>
|
|
124
|
+
<h3 class="text-xl font-semibold mb-2">Test-Driven</h3>
|
|
125
|
+
<p class="text-gray-400">Blocks commits if tests fail. Encourages writing tests before marking tasks complete.
|
|
126
|
+
</p>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 transition">
|
|
129
|
+
<div class="w-12 h-12 rounded-lg bg-emerald-500/20 flex items-center justify-center mb-4">
|
|
130
|
+
<i data-lucide="file-text" class="w-6 h-6 text-emerald-400"></i>
|
|
131
|
+
</div>
|
|
132
|
+
<h3 class="text-xl font-semibold mb-2">Documentation</h3>
|
|
133
|
+
<p class="text-gray-400">Reminds you to update documentation (README, docs, changelog) for every change.</p>
|
|
134
|
+
</div>
|
|
135
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 transition">
|
|
136
|
+
<div class="w-12 h-12 rounded-lg bg-orange-500/20 flex items-center justify-center mb-4">
|
|
137
|
+
<i data-lucide="git-branch" class="w-6 h-6 text-orange-400"></i>
|
|
138
|
+
</div>
|
|
139
|
+
<h3 class="text-xl font-semibold mb-2">State Tracking</h3>
|
|
140
|
+
<p class="text-gray-400">Remembers exactly where you are in the workflow, even across sessions.</p>
|
|
141
|
+
</div>
|
|
142
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 transition">
|
|
143
|
+
<div class="w-12 h-12 rounded-lg bg-blue-500/20 flex items-center justify-center mb-4">
|
|
144
|
+
<i data-lucide="history" class="w-6 h-6 text-blue-400"></i>
|
|
145
|
+
</div>
|
|
146
|
+
<h3 class="text-xl font-semibold mb-2">Task History</h3>
|
|
147
|
+
<p class="text-gray-400">Keeps a detailed log of all completed tasks, commits, and releases.</p>
|
|
148
|
+
</div>
|
|
149
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10 hover:bg-white/10 transition">
|
|
150
|
+
<div class="w-12 h-12 rounded-lg bg-pink-500/20 flex items-center justify-center mb-4">
|
|
151
|
+
<i data-lucide="zap" class="w-6 h-6 text-pink-400"></i>
|
|
152
|
+
</div>
|
|
153
|
+
<h3 class="text-xl font-semibold mb-2">Smart Prompts</h3>
|
|
154
|
+
<p class="text-gray-400">Provides quick reminders and guidance on best practices as you work.</p>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</section>
|
|
159
|
+
|
|
160
|
+
<!-- History Section -->
|
|
161
|
+
<section id="history" class="py-20 px-4 bg-white/5">
|
|
162
|
+
<div class="max-w-7xl mx-auto">
|
|
163
|
+
<h2 class="text-3xl md:text-4xl font-bold mb-8">Workflow History</h2>
|
|
164
|
+
<p class="text-gray-400 mb-12">Track your development progress and analyze your workflow patterns.</p>
|
|
165
|
+
<div class="bg-[#0a0a0f] rounded-xl border border-white/10 p-6">
|
|
166
|
+
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4 mb-6">
|
|
167
|
+
<input type="text" id="userId" placeholder="User ID"
|
|
168
|
+
class="px-4 py-2 bg-white/5 border border-white/10 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 text-white">
|
|
169
|
+
<input type="date" id="startDate"
|
|
170
|
+
class="px-4 py-2 bg-white/5 border border-white/10 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 [color-scheme:dark]">
|
|
171
|
+
<input type="date" id="endDate"
|
|
172
|
+
class="px-4 py-2 bg-white/5 border border-white/10 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 [color-scheme:dark]">
|
|
173
|
+
<button id="applyFiltersBtn"
|
|
174
|
+
class="px-4 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg font-semibold hover:shadow-lg hover:shadow-indigo-500/50 transition">Apply
|
|
175
|
+
Filters</button>
|
|
176
|
+
</div>
|
|
177
|
+
<div id="summarySection" class="hidden mb-6">
|
|
178
|
+
<h3 class="text-lg font-semibold mb-4">Project Summary</h3>
|
|
179
|
+
<div id="summaryContent" class="text-gray-400"></div>
|
|
180
|
+
</div>
|
|
181
|
+
<div id="historySection" class="hidden">
|
|
182
|
+
<h3 class="text-lg font-semibold mb-4">Recent History</h3>
|
|
183
|
+
<div id="historyContent" class="space-y-3"></div>
|
|
184
|
+
<div id="paginationControls" class="flex items-center justify-between mt-6 hidden">
|
|
185
|
+
<button id="prevPageBtn"
|
|
186
|
+
class="px-4 py-2 bg-white/5 border border-white/10 rounded-lg hover:bg-white/10 disabled:opacity-50">Previous</button>
|
|
187
|
+
<span id="pageInfo" class="text-sm text-gray-400"></span>
|
|
188
|
+
<button id="nextPageBtn"
|
|
189
|
+
class="px-4 py-2 bg-white/5 border border-white/10 rounded-lg hover:bg-white/10 disabled:opacity-50">Next</button>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</section>
|
|
195
|
+
|
|
196
|
+
<!-- API Section -->
|
|
197
|
+
<section id="api" class="py-20 px-4">
|
|
198
|
+
<div class="max-w-7xl mx-auto">
|
|
199
|
+
<h2 class="text-3xl md:text-4xl font-bold mb-8">API Reference</h2>
|
|
200
|
+
<p class="text-gray-400 mb-12">Query workflow data programmatically with our JSON API.</p>
|
|
201
|
+
<div class="grid md:grid-cols-2 gap-6">
|
|
202
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10">
|
|
203
|
+
<code class="text-indigo-400 font-mono text-sm">GET /api/history</code>
|
|
204
|
+
<p class="text-gray-400 mt-2">Retrieve paginated task history entries.</p>
|
|
205
|
+
</div>
|
|
206
|
+
<div class="p-6 rounded-xl bg-white/5 border border-white/10">
|
|
207
|
+
<code class="text-indigo-400 font-mono text-sm">GET /api/summary</code>
|
|
208
|
+
<p class="text-gray-400 mt-2">Get project health stats and recent tasks.</p>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</section>
|
|
213
|
+
|
|
214
|
+
<!-- Footer -->
|
|
215
|
+
<footer class="py-12 px-4 border-t border-white/10">
|
|
216
|
+
<div class="max-w-7xl mx-auto text-center text-gray-400">
|
|
217
|
+
<p>Built with ❤️ for developers who care about quality</p>
|
|
218
|
+
</div>
|
|
219
|
+
</footer>
|
|
220
|
+
<script src="/main.js"></script>
|
|
221
|
+
</body>
|
|
222
|
+
|
|
223
|
+
</html>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
@layer utilities {
|
|
6
|
+
@keyframes fadeInUp {
|
|
7
|
+
0% {
|
|
8
|
+
opacity: 0;
|
|
9
|
+
transform: translateY(20px);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
100% {
|
|
13
|
+
opacity: 1;
|
|
14
|
+
transform: translateY(0px);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@keyframes fadeInRight {
|
|
19
|
+
0% {
|
|
20
|
+
opacity: 0;
|
|
21
|
+
transform: translateY(-50%) translateX(40px);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
100% {
|
|
25
|
+
opacity: 1;
|
|
26
|
+
transform: translateY(-50%) translateX(0px);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@keyframes fadeIn {
|
|
31
|
+
0% {
|
|
32
|
+
opacity: 0;
|
|
33
|
+
transform: translateX(-10px);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
100% {
|
|
37
|
+
opacity: 1;
|
|
38
|
+
transform: translateX(0px);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.animate-fade-in-up {
|
|
43
|
+
animation: fadeInUp 0.8s ease-out forwards;
|
|
44
|
+
opacity: 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.animate-fade-in-right {
|
|
48
|
+
animation: fadeInRight 0.8s ease-out forwards;
|
|
49
|
+
opacity: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.terminal-line {
|
|
53
|
+
opacity: 0;
|
|
54
|
+
display: flex;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.terminal-line.visible {
|
|
58
|
+
opacity: 1;
|
|
59
|
+
transition: opacity 0.1s;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.typing-cursor::after {
|
|
63
|
+
content: '▋';
|
|
64
|
+
animation: blink 1s step-end infinite;
|
|
65
|
+
margin-left: 4px;
|
|
66
|
+
color: #a855f7;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@keyframes blink {
|
|
70
|
+
|
|
71
|
+
0%,
|
|
72
|
+
100% {
|
|
73
|
+
opacity: 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
50% {
|
|
77
|
+
opacity: 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
|
|
2
|
+
const state = {
|
|
3
|
+
userId: "", startDate: "", endDate: "", page: 1, pageSize: 20, totalPages: 1
|
|
4
|
+
};
|
|
5
|
+
const el = (id) => document.getElementById(id);
|
|
6
|
+
|
|
7
|
+
async function load() {
|
|
8
|
+
const params = new URLSearchParams();
|
|
9
|
+
if (state.userId) params.append("user", state.userId);
|
|
10
|
+
if (state.startDate) params.append("startDate", state.startDate);
|
|
11
|
+
if (state.endDate) params.append("endDate", state.endDate);
|
|
12
|
+
params.append("page", state.page);
|
|
13
|
+
params.append("pageSize", state.pageSize);
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const res = await fetch(`/api/history?${params}`);
|
|
17
|
+
const data = await res.json();
|
|
18
|
+
state.totalPages = data.totalPages;
|
|
19
|
+
|
|
20
|
+
el("historySection").classList.remove("hidden");
|
|
21
|
+
el("summarySection").classList.remove("hidden");
|
|
22
|
+
el("paginationControls").classList.remove("hidden");
|
|
23
|
+
|
|
24
|
+
el("pageInfo").textContent = `Page ${data.page} of ${data.totalPages}`;
|
|
25
|
+
|
|
26
|
+
el("historyContent").innerHTML = (data.data || []).map(row => `
|
|
27
|
+
<div class="p-4 rounded-lg bg-white/5 border border-white/10">
|
|
28
|
+
<div class="font-semibold">${row.task_description}</div>
|
|
29
|
+
<div class="text-sm text-gray-400 mt-1">${new Date(row.created_at).toLocaleString()}</div>
|
|
30
|
+
</div>
|
|
31
|
+
`).join('') || '<p class="text-gray-500">No history yet.</p>';
|
|
32
|
+
|
|
33
|
+
el("prevPageBtn").disabled = data.page <= 1;
|
|
34
|
+
el("nextPageBtn").disabled = data.page >= data.totalPages;
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.error(err);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const summaryRes = await fetch(`/api/summary?${params}`);
|
|
41
|
+
const summary = await summaryRes.json();
|
|
42
|
+
el("summaryContent").innerHTML = `<p>Total tasks: ${summary.summary?.totalTasks || 0}</p>`;
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error(err);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
el("applyFiltersBtn").addEventListener("click", () => {
|
|
49
|
+
state.userId = el("userId").value;
|
|
50
|
+
state.startDate = el("startDate").value;
|
|
51
|
+
state.endDate = el("endDate").value;
|
|
52
|
+
state.page = 1;
|
|
53
|
+
load();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
el("prevPageBtn").addEventListener("click", () => {
|
|
57
|
+
if (state.page > 1) {
|
|
58
|
+
state.page--;
|
|
59
|
+
load();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
el("nextPageBtn").addEventListener("click", () => {
|
|
64
|
+
if (state.page < state.totalPages) {
|
|
65
|
+
state.page++;
|
|
66
|
+
load();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Terminal Animation
|
|
71
|
+
const terminalLines = [
|
|
72
|
+
{ type: 'command', text: 'start_task', delay: 500 },
|
|
73
|
+
{ type: 'success', text: '✓ Task started: Implement user auth', delay: 1500 },
|
|
74
|
+
{ type: 'comment', text: '# Write code...', delay: 2500 },
|
|
75
|
+
{ type: 'command', text: 'mark_bug_fixed', delay: 4000 },
|
|
76
|
+
{ type: 'info', text: '✨ Feature complete! Now create tests...', delay: 5000 },
|
|
77
|
+
{ type: 'command', text: 'create_tests', delay: 6500 },
|
|
78
|
+
{ type: 'success', text: '✓ Tests created', delay: 7500 },
|
|
79
|
+
{ type: 'command', text: 'run_tests', delay: 8500 },
|
|
80
|
+
{ type: 'success', text: '✓ All tests passed!', delay: 9500 },
|
|
81
|
+
{ type: 'command', text: 'create_documentation', delay: 10500 },
|
|
82
|
+
{ type: 'success', text: '✓ Documentation updated', delay: 11500 },
|
|
83
|
+
{ type: 'command', text: 'commit_and_push', delay: 12500 },
|
|
84
|
+
{ type: 'final', text: 'Ready to release!', delay: 13500 }
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const terminalContent = document.getElementById('terminalContent');
|
|
88
|
+
|
|
89
|
+
function createLine(line) {
|
|
90
|
+
const div = document.createElement('div');
|
|
91
|
+
div.className = 'terminal-line';
|
|
92
|
+
|
|
93
|
+
if (line.type === 'command') {
|
|
94
|
+
div.innerHTML = `<span class="text-gray-500 mr-2">$</span><span class="text-white typing-cursor">${line.text}</span>`;
|
|
95
|
+
} else if (line.type === 'success') {
|
|
96
|
+
div.className += ' text-emerald-400';
|
|
97
|
+
div.textContent = line.text;
|
|
98
|
+
} else if (line.type === 'comment') {
|
|
99
|
+
div.innerHTML = `<span class="text-gray-500 mr-2">$</span><span class="text-white">${line.text}</span>`;
|
|
100
|
+
div.classList.add('mt-3');
|
|
101
|
+
} else if (line.type === 'info') {
|
|
102
|
+
div.className += ' text-purple-400';
|
|
103
|
+
div.textContent = line.text;
|
|
104
|
+
} else if (line.type === 'final') {
|
|
105
|
+
div.className += ' text-pink-400 flex items-center gap-2';
|
|
106
|
+
div.innerHTML = `<i data-lucide="rocket" class="w-4 h-4"></i>${line.text}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return div;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function runTerminalAnimation() {
|
|
113
|
+
terminalContent.innerHTML = '';
|
|
114
|
+
|
|
115
|
+
for (const line of terminalLines) {
|
|
116
|
+
const div = createLine(line);
|
|
117
|
+
terminalContent.appendChild(div);
|
|
118
|
+
|
|
119
|
+
if (line.type === 'command') {
|
|
120
|
+
const textSpan = div.querySelector('.typing-cursor');
|
|
121
|
+
const fullText = line.text;
|
|
122
|
+
textSpan.textContent = '';
|
|
123
|
+
div.classList.add('visible');
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < fullText.length; i++) {
|
|
126
|
+
textSpan.textContent += fullText[i];
|
|
127
|
+
await new Promise(r => setTimeout(r, 50 + Math.random() * 50));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
textSpan.classList.remove('typing-cursor');
|
|
131
|
+
} else {
|
|
132
|
+
await new Promise(r => setTimeout(r, 300));
|
|
133
|
+
div.classList.add('visible');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
await new Promise(r => setTimeout(r, 500));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Start animation when visible
|
|
141
|
+
const observer = new IntersectionObserver((entries) => {
|
|
142
|
+
entries.forEach(entry => {
|
|
143
|
+
if (entry.isIntersecting) {
|
|
144
|
+
runTerminalAnimation();
|
|
145
|
+
observer.disconnect();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
observer.observe(document.querySelector('.relative.bg-\\[\\#1a1a24\\]'));
|
|
151
|
+
|
|
152
|
+
// Mobile menu toggle
|
|
153
|
+
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
|
|
154
|
+
const mobileMenu = document.getElementById('mobileMenu');
|
|
155
|
+
|
|
156
|
+
if (mobileMenuBtn && mobileMenu) {
|
|
157
|
+
mobileMenuBtn.addEventListener('click', () => {
|
|
158
|
+
mobileMenu.classList.toggle('hidden');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Close mobile menu when clicking on a link
|
|
162
|
+
mobileMenu.querySelectorAll('a').forEach(link => {
|
|
163
|
+
link.addEventListener('click', () => {
|
|
164
|
+
mobileMenu.classList.add('hidden');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|