@programinglive/dev-workflow-mcp-server 1.4.0 → 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 +125 -2
- package/README.md +1 -1
- package/docs/PLESK_DEPLOYMENT.md +170 -0
- package/docs/WORKFLOW-BEST-PRACTICES.md +58 -0
- package/docs/release-notes/RELEASE_NOTES.md +40 -0
- package/package.json +7 -6
- package/release-wrapper.js +68 -33
- package/scripts/update-release-notes.cjs +14 -18
- package/tailwind.config.js +2 -4
- 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/web-legacy/public/docs/RELEASE_NOTES.html +275 -0
- 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/dist/docs/RELEASE_NOTES.html +0 -167
- package/web/public/index.html +0 -1046
- package/web/public/input.css +0 -3
- package/web/public/output.css +0 -1
package/web/public/index.html
DELETED
|
@@ -1,1046 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>Dev Workflow Dashboard</title>
|
|
8
|
-
<link rel="stylesheet" href="/output.css">
|
|
9
|
-
<script src="https://unpkg.com/lucide@latest"></script>
|
|
10
|
-
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
11
|
-
</head>
|
|
12
|
-
|
|
13
|
-
<body class="bg-slate-50 text-slate-900">
|
|
14
|
-
<div class="min-h-screen flex flex-col">
|
|
15
|
-
<header class="border-b bg-gradient-to-r from-indigo-600 via-indigo-500 to-purple-500 text-white shadow-lg">
|
|
16
|
-
<div class="max-w-7xl mx-auto px-6 py-6 flex flex-col gap-6 md:flex-row md:items-center md:justify-between">
|
|
17
|
-
<div class="flex items-start gap-4">
|
|
18
|
-
<div class="relative">
|
|
19
|
-
<div class="absolute inset-0 rounded-2xl bg-white/20 blur-md"></div>
|
|
20
|
-
<span
|
|
21
|
-
class="relative inline-flex items-center justify-center h-14 w-14 rounded-2xl bg-white text-indigo-600 text-xl font-semibold shadow-lg">
|
|
22
|
-
DW
|
|
23
|
-
</span>
|
|
24
|
-
</div>
|
|
25
|
-
<div>
|
|
26
|
-
<h1 class="text-3xl font-semibold flex items-center gap-3">
|
|
27
|
-
<span
|
|
28
|
-
class="inline-flex h-9 w-9 items-center justify-center rounded-full bg-white/20 text-white shadow-sm">
|
|
29
|
-
<i data-lucide="book-open"></i>
|
|
30
|
-
</span>
|
|
31
|
-
Dev Workflow Knowledge Hub
|
|
32
|
-
<span id="appVersion"
|
|
33
|
-
class="text-sm bg-white/20 px-2 py-0.5 rounded-full font-normal opacity-90 hidden"></span>
|
|
34
|
-
</h1>
|
|
35
|
-
<p class="text-sm md:text-base text-indigo-100/90 mt-2 max-w-xl">
|
|
36
|
-
History, commands, and documentation unified into one dashboard so every task follows the disciplined
|
|
37
|
-
workflow.
|
|
38
|
-
</p>
|
|
39
|
-
<div class="mt-4 flex flex-wrap gap-3 text-sm">
|
|
40
|
-
<span class="inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1"><i data-lucide="sparkles"
|
|
41
|
-
class="h-4 w-4"></i> Live insights</span>
|
|
42
|
-
<span class="inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1"><i data-lucide="workflow"
|
|
43
|
-
class="h-4 w-4"></i> Workflow guardrails</span>
|
|
44
|
-
<span class="inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1"><i
|
|
45
|
-
data-lucide="book-open-check" class="h-4 w-4"></i> Embedded documentation</span>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
<div class="flex flex-col gap-4 md:items-end">
|
|
50
|
-
<div class="flex items-center gap-3 w-full md:w-auto">
|
|
51
|
-
<div class="relative flex-1 md:flex-initial">
|
|
52
|
-
<i data-lucide="search"
|
|
53
|
-
class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-indigo-300 h-4 w-4"></i>
|
|
54
|
-
<input type="search" placeholder="Search sections" aria-label="Search sections"
|
|
55
|
-
class="w-full pl-9 pr-4 py-2 rounded-full bg-white/20 text-white placeholder:text-indigo-200/80 focus:outline-none focus:ring-2 focus:ring-white/60 focus:bg-white/30"
|
|
56
|
-
oninput="handleSectionSearch(event)" />
|
|
57
|
-
</div>
|
|
58
|
-
<button
|
|
59
|
-
class="inline-flex items-center gap-2 rounded-full bg-white text-indigo-600 px-4 py-2 text-sm font-semibold shadow-md hover:bg-indigo-50"
|
|
60
|
-
id="refreshDashboardBtn">
|
|
61
|
-
<i data-lucide="refresh-ccw"></i>
|
|
62
|
-
Refresh data
|
|
63
|
-
</button>
|
|
64
|
-
</div>
|
|
65
|
-
<div class="flex flex-wrap gap-2 text-xs text-indigo-100/80 md:justify-end">
|
|
66
|
-
<span class="inline-flex items-center gap-2"><i data-lucide="keyboard"></i> Press ⬇️ to navigate
|
|
67
|
-
sections</span>
|
|
68
|
-
<span class="inline-flex items-center gap-2"><i data-lucide="external-link"></i> Docs open inline</span>
|
|
69
|
-
</div>
|
|
70
|
-
<div class="flex flex-wrap gap-3 md:justify-end">
|
|
71
|
-
<button
|
|
72
|
-
class="scroll-link inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-medium hover:bg-white/25 transition"
|
|
73
|
-
data-scroll-target="#overview"><i data-lucide="compass" class="h-4 w-4"></i> Overview</button>
|
|
74
|
-
<button
|
|
75
|
-
class="scroll-link inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-medium hover:bg-white/25 transition"
|
|
76
|
-
data-scroll-target="#history"><i data-lucide="clock" class="h-4 w-4"></i> History</button>
|
|
77
|
-
<button
|
|
78
|
-
class="scroll-link inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-medium hover:bg-white/25 transition"
|
|
79
|
-
data-scroll-target="#commands"><i data-lucide="workflow" class="h-4 w-4"></i> Commands</button>
|
|
80
|
-
<button
|
|
81
|
-
class="scroll-link inline-flex items-center gap-2 rounded-full bg-white/15 px-3 py-1 text-sm font-medium hover:bg-white/25 transition"
|
|
82
|
-
data-scroll-target="#api"><i data-lucide="code" class="h-4 w-4"></i> API</button>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
</header>
|
|
87
|
-
|
|
88
|
-
<div class="flex flex-1 max-w-7xl mx-auto w-full px-4 sm:px-6 lg:px-8 gap-6 py-8">
|
|
89
|
-
<aside class="hidden lg:block w-64 shrink-0">
|
|
90
|
-
<nav class="sticky top-24 bg-white border border-slate-200 rounded-lg p-4 space-y-4">
|
|
91
|
-
<div>
|
|
92
|
-
<h2 class="text-xs uppercase tracking-wide text-slate-500 mb-2">Documentation</h2>
|
|
93
|
-
<ul class="space-y-1 text-sm" id="sidebarNav">
|
|
94
|
-
<li><a href="#overview" class="block px-3 py-2 rounded hover:bg-indigo-50 text-slate-700">Overview</a>
|
|
95
|
-
</li>
|
|
96
|
-
<li><a href="#history" class="block px-3 py-2 rounded hover:bg-indigo-50 text-slate-700">Workflow
|
|
97
|
-
History</a></li>
|
|
98
|
-
<li><a href="#usage" class="block px-3 py-2 rounded hover:bg-indigo-50 text-slate-700">Using Filters</a>
|
|
99
|
-
</li>
|
|
100
|
-
<li><a href="#commands" class="block px-3 py-2 rounded hover:bg-indigo-50 text-slate-700">Commands
|
|
101
|
-
Reference</a></li>
|
|
102
|
-
<li><a href="#api" class="block px-3 py-2 rounded hover:bg-indigo-50 text-slate-700">API Endpoints</a>
|
|
103
|
-
</li>
|
|
104
|
-
<li><a href="#troubleshooting"
|
|
105
|
-
class="block px-3 py-2 rounded hover:bg-indigo-50 text-slate-700">Troubleshooting</a></li>
|
|
106
|
-
</ul>
|
|
107
|
-
</div>
|
|
108
|
-
<div class="border-t pt-4">
|
|
109
|
-
<h2 class="text-xs uppercase tracking-wide text-slate-500 mb-2">Resources</h2>
|
|
110
|
-
<ul class="space-y-1 text-sm">
|
|
111
|
-
<li><a href="https://github.com/programinglive/dev-workflow-mcp-server" target="_blank" rel="noopener"
|
|
112
|
-
class="block px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">GitHub Repository</a></li>
|
|
113
|
-
<li><button data-doc="README.md"
|
|
114
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Project
|
|
115
|
-
README</button></li>
|
|
116
|
-
<li><button data-doc="web-dashboard.md"
|
|
117
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Web
|
|
118
|
-
Dashboard Guide</button></li>
|
|
119
|
-
<li><button data-doc="GETTING-STARTED.md"
|
|
120
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Getting
|
|
121
|
-
Started</button></li>
|
|
122
|
-
<li><button data-doc="EXAMPLES.md"
|
|
123
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Examples</button>
|
|
124
|
-
</li>
|
|
125
|
-
<li><button data-doc="WORKFLOW-TEMPLATES.md"
|
|
126
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Workflow
|
|
127
|
-
Templates</button></li>
|
|
128
|
-
<li><button data-doc="TROUBLESHOOTING.md"
|
|
129
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Troubleshooting</button>
|
|
130
|
-
</li>
|
|
131
|
-
<li><button data-doc="RELEASE_NOTES.md"
|
|
132
|
-
class="doc-link block w-full text-left px-3 py-2 rounded hover:bg-indigo-50 text-indigo-600">Release
|
|
133
|
-
Notes</button></li>
|
|
134
|
-
</ul>
|
|
135
|
-
</div>
|
|
136
|
-
</nav>
|
|
137
|
-
</aside>
|
|
138
|
-
|
|
139
|
-
<main class="flex-1 space-y-12">
|
|
140
|
-
<section id="overview" class="bg-white border border-slate-200 rounded-xl shadow-sm p-6">
|
|
141
|
-
<div class="flex items-center justify-between">
|
|
142
|
-
<div>
|
|
143
|
-
<h2 class="text-2xl font-semibold flex items-center gap-2">
|
|
144
|
-
<i data-lucide="compass"></i>
|
|
145
|
-
Overview
|
|
146
|
-
</h2>
|
|
147
|
-
<p class="mt-2 text-slate-600">Learn how the Dev Workflow dashboard surfaces workflow history and offers
|
|
148
|
-
inline documentation for every MCP command.</p>
|
|
149
|
-
<div class="mt-4 bg-amber-50 border border-amber-200 text-amber-800 text-sm rounded-lg p-4 flex gap-3">
|
|
150
|
-
<i data-lucide="alert-circle" class="mt-1 shrink-0"></i>
|
|
151
|
-
<p>
|
|
152
|
-
The dashboard is read-only. MCP clients (Windsurf, Claude Desktop, etc.) must launch the server via
|
|
153
|
-
<code>node index.js</code>
|
|
154
|
-
over stdio on the machine they control. Hosting this site publicly does <strong>not</strong> expose
|
|
155
|
-
the MCP protocol; without SSH or another
|
|
156
|
-
execution path to the server, remote users cannot connect their MCP agents.
|
|
157
|
-
</p>
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
<div class="hidden md:flex items-center gap-2 text-sm text-slate-500">
|
|
161
|
-
<i data-lucide="info"></i>
|
|
162
|
-
<span>Need help? Jump to <a href="#commands" class="text-indigo-600 underline">Commands
|
|
163
|
-
Reference</a>.</span>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
<div class="mt-6 grid gap-6 md:grid-cols-2">
|
|
167
|
-
<div class="p-4 bg-indigo-50 rounded-lg border border-indigo-100">
|
|
168
|
-
<h3 class="font-medium text-indigo-900 flex items-center gap-2"><i data-lucide="activity"></i> Live
|
|
169
|
-
Insights</h3>
|
|
170
|
-
<p class="text-sm text-indigo-900/80 mt-2">Connects directly to your `.state` history to show progress,
|
|
171
|
-
release cadence, and team activity trends.</p>
|
|
172
|
-
</div>
|
|
173
|
-
<div class="p-4 bg-emerald-50 rounded-lg border border-emerald-100">
|
|
174
|
-
<h3 class="font-medium text-emerald-900 flex items-center gap-2"><i data-lucide="book"></i> Built-in
|
|
175
|
-
Playbook</h3>
|
|
176
|
-
<p class="text-sm text-emerald-900/80 mt-2">Every MCP tool is documented with prerequisites, recommended
|
|
177
|
-
usage, and follow-up actions.</p>
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
</section>
|
|
181
|
-
|
|
182
|
-
<section id="history" class="bg-white border border-slate-200 rounded-xl shadow-sm p-6 space-y-8">
|
|
183
|
-
<div class="flex items-center justify-between flex-wrap gap-4">
|
|
184
|
-
<div>
|
|
185
|
-
<h2 class="text-2xl font-semibold flex items-center gap-2">
|
|
186
|
-
<i data-lucide="clock-4"></i>
|
|
187
|
-
Workflow History Explorer
|
|
188
|
-
</h2>
|
|
189
|
-
<p class="text-slate-600 mt-2">Slice and explore your task history. Use the filters below to focus on a
|
|
190
|
-
user, time range, or frequency.</p>
|
|
191
|
-
</div>
|
|
192
|
-
<a href="#api" class="inline-flex items-center gap-2 text-sm text-indigo-600 hover:text-indigo-700">
|
|
193
|
-
<i data-lucide="terminal"></i>
|
|
194
|
-
View API
|
|
195
|
-
</a>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
198
|
-
<section id="filtersSection">
|
|
199
|
-
<div class="bg-slate-50 border border-slate-200 rounded-lg p-6">
|
|
200
|
-
<h3 class="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
201
|
-
<i data-lucide="sliders-horizontal"></i>
|
|
202
|
-
Filters
|
|
203
|
-
</h3>
|
|
204
|
-
<div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
|
|
205
|
-
<label class="flex flex-col gap-1">
|
|
206
|
-
<span class="text-sm font-medium text-slate-600">User ID</span>
|
|
207
|
-
<input id="userId" type="text" placeholder="default"
|
|
208
|
-
class="border border-slate-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500" />
|
|
209
|
-
</label>
|
|
210
|
-
<label class="flex flex-col gap-1">
|
|
211
|
-
<span class="text-sm font-medium text-slate-600">Start date</span>
|
|
212
|
-
<input id="startDate" type="date"
|
|
213
|
-
class="border border-slate-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500" />
|
|
214
|
-
</label>
|
|
215
|
-
<label class="flex flex-col gap-1">
|
|
216
|
-
<span class="text-sm font-medium text-slate-600">End date</span>
|
|
217
|
-
<input id="endDate" type="date"
|
|
218
|
-
class="border border-slate-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500" />
|
|
219
|
-
</label>
|
|
220
|
-
<label class="flex flex-col gap-1">
|
|
221
|
-
<span class="text-sm font-medium text-slate-600">Activity frequency</span>
|
|
222
|
-
<select id="frequency"
|
|
223
|
-
class="border border-slate-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500">
|
|
224
|
-
<option value="daily">Daily</option>
|
|
225
|
-
<option value="monthly">Monthly</option>
|
|
226
|
-
<option value="yearly">Yearly</option>
|
|
227
|
-
</select>
|
|
228
|
-
</label>
|
|
229
|
-
<label class="flex flex-col gap-1">
|
|
230
|
-
<span class="text-sm font-medium text-slate-600">Page size</span>
|
|
231
|
-
<select id="pageSize"
|
|
232
|
-
class="border border-slate-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500">
|
|
233
|
-
<option value="10">10</option>
|
|
234
|
-
<option value="20" selected>20</option>
|
|
235
|
-
<option value="50">50</option>
|
|
236
|
-
</select>
|
|
237
|
-
</label>
|
|
238
|
-
</div>
|
|
239
|
-
<div class="flex flex-wrap gap-3 items-center mt-5">
|
|
240
|
-
<button id="applyFiltersBtn"
|
|
241
|
-
class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">Apply filters</button>
|
|
242
|
-
<button id="resetFiltersBtn"
|
|
243
|
-
class="bg-white border border-slate-300 text-slate-700 px-4 py-2 rounded-md hover:bg-slate-100">Reset</button>
|
|
244
|
-
<span class="text-sm text-slate-500">Leave fields empty to view all data for the default user.</span>
|
|
245
|
-
</div>
|
|
246
|
-
</div>
|
|
247
|
-
</section>
|
|
248
|
-
|
|
249
|
-
<section id="summarySection" class="hidden">
|
|
250
|
-
<div class="bg-white border border-slate-200 rounded-lg p-6 shadow-inner">
|
|
251
|
-
<h3 class="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
252
|
-
<i data-lucide="bar-chart-2"></i>
|
|
253
|
-
Project Summary
|
|
254
|
-
</h3>
|
|
255
|
-
<div id="summaryContent" class="space-y-2 text-sm"></div>
|
|
256
|
-
<div id="historySummaryCard" class="mt-6 bg-slate-50 border border-slate-200 rounded-md p-4 hidden">
|
|
257
|
-
<div class="flex items-center justify-between mb-2">
|
|
258
|
-
<h4 class="font-medium text-slate-700" id="historySummaryHeading">Activity by period</h4>
|
|
259
|
-
<span class="text-xs uppercase tracking-wide text-slate-500" id="historySummaryMeta"></span>
|
|
260
|
-
</div>
|
|
261
|
-
<div id="historySummaryContent" class="space-y-1 text-sm text-slate-700"></div>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
</section>
|
|
265
|
-
|
|
266
|
-
<section id="historySection" class="hidden">
|
|
267
|
-
<div class="bg-white border border-slate-200 rounded-lg p-6 shadow-inner">
|
|
268
|
-
<h3 class="text-lg font-semibold mb-4 flex items-center gap-2">
|
|
269
|
-
<i data-lucide="history"></i>
|
|
270
|
-
Recent History
|
|
271
|
-
</h3>
|
|
272
|
-
<div id="historyContent" class="space-y-3 text-sm"></div>
|
|
273
|
-
<div id="paginationControls" class="flex items-center justify-between mt-6 hidden">
|
|
274
|
-
<button id="prevPageBtn"
|
|
275
|
-
class="bg-white border border-slate-300 text-slate-700 px-3 py-1 rounded-md hover:bg-slate-100 disabled:opacity-50 disabled:cursor-not-allowed">Previous</button>
|
|
276
|
-
<span id="pageInfo" class="text-sm text-slate-600"></span>
|
|
277
|
-
<button id="nextPageBtn"
|
|
278
|
-
class="bg-white border border-slate-300 text-slate-700 px-3 py-1 rounded-md hover:bg-slate-100 disabled:opacity-50 disabled:cursor-not-allowed">Next</button>
|
|
279
|
-
</div>
|
|
280
|
-
</div>
|
|
281
|
-
</section>
|
|
282
|
-
</section>
|
|
283
|
-
|
|
284
|
-
<section id="usage" class="bg-white border border-slate-200 rounded-xl shadow-sm p-6">
|
|
285
|
-
<div class="flex items-center gap-2 text-indigo-600 text-sm font-medium uppercase tracking-wide">
|
|
286
|
-
<i data-lucide="target"></i>
|
|
287
|
-
How to Use the Dashboard
|
|
288
|
-
</div>
|
|
289
|
-
<div class="mt-4 grid gap-6 md:grid-cols-2">
|
|
290
|
-
<div>
|
|
291
|
-
<h3 class="font-semibold text-slate-800">1. Filter your scope</h3>
|
|
292
|
-
<p class="text-sm text-slate-600 mt-2">Pick a user ID to analyze individual contributions. Add date ranges
|
|
293
|
-
to focus on a release window, sprint, or quarter.</p>
|
|
294
|
-
</div>
|
|
295
|
-
<div>
|
|
296
|
-
<h3 class="font-semibold text-slate-800">2. Inspect the summary</h3>
|
|
297
|
-
<p class="text-sm text-slate-600 mt-2">Review overall throughput, mix of task types, and recent activity.
|
|
298
|
-
The summary auto-updates whenever you change filters.</p>
|
|
299
|
-
</div>
|
|
300
|
-
<div>
|
|
301
|
-
<h3 class="font-semibold text-slate-800">3. Dive into entries</h3>
|
|
302
|
-
<p class="text-sm text-slate-600 mt-2">Scroll the event log to see commit messages, forced completions,
|
|
303
|
-
and dropped tasks. Use pagination to traverse older work.</p>
|
|
304
|
-
</div>
|
|
305
|
-
<div>
|
|
306
|
-
<h3 class="font-semibold text-slate-800">4. Export via API</h3>
|
|
307
|
-
<p class="text-sm text-slate-600 mt-2">Need automation or reporting? Jump to the <a href="#api"
|
|
308
|
-
class="text-indigo-600 underline">API section</a> and query JSON endpoints directly.</p>
|
|
309
|
-
</div>
|
|
310
|
-
</div>
|
|
311
|
-
</section>
|
|
312
|
-
|
|
313
|
-
<section id="commands" class="bg-white border border-slate-200 rounded-xl shadow-sm p-6 space-y-6">
|
|
314
|
-
<div class="flex items-center justify-between flex-wrap gap-3">
|
|
315
|
-
<div>
|
|
316
|
-
<h2 class="text-2xl font-semibold flex items-center gap-2">
|
|
317
|
-
<i data-lucide="workflow"></i>
|
|
318
|
-
Commands Reference
|
|
319
|
-
</h2>
|
|
320
|
-
<div
|
|
321
|
-
class="mt-2 inline-flex items-center gap-2 rounded-full bg-indigo-50 px-3 py-1 text-xs font-semibold text-indigo-600 uppercase tracking-wide">
|
|
322
|
-
<i data-lucide="check-square"></i>
|
|
323
|
-
<span>All Tools · 20 commands</span>
|
|
324
|
-
</div>
|
|
325
|
-
<p class="text-slate-600 mt-3">Explore all <strong>20</strong> MCP tools that keep the workflow honest.
|
|
326
|
-
Review prerequisites, usage tips, and next steps for each command below.</p>
|
|
327
|
-
</div>
|
|
328
|
-
<button data-doc="README.md" data-doc-heading="🛠️ Available Tools"
|
|
329
|
-
class="doc-link inline-flex items-center gap-2 text-sm text-indigo-600 hover:text-indigo-700">
|
|
330
|
-
<i data-lucide="external-link"></i>
|
|
331
|
-
Full README Reference
|
|
332
|
-
</button>
|
|
333
|
-
</div>
|
|
334
|
-
|
|
335
|
-
<div class="space-y-4">
|
|
336
|
-
<details open class="border border-slate-200 rounded-lg">
|
|
337
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
338
|
-
<span><i data-lucide="flag"></i> start_task</span>
|
|
339
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
340
|
-
</summary>
|
|
341
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
342
|
-
<p>Begin every effort with a clear description and task type.</p>
|
|
343
|
-
<ul class="list-disc list-inside space-y-1">
|
|
344
|
-
<li><strong>Parameters:</strong> <code>description</code> (string, required), <code>type</code>
|
|
345
|
-
("feature" | "bugfix" | "refactor" | "other", required)</li>
|
|
346
|
-
<li><strong>When to use:</strong> Before writing code or touching files.</li>
|
|
347
|
-
<li><strong>Next step:</strong> Implement your changes then run <code>mark_bug_fixed</code>.</li>
|
|
348
|
-
</ul>
|
|
349
|
-
</div>
|
|
350
|
-
</details>
|
|
351
|
-
|
|
352
|
-
<details class="border border-slate-200 rounded-lg">
|
|
353
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
354
|
-
<span><i data-lucide="check-circle"></i> mark_bug_fixed</span>
|
|
355
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
356
|
-
</summary>
|
|
357
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
358
|
-
<p>Declare the implementation complete and explain what was delivered.</p>
|
|
359
|
-
<ul class="list-disc list-inside space-y-1">
|
|
360
|
-
<li><strong>Parameter:</strong> <code>summary</code> (string, required)</li>
|
|
361
|
-
<li><strong>Prerequisite:</strong> Code changes ready for testing.</li>
|
|
362
|
-
<li><strong>Next step:</strong> Create or update automated tests.</li>
|
|
363
|
-
</ul>
|
|
364
|
-
</div>
|
|
365
|
-
</details>
|
|
366
|
-
|
|
367
|
-
<details class="border border-slate-200 rounded-lg">
|
|
368
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
369
|
-
<span><i data-lucide="beaker"></i> create_tests</span>
|
|
370
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
371
|
-
</summary>
|
|
372
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
373
|
-
<p>Confirm that coverage exists for the work you just completed.</p>
|
|
374
|
-
<ul class="list-disc list-inside space-y-1">
|
|
375
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
376
|
-
<li><strong>When to use:</strong> After <code>mark_bug_fixed</code> once tests are written.</li>
|
|
377
|
-
<li><strong>Next step:</strong> Execute <code>run_tests</code> and record the results.</li>
|
|
378
|
-
</ul>
|
|
379
|
-
</div>
|
|
380
|
-
</details>
|
|
381
|
-
|
|
382
|
-
<details class="border border-slate-200 rounded-lg">
|
|
383
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
384
|
-
<span><i data-lucide="ban"></i> skip_tests</span>
|
|
385
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
386
|
-
</summary>
|
|
387
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
388
|
-
<p>Document why automated tests are impossible for this task.</p>
|
|
389
|
-
<ul class="list-disc list-inside space-y-1">
|
|
390
|
-
<li><strong>Parameter:</strong> <code>reason</code> (string, required)</li>
|
|
391
|
-
<li><strong>Effect:</strong> Flags the workflow for manual QA review.</li>
|
|
392
|
-
<li><strong>Next step:</strong> Continue with <code>create_documentation</code>.</li>
|
|
393
|
-
</ul>
|
|
394
|
-
</div>
|
|
395
|
-
</details>
|
|
396
|
-
|
|
397
|
-
<details class="border border-slate-200 rounded-lg">
|
|
398
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
399
|
-
<span><i data-lucide="test-tube"></i> run_tests</span>
|
|
400
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
401
|
-
</summary>
|
|
402
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
403
|
-
<p>Capture the outcome of your automated test run.</p>
|
|
404
|
-
<ul class="list-disc list-inside space-y-1">
|
|
405
|
-
<li><strong>Parameters:</strong> <code>passed</code> (boolean, required), <code>testCommand</code>
|
|
406
|
-
(string, required), optional <code>details</code> (string)</li>
|
|
407
|
-
<li><strong>Guidance:</strong> Never proceed if tests fail—return to coding and re-run.</li>
|
|
408
|
-
<li><strong>Next step:</strong> Move to <code>create_documentation</code> when green.</li>
|
|
409
|
-
</ul>
|
|
410
|
-
</div>
|
|
411
|
-
</details>
|
|
412
|
-
|
|
413
|
-
<details class="border border-slate-200 rounded-lg">
|
|
414
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
415
|
-
<span><i data-lucide="file-text"></i> create_documentation</span>
|
|
416
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
417
|
-
</summary>
|
|
418
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
419
|
-
<p>Record documentation updates before proceeding to verification.</p>
|
|
420
|
-
<ul class="list-disc list-inside space-y-1">
|
|
421
|
-
<li><strong>Parameters:</strong> <code>documentationType</code> (enum), <code>summary</code> (string)
|
|
422
|
-
</li>
|
|
423
|
-
<li><strong>Tip:</strong> Keep summaries short but action-oriented. Include links to README sections
|
|
424
|
-
or docs PRs.</li>
|
|
425
|
-
</ul>
|
|
426
|
-
</div>
|
|
427
|
-
</details>
|
|
428
|
-
|
|
429
|
-
<details class="border border-slate-200 rounded-lg">
|
|
430
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
431
|
-
<span><i data-lucide="shield-check"></i> check_ready_to_commit</span>
|
|
432
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
433
|
-
</summary>
|
|
434
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
435
|
-
<p>Run the automated readiness review. This ensures each phase is complete before you commit.</p>
|
|
436
|
-
<ul class="list-disc list-inside space-y-1">
|
|
437
|
-
<li><strong>Output:</strong> Highlights missing steps and pending verification.</li>
|
|
438
|
-
<li><strong>Next step:</strong> <code>commit_and_push</code> when the ready check passes.</li>
|
|
439
|
-
</ul>
|
|
440
|
-
</div>
|
|
441
|
-
</details>
|
|
442
|
-
|
|
443
|
-
<details class="border border-slate-200 rounded-lg">
|
|
444
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
445
|
-
<span><i data-lucide="git-commit"></i> commit_and_push</span>
|
|
446
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
447
|
-
</summary>
|
|
448
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
449
|
-
<p>Automatically stage, commit, and push once verification passes.</p>
|
|
450
|
-
<ul class="list-disc list-inside space-y-1">
|
|
451
|
-
<li><strong>Parameters:</strong> <code>commitMessage</code> (string), optional <code>branch</code>
|
|
452
|
-
(string)</li>
|
|
453
|
-
<li><strong>Behavior:</strong> Detects clean working trees and reuses the latest commit metadata.</li>
|
|
454
|
-
<li><strong>Reminder:</strong> Any new edits will bounce you back to this step.</li>
|
|
455
|
-
</ul>
|
|
456
|
-
</div>
|
|
457
|
-
</details>
|
|
458
|
-
|
|
459
|
-
<details class="border border-slate-200 rounded-lg">
|
|
460
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
461
|
-
<span><i data-lucide="rocket"></i> perform_release</span>
|
|
462
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
463
|
-
</summary>
|
|
464
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
465
|
-
<p>Record release details once the commit is live. Guards ensure the workflow order.</p>
|
|
466
|
-
<ul class="list-disc list-inside space-y-1">
|
|
467
|
-
<li><strong>Parameters:</strong> <code>command</code> (string), optional <code>notes</code>,
|
|
468
|
-
<code>releaseType</code>, <code>preset</code>
|
|
469
|
-
</li>
|
|
470
|
-
<li><strong>Integration:</strong> Wraps <code>release-wrapper.js</code> to prevent accidental version
|
|
471
|
-
bumps.</li>
|
|
472
|
-
</ul>
|
|
473
|
-
</div>
|
|
474
|
-
</details>
|
|
475
|
-
|
|
476
|
-
<details class="border border-slate-200 rounded-lg">
|
|
477
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
478
|
-
<span><i data-lucide="check-square"></i> complete_task</span>
|
|
479
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
480
|
-
</summary>
|
|
481
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
482
|
-
<p>Close the workflow after a successful push and release.</p>
|
|
483
|
-
<ul class="list-disc list-inside space-y-1">
|
|
484
|
-
<li><strong>Parameter:</strong> <code>commitMessage</code> (string, required)</li>
|
|
485
|
-
<li><strong>Effect:</strong> Archives the task in history and resets the state.</li>
|
|
486
|
-
<li><strong>Next step:</strong> Celebrate or begin the next task with <code>start_task</code>.</li>
|
|
487
|
-
</ul>
|
|
488
|
-
</div>
|
|
489
|
-
</details>
|
|
490
|
-
|
|
491
|
-
<details class="border border-slate-200 rounded-lg">
|
|
492
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
493
|
-
<span><i data-lucide="alert-triangle"></i> force_complete_task</span>
|
|
494
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
495
|
-
</summary>
|
|
496
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
497
|
-
<p>Record an incomplete task as finished with a justification.</p>
|
|
498
|
-
<ul class="list-disc list-inside space-y-1">
|
|
499
|
-
<li><strong>Parameters:</strong> optional <code>commitMessage</code>, optional <code>reason</code>
|
|
500
|
-
(string)</li>
|
|
501
|
-
<li><strong>Use sparingly:</strong> Ideal for emergencies where remaining steps cannot be done.</li>
|
|
502
|
-
<li><strong>Next step:</strong> Follow up manually on outstanding work.</li>
|
|
503
|
-
</ul>
|
|
504
|
-
</div>
|
|
505
|
-
</details>
|
|
506
|
-
|
|
507
|
-
<details class="border border-slate-200 rounded-lg">
|
|
508
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
509
|
-
<span><i data-lucide="x-circle"></i> drop_task</span>
|
|
510
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
511
|
-
</summary>
|
|
512
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
513
|
-
<p>Abandon the current effort while keeping the history clean.</p>
|
|
514
|
-
<ul class="list-disc list-inside space-y-1">
|
|
515
|
-
<li><strong>Parameter:</strong> optional <code>reason</code> (string)</li>
|
|
516
|
-
<li><strong>When to use:</strong> Pivoting to a new approach or discarding exploratory work.</li>
|
|
517
|
-
<li><strong>Next step:</strong> Start a fresh task once direction is clear.</li>
|
|
518
|
-
</ul>
|
|
519
|
-
</div>
|
|
520
|
-
</details>
|
|
521
|
-
|
|
522
|
-
<details class="border border-slate-200 rounded-lg">
|
|
523
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
524
|
-
<span><i data-lucide="info"></i> get_workflow_status</span>
|
|
525
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
526
|
-
</summary>
|
|
527
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
528
|
-
<p>Check the current phase, pending steps, and metadata.</p>
|
|
529
|
-
<ul class="list-disc list-inside space-y-1">
|
|
530
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
531
|
-
<li><strong>Use when:</strong> You need a quick reminder of what remains.</li>
|
|
532
|
-
</ul>
|
|
533
|
-
</div>
|
|
534
|
-
</details>
|
|
535
|
-
|
|
536
|
-
<details class="border border-slate-200 rounded-lg">
|
|
537
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
538
|
-
<span><i data-lucide="history"></i> view_history</span>
|
|
539
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
540
|
-
</summary>
|
|
541
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
542
|
-
<p>List recently completed tasks and their outcomes.</p>
|
|
543
|
-
<ul class="list-disc list-inside space-y-1">
|
|
544
|
-
<li><strong>Parameter:</strong> optional <code>limit</code> (number)</li>
|
|
545
|
-
<li><strong>Great for:</strong> Standups, retrospectives, or auditing recent work.</li>
|
|
546
|
-
</ul>
|
|
547
|
-
</div>
|
|
548
|
-
</details>
|
|
549
|
-
|
|
550
|
-
<details class="border border-slate-200 rounded-lg">
|
|
551
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
552
|
-
<span><i data-lucide="compass"></i> continue_workflow</span>
|
|
553
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
554
|
-
</summary>
|
|
555
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
556
|
-
<p>Receive coaching on what to do next.</p>
|
|
557
|
-
<ul class="list-disc list-inside space-y-1">
|
|
558
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
559
|
-
<li><strong>Behavior:</strong> Runs readiness checks automatically and surfaces blockers.</li>
|
|
560
|
-
</ul>
|
|
561
|
-
</div>
|
|
562
|
-
</details>
|
|
563
|
-
|
|
564
|
-
<details class="border border-slate-200 rounded-lg">
|
|
565
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
566
|
-
<span><i data-lucide="refresh-cw"></i> rerun_workflow</span>
|
|
567
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
568
|
-
</summary>
|
|
569
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
570
|
-
<p>Reset the active task back to the start.</p>
|
|
571
|
-
<ul class="list-disc list-inside space-y-1">
|
|
572
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
573
|
-
<li><strong>Use when:</strong> You want to replay the entire process with fresh inputs.</li>
|
|
574
|
-
</ul>
|
|
575
|
-
</div>
|
|
576
|
-
</details>
|
|
577
|
-
|
|
578
|
-
<details class="border border-slate-200 rounded-lg">
|
|
579
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
580
|
-
<span><i data-lucide="workflow"></i> run_full_workflow</span>
|
|
581
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
582
|
-
</summary>
|
|
583
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
584
|
-
<p>Execute every command in sequence when you already know the answers.</p>
|
|
585
|
-
<ul class="list-disc list-inside space-y-1">
|
|
586
|
-
<li><strong>Parameters (required):</strong> <code>summary</code>, <code>testCommand</code>,
|
|
587
|
-
<code>documentationType</code>, <code>documentationSummary</code>, <code>commitMessage</code>,
|
|
588
|
-
<code>releaseCommand</code>
|
|
589
|
-
</li>
|
|
590
|
-
<li><strong>Optional:</strong> <code>testsPassed</code>, <code>testDetails</code>,
|
|
591
|
-
<code>branch</code>, <code>releaseNotes</code>, <code>releaseType</code>, <code>preset</code>
|
|
592
|
-
</li>
|
|
593
|
-
<li><strong>Ideal for:</strong> Scripted flows or demos where you want the guardrails without manual
|
|
594
|
-
calls.</li>
|
|
595
|
-
</ul>
|
|
596
|
-
</div>
|
|
597
|
-
</details>
|
|
598
|
-
|
|
599
|
-
<details class="border border-slate-200 rounded-lg">
|
|
600
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
601
|
-
<span><i data-lucide="pie-chart"></i> project_summary</span>
|
|
602
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
603
|
-
</summary>
|
|
604
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
605
|
-
<p>Generate a high-level recap of the project’s workflow health.</p>
|
|
606
|
-
<ul class="list-disc list-inside space-y-1">
|
|
607
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
608
|
-
<li><strong>Output:</strong> Aggregated stats compiled from workflow history.</li>
|
|
609
|
-
</ul>
|
|
610
|
-
</div>
|
|
611
|
-
</details>
|
|
612
|
-
|
|
613
|
-
<details class="border border-slate-200 rounded-lg">
|
|
614
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
615
|
-
<span><i data-lucide="database"></i> project_summary_data</span>
|
|
616
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
617
|
-
</summary>
|
|
618
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
619
|
-
<p>Read the persisted JSON knowledge base (project-summary.json).</p>
|
|
620
|
-
<ul class="list-disc list-inside space-y-1">
|
|
621
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
622
|
-
<li><strong>Use when:</strong> You need the structured summary file for automation or reporting.</li>
|
|
623
|
-
</ul>
|
|
624
|
-
</div>
|
|
625
|
-
</details>
|
|
626
|
-
|
|
627
|
-
<details class="border border-slate-200 rounded-lg">
|
|
628
|
-
<summary class="cursor-pointer select-none px-4 py-3 flex items-center justify-between font-medium">
|
|
629
|
-
<span><i data-lucide="database-backup"></i> project_summary_db</span>
|
|
630
|
-
<i data-lucide="chevron-down" class="ml-2"></i>
|
|
631
|
-
</summary>
|
|
632
|
-
<div class="px-5 pb-5 space-y-3 text-sm text-slate-600">
|
|
633
|
-
<p>Query the SQLite-backed knowledge base for the active user.</p>
|
|
634
|
-
<ul class="list-disc list-inside space-y-1">
|
|
635
|
-
<li><strong>Parameters:</strong> None.</li>
|
|
636
|
-
<li><strong>Tip:</strong> Set <code>DEV_WORKFLOW_USER_ID</code> to target another user’s dataset.</li>
|
|
637
|
-
</ul>
|
|
638
|
-
</div>
|
|
639
|
-
</details>
|
|
640
|
-
</div>
|
|
641
|
-
</section>
|
|
642
|
-
|
|
643
|
-
<section id="api" class="bg-white border border-slate-200 rounded-xl shadow-sm p-6 space-y-6">
|
|
644
|
-
<div class="flex items-center gap-2 text-indigo-600 text-sm font-medium uppercase tracking-wide">
|
|
645
|
-
<i data-lucide="code"></i>
|
|
646
|
-
API Endpoints
|
|
647
|
-
</div>
|
|
648
|
-
<p class="text-slate-600">Use these JSON endpoints to integrate task history into automation, dashboards, or
|
|
649
|
-
reports.</p>
|
|
650
|
-
<div class="space-y-4 text-sm text-slate-700">
|
|
651
|
-
<div class="border border-slate-200 rounded-lg p-4">
|
|
652
|
-
<h3 class="font-medium text-slate-800">GET /api/summary</h3>
|
|
653
|
-
<p class="mt-1">Aggregate stats (totals, task mix, recent activity).</p>
|
|
654
|
-
<p class="mt-2 text-xs text-slate-500">Query params: <code>user</code></p>
|
|
655
|
-
</div>
|
|
656
|
-
<div class="border border-slate-200 rounded-lg p-4">
|
|
657
|
-
<h3 class="font-medium text-slate-800">GET /api/history</h3>
|
|
658
|
-
<p class="mt-1">Paginated timeline of workflow entries with commit metadata.</p>
|
|
659
|
-
<p class="mt-2 text-xs text-slate-500">Query params: <code>user</code>, <code>page</code>,
|
|
660
|
-
<code>pageSize</code>, <code>startDate</code>, <code>endDate</code>
|
|
661
|
-
</p>
|
|
662
|
-
</div>
|
|
663
|
-
<div class="border border-slate-200 rounded-lg p-4">
|
|
664
|
-
<h3 class="font-medium text-slate-800">GET /api/history-summary</h3>
|
|
665
|
-
<p class="mt-1">Counts per day, month, or year for trend analysis.</p>
|
|
666
|
-
<p class="mt-2 text-xs text-slate-500">Query params: <code>user</code>, <code>frequency</code>,
|
|
667
|
-
<code>startDate</code>, <code>endDate</code>
|
|
668
|
-
</p>
|
|
669
|
-
</div>
|
|
670
|
-
</div>
|
|
671
|
-
</section>
|
|
672
|
-
|
|
673
|
-
<section id="troubleshooting" class="bg-white border border-slate-200 rounded-xl shadow-sm p-6">
|
|
674
|
-
<div class="flex items-center gap-2 text-rose-600 text-sm font-medium uppercase tracking-wide">
|
|
675
|
-
<i data-lucide="life-buoy"></i>
|
|
676
|
-
Troubleshooting
|
|
677
|
-
</div>
|
|
678
|
-
<div class="mt-4 overflow-hidden border border-slate-200 rounded-lg">
|
|
679
|
-
<table class="min-w-full divide-y divide-slate-200 text-sm">
|
|
680
|
-
<thead class="bg-slate-50 text-slate-600 uppercase text-xs tracking-wide">
|
|
681
|
-
<tr>
|
|
682
|
-
<th class="px-4 py-3 text-left">Symptom</th>
|
|
683
|
-
<th class="px-4 py-3 text-left">Resolution</th>
|
|
684
|
-
</tr>
|
|
685
|
-
</thead>
|
|
686
|
-
<tbody class="divide-y divide-slate-100">
|
|
687
|
-
<tr>
|
|
688
|
-
<td class="px-4 py-3">Dashboard shows empty data</td>
|
|
689
|
-
<td class="px-4 py-3">Verify the MCP server has created `.state/users/<user>/workflow-state.json` and
|
|
690
|
-
that the selected user matches.</td>
|
|
691
|
-
</tr>
|
|
692
|
-
<tr>
|
|
693
|
-
<td class="px-4 py-3">`better-sqlite3` build error on startup</td>
|
|
694
|
-
<td class="px-4 py-3">Install Python 3 and native build tools (Windows) or ensure SQLite headers are
|
|
695
|
-
installed (macOS/Linux).</td>
|
|
696
|
-
</tr>
|
|
697
|
-
<tr>
|
|
698
|
-
<td class="px-4 py-3">Port already in use</td>
|
|
699
|
-
<td class="px-4 py-3">Set <code>DEV_WORKFLOW_WEB_PORT</code> to a free port before running
|
|
700
|
-
<code>npm run web</code>.
|
|
701
|
-
</td>
|
|
702
|
-
</tr>
|
|
703
|
-
</tbody>
|
|
704
|
-
</table>
|
|
705
|
-
</div>
|
|
706
|
-
</section>
|
|
707
|
-
</main>
|
|
708
|
-
</div>
|
|
709
|
-
</div>
|
|
710
|
-
|
|
711
|
-
<div id="docModal" class="fixed inset-0 hidden z-50">
|
|
712
|
-
<div class="absolute inset-0 bg-slate-900/70" id="docModalBackdrop"></div>
|
|
713
|
-
<div class="relative h-full w-full overflow-y-auto p-4 md:p-8">
|
|
714
|
-
<div class="max-w-5xl mx-auto bg-white rounded-xl shadow-2xl border border-slate-200">
|
|
715
|
-
<header
|
|
716
|
-
class="flex items-center justify-between px-6 md:px-8 py-5 border-b border-slate-200 bg-gradient-to-r from-indigo-50 to-white">
|
|
717
|
-
<div>
|
|
718
|
-
<h3 id="docModalTitle" class="text-xl font-bold text-slate-900"></h3>
|
|
719
|
-
<p id="docModalSubtitle" class="text-sm text-slate-600 mt-1"></p>
|
|
720
|
-
</div>
|
|
721
|
-
<button id="docModalClose"
|
|
722
|
-
class="p-2.5 rounded-lg text-slate-500 hover:text-slate-700 hover:bg-white/80 transition-colors shadow-sm"
|
|
723
|
-
aria-label="Close documentation">
|
|
724
|
-
<i data-lucide="x"></i>
|
|
725
|
-
</button>
|
|
726
|
-
</header>
|
|
727
|
-
<article id="docModalContent" class="prose prose-slate prose-lg max-w-none px-6 md:px-12 py-8 md:py-10">
|
|
728
|
-
<p class="text-sm text-slate-500">Loading…</p>
|
|
729
|
-
</article>
|
|
730
|
-
</div>
|
|
731
|
-
</div>
|
|
732
|
-
</div>
|
|
733
|
-
|
|
734
|
-
<script type="module">
|
|
735
|
-
window.handleSectionSearch = (event) => {
|
|
736
|
-
const query = event.target.value.trim().toLowerCase();
|
|
737
|
-
const links = Array.from(document.querySelectorAll('#sidebarNav a'));
|
|
738
|
-
links.forEach((link) => {
|
|
739
|
-
const match = link.textContent.toLowerCase().includes(query);
|
|
740
|
-
link.classList.toggle('hidden', query && !match);
|
|
741
|
-
});
|
|
742
|
-
};
|
|
743
|
-
|
|
744
|
-
function el(id) { return document.getElementById(id); }
|
|
745
|
-
|
|
746
|
-
const frequencyLabels = {
|
|
747
|
-
daily: "Daily",
|
|
748
|
-
monthly: "Monthly",
|
|
749
|
-
yearly: "Yearly",
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
const state = {
|
|
753
|
-
userId: "",
|
|
754
|
-
startDate: "",
|
|
755
|
-
endDate: "",
|
|
756
|
-
frequency: "daily",
|
|
757
|
-
page: 1,
|
|
758
|
-
pageSize: 20,
|
|
759
|
-
totalPages: 1,
|
|
760
|
-
};
|
|
761
|
-
|
|
762
|
-
const controls = {
|
|
763
|
-
userId: el("userId"),
|
|
764
|
-
startDate: el("startDate"),
|
|
765
|
-
endDate: el("endDate"),
|
|
766
|
-
frequency: el("frequency"),
|
|
767
|
-
pageSize: el("pageSize"),
|
|
768
|
-
applyFilters: el("applyFiltersBtn"),
|
|
769
|
-
resetFilters: el("resetFiltersBtn"),
|
|
770
|
-
prevPage: el("prevPageBtn"),
|
|
771
|
-
nextPage: el("nextPageBtn"),
|
|
772
|
-
pageInfo: el("pageInfo"),
|
|
773
|
-
pagination: el("paginationControls"),
|
|
774
|
-
historySummaryCard: el("historySummaryCard"),
|
|
775
|
-
historySummaryContent: el("historySummaryContent"),
|
|
776
|
-
historySummaryMeta: el("historySummaryMeta"),
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
function formatSummary(data) {
|
|
780
|
-
if (!data) return '<p class="text-gray-500">No summary available.</p>';
|
|
781
|
-
const taskTypes = Object.entries(data.taskTypes || {}).map(([t, c]) => `${t}: ${c}`).join(', ');
|
|
782
|
-
const recent = (data.recentTasks || []).map(t => `<li>${t.description} (${t.type})</li>`).join('');
|
|
783
|
-
return `
|
|
784
|
-
<div><strong>Total tasks:</strong> ${data.totalTasks}</div>
|
|
785
|
-
<div><strong>Task mix:</strong> ${taskTypes || '—'}</div>
|
|
786
|
-
<div><strong>Last active:</strong> ${data.lastActive ? new Date(data.lastActive).toLocaleDateString() : 'Never'}</div>
|
|
787
|
-
<div><strong>Updated:</strong> ${data.updatedAt ? new Date(data.updatedAt).toLocaleString() : '—'}</div>
|
|
788
|
-
<div class="mt-4"><strong>Recent tasks:</strong><ul class="list-disc list-inside">${recent || '<li>No recent tasks</li>'}</ul></div>
|
|
789
|
-
`;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
function formatHistory(rows) {
|
|
793
|
-
if (!rows || rows.length === 0) return '<p class="text-gray-500">No history yet.</p>';
|
|
794
|
-
return rows.map(row => `
|
|
795
|
-
<div class="border-b pb-2">
|
|
796
|
-
<div class="flex justify-between items-start">
|
|
797
|
-
<div>
|
|
798
|
-
<div class="font-medium">${row.task_description}</div>
|
|
799
|
-
<div class="text-sm text-gray-600">${row.task_type} • ${new Date(row.timestamp).toLocaleString()}</div>
|
|
800
|
-
<div class="text-sm text-gray-500">Commit: ${row.commit_message || '(none)'}</div>
|
|
801
|
-
</div>
|
|
802
|
-
${row.forced ? '<span class="text-xs bg-orange-100 text-orange-800 px-2 py-1 rounded">Forced</span>' : ''}
|
|
803
|
-
${row.dropped ? '<span class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded">Dropped</span>' : ''}
|
|
804
|
-
</div>
|
|
805
|
-
</div>
|
|
806
|
-
`).join('');
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
function formatHistorySummary(series) {
|
|
810
|
-
if (!series || series.length === 0) {
|
|
811
|
-
return '<p class="text-gray-500">No activity for the selected range.</p>';
|
|
812
|
-
}
|
|
813
|
-
return series.map(item => `
|
|
814
|
-
<div class="flex justify-between">
|
|
815
|
-
<span>${item.period}</span>
|
|
816
|
-
<span class="font-medium">${item.count}</span>
|
|
817
|
-
</div>
|
|
818
|
-
`).join('');
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
async function fetchJson(path, params = {}) {
|
|
822
|
-
const url = new URL(path, window.location.origin);
|
|
823
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
824
|
-
if (value !== undefined && value !== null && value !== '') {
|
|
825
|
-
url.searchParams.set(key, value);
|
|
826
|
-
}
|
|
827
|
-
});
|
|
828
|
-
const res = await fetch(url.toString());
|
|
829
|
-
if (!res.ok) {
|
|
830
|
-
throw new Error(`Request failed: ${res.status}`);
|
|
831
|
-
}
|
|
832
|
-
return res.json();
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
function collectFilters() {
|
|
836
|
-
state.userId = controls.userId.value.trim();
|
|
837
|
-
state.startDate = controls.startDate.value;
|
|
838
|
-
state.endDate = controls.endDate.value;
|
|
839
|
-
state.frequency = controls.frequency.value;
|
|
840
|
-
state.pageSize = Number(controls.pageSize.value) || 20;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
function resetFilters() {
|
|
844
|
-
controls.userId.value = "";
|
|
845
|
-
controls.startDate.value = "";
|
|
846
|
-
controls.endDate.value = "";
|
|
847
|
-
controls.frequency.value = "daily";
|
|
848
|
-
controls.pageSize.value = "20";
|
|
849
|
-
state.userId = "";
|
|
850
|
-
state.startDate = "";
|
|
851
|
-
state.endDate = "";
|
|
852
|
-
state.frequency = "daily";
|
|
853
|
-
state.page = 1;
|
|
854
|
-
state.pageSize = 20;
|
|
855
|
-
load();
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
function updatePagination(total, page, pageSize) {
|
|
859
|
-
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
860
|
-
state.totalPages = totalPages;
|
|
861
|
-
controls.pageInfo.textContent = `Page ${page} of ${totalPages} (${total} entries)`;
|
|
862
|
-
controls.prevPage.disabled = page <= 1;
|
|
863
|
-
controls.nextPage.disabled = page >= totalPages;
|
|
864
|
-
controls.pagination.classList.toggle("hidden", total === 0);
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
function updateHistorySummary(series) {
|
|
868
|
-
if (!series || series.length === 0) {
|
|
869
|
-
controls.historySummaryCard.classList.add("hidden");
|
|
870
|
-
controls.historySummaryContent.innerHTML = "";
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
controls.historySummaryContent.innerHTML = formatHistorySummary(series);
|
|
874
|
-
const freqLabel = frequencyLabels[state.frequency] || "Daily";
|
|
875
|
-
const rangeParts = [];
|
|
876
|
-
if (state.startDate) rangeParts.push(`from ${state.startDate}`);
|
|
877
|
-
if (state.endDate) rangeParts.push(`to ${state.endDate}`);
|
|
878
|
-
controls.historySummaryMeta.textContent = `${freqLabel}${rangeParts.length ? ` • ${rangeParts.join(" ")}` : ""}`;
|
|
879
|
-
controls.historySummaryCard.classList.remove("hidden");
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
async function load() {
|
|
883
|
-
const userId = state.userId || "default";
|
|
884
|
-
|
|
885
|
-
// Fetch version
|
|
886
|
-
fetchJson('/api/version').then(({ version }) => {
|
|
887
|
-
const verEl = el('appVersion');
|
|
888
|
-
if (verEl && version) {
|
|
889
|
-
verEl.textContent = `v${version}`;
|
|
890
|
-
verEl.classList.remove('hidden');
|
|
891
|
-
}
|
|
892
|
-
}).catch(() => { }); // Ignore version fetch errors
|
|
893
|
-
|
|
894
|
-
try {
|
|
895
|
-
const historyParams = {
|
|
896
|
-
user: userId,
|
|
897
|
-
page: state.page,
|
|
898
|
-
pageSize: state.pageSize,
|
|
899
|
-
startDate: state.startDate,
|
|
900
|
-
endDate: state.endDate,
|
|
901
|
-
};
|
|
902
|
-
const summaryParams = {
|
|
903
|
-
user: userId,
|
|
904
|
-
startDate: state.startDate,
|
|
905
|
-
endDate: state.endDate,
|
|
906
|
-
frequency: state.frequency,
|
|
907
|
-
};
|
|
908
|
-
const [{ summary }, historyData, { summary: historySummary }] = await Promise.all([
|
|
909
|
-
fetchJson('/api/summary', { user: userId }),
|
|
910
|
-
fetchJson('/api/history', historyParams),
|
|
911
|
-
fetchJson('/api/history-summary', summaryParams),
|
|
912
|
-
]);
|
|
913
|
-
|
|
914
|
-
el('summaryContent').innerHTML = formatSummary(summary);
|
|
915
|
-
el('historyContent').innerHTML = formatHistory(historyData.entries);
|
|
916
|
-
updatePagination(historyData.total, historyData.page, historyData.pageSize);
|
|
917
|
-
updateHistorySummary(historySummary);
|
|
918
|
-
|
|
919
|
-
el('summarySection').classList.remove('hidden');
|
|
920
|
-
el('historySection').classList.remove('hidden');
|
|
921
|
-
} catch (error) {
|
|
922
|
-
el('summaryContent').innerHTML = `<p class="text-red-500">Failed to load summary: ${error.message}</p>`;
|
|
923
|
-
el('historyContent').innerHTML = '<p class="text-gray-500">History unavailable.</p>';
|
|
924
|
-
controls.pagination.classList.add("hidden");
|
|
925
|
-
controls.historySummaryCard.classList.add("hidden");
|
|
926
|
-
el('summarySection').classList.remove('hidden');
|
|
927
|
-
el('historySection').classList.remove('hidden');
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
controls.applyFilters.addEventListener('click', () => {
|
|
932
|
-
collectFilters();
|
|
933
|
-
state.page = 1;
|
|
934
|
-
load();
|
|
935
|
-
});
|
|
936
|
-
controls.resetFilters.addEventListener('click', resetFilters);
|
|
937
|
-
controls.userId.addEventListener('keydown', (e) => {
|
|
938
|
-
if (e.key === 'Enter') {
|
|
939
|
-
collectFilters();
|
|
940
|
-
state.page = 1;
|
|
941
|
-
load();
|
|
942
|
-
}
|
|
943
|
-
});
|
|
944
|
-
controls.prevPage.addEventListener('click', () => {
|
|
945
|
-
if (state.page > 1) {
|
|
946
|
-
state.page -= 1;
|
|
947
|
-
load();
|
|
948
|
-
}
|
|
949
|
-
});
|
|
950
|
-
controls.nextPage.addEventListener('click', () => {
|
|
951
|
-
if (state.page < state.totalPages) {
|
|
952
|
-
state.page += 1;
|
|
953
|
-
load();
|
|
954
|
-
}
|
|
955
|
-
});
|
|
956
|
-
|
|
957
|
-
const docModal = el('docModal');
|
|
958
|
-
const docModalContent = el('docModalContent');
|
|
959
|
-
const docModalTitle = el('docModalTitle');
|
|
960
|
-
const docModalSubtitle = el('docModalSubtitle');
|
|
961
|
-
const docModalClose = el('docModalClose');
|
|
962
|
-
const docModalBackdrop = el('docModalBackdrop');
|
|
963
|
-
|
|
964
|
-
function closeDocModal() {
|
|
965
|
-
docModal.classList.add('hidden');
|
|
966
|
-
docModalContent.innerHTML = '<p class="text-sm text-slate-500">Loading…</p>';
|
|
967
|
-
docModalSubtitle.textContent = '';
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
async function openDocModal(docKey, headingText) {
|
|
971
|
-
try {
|
|
972
|
-
docModal.classList.remove('hidden');
|
|
973
|
-
docModalTitle.textContent = docKey;
|
|
974
|
-
docModalContent.innerHTML = '<p class="text-sm text-slate-500">Loading…</p>';
|
|
975
|
-
const response = await fetch(`/api/docs?doc=${encodeURIComponent(docKey)}`);
|
|
976
|
-
if (!response.ok) {
|
|
977
|
-
throw new Error(`Failed to load document (${response.status})`);
|
|
978
|
-
}
|
|
979
|
-
const payload = await response.json();
|
|
980
|
-
const rawContent = payload.content || '';
|
|
981
|
-
const format = (payload.format || 'markdown').toLowerCase();
|
|
982
|
-
const html = format === 'html' ? rawContent : marked.parse(rawContent);
|
|
983
|
-
docModalContent.innerHTML = html;
|
|
984
|
-
|
|
985
|
-
lucide.createIcons();
|
|
986
|
-
|
|
987
|
-
if (headingText) {
|
|
988
|
-
const headings = docModalContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
|
989
|
-
for (const heading of headings) {
|
|
990
|
-
if (heading.textContent.trim().toLowerCase().includes(headingText.toLowerCase())) {
|
|
991
|
-
heading.classList.add('bg-indigo-50', 'border-l-4', 'border-indigo-400', 'pl-3', 'py-1');
|
|
992
|
-
heading.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
993
|
-
docModalSubtitle.textContent = `Jumped to section: ${heading.textContent.trim()}`;
|
|
994
|
-
break;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
} catch (error) {
|
|
999
|
-
docModalContent.innerHTML = `<p class="text-sm text-rose-600">${error.message}</p>`;
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
document.querySelectorAll('.doc-link').forEach((button) => {
|
|
1004
|
-
button.addEventListener('click', () => {
|
|
1005
|
-
const docKey = button.dataset.doc;
|
|
1006
|
-
const heading = button.dataset.docHeading;
|
|
1007
|
-
openDocModal(docKey, heading);
|
|
1008
|
-
});
|
|
1009
|
-
});
|
|
1010
|
-
|
|
1011
|
-
document.querySelectorAll('.scroll-link').forEach((button) => {
|
|
1012
|
-
button.addEventListener('click', () => {
|
|
1013
|
-
const target = button.dataset.scrollTarget;
|
|
1014
|
-
if (!target) return;
|
|
1015
|
-
const elTarget = document.querySelector(target);
|
|
1016
|
-
if (elTarget) {
|
|
1017
|
-
elTarget.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
1018
|
-
}
|
|
1019
|
-
});
|
|
1020
|
-
});
|
|
1021
|
-
|
|
1022
|
-
docModalClose.addEventListener('click', closeDocModal);
|
|
1023
|
-
docModalBackdrop.addEventListener('click', closeDocModal);
|
|
1024
|
-
document.addEventListener('keydown', (event) => {
|
|
1025
|
-
if (event.key === 'Escape' && !docModal.classList.contains('hidden')) {
|
|
1026
|
-
closeDocModal();
|
|
1027
|
-
}
|
|
1028
|
-
});
|
|
1029
|
-
|
|
1030
|
-
const refreshButton = document.getElementById('refreshDashboardBtn');
|
|
1031
|
-
if (refreshButton) {
|
|
1032
|
-
refreshButton.addEventListener('click', () => {
|
|
1033
|
-
collectFilters();
|
|
1034
|
-
state.page = 1;
|
|
1035
|
-
load();
|
|
1036
|
-
});
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
// Initialize Lucide icons and initial load
|
|
1040
|
-
lucide.createIcons();
|
|
1041
|
-
collectFilters();
|
|
1042
|
-
load();
|
|
1043
|
-
</script>
|
|
1044
|
-
</body>
|
|
1045
|
-
|
|
1046
|
-
</html>
|