@programinglive/dev-workflow-mcp-server 1.4.6 → 1.5.1
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/CHANGELOG.md +114 -0
- package/docs/NETLIFY_DEPLOYMENT.md +125 -0
- package/docs/product/PRD.md +4 -2
- package/docs/release-notes/RELEASE_NOTES.md +32 -0
- package/docs/web-dashboard.md +12 -0
- package/package.json +1 -1
- package/server.json +13 -3
- package/tests/build.test.js +30 -0
- package/tests/mcpRegistry.test.js +13 -3
- package/web/app/api/history/route.ts +10 -17
- package/web/app/api/summary/route.ts +11 -13
- package/web/app/api/version/route.ts +4 -11
- package/web/netlify.toml +6 -0
- package/web/next.config.ts +1 -2
- package/web/package-lock.json +17 -428
- package/web/package.json +0 -1
- 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 +0 -1
- package/web-legacy/public/docs/EXAMPLES.html +0 -496
- package/web-legacy/public/docs/GETTING-STARTED.html +0 -318
- package/web-legacy/public/docs/README.html +0 -620
- package/web-legacy/public/docs/RELEASE_NOTES.html +0 -275
- package/web-legacy/public/docs/TROUBLESHOOTING.html +0 -627
- package/web-legacy/public/docs/WORKFLOW-TEMPLATES.html +0 -676
- package/web-legacy/public/docs/web-dashboard.html +0 -243
- package/web-legacy/public/index.html +0 -223
- package/web-legacy/public/input.css +0 -80
- package/web-legacy/public/main.js +0 -167
- package/web-legacy/public/output.css +0 -1559
- package/web-legacy/server.js +0 -207
|
@@ -1,167 +0,0 @@
|
|
|
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
|
-
}
|