@programinglive/dev-workflow-mcp-server 1.5.0 → 1.5.2

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.
Files changed (99) hide show
  1. package/.agent/workflows/dev-workflow-bugfix.md +250 -250
  2. package/.agent/workflows/dev-workflow-feature.md +201 -201
  3. package/.agent/workflows/dev-workflow-full-cycle.md +400 -400
  4. package/.agent/workflows/dev-workflow-refactor.md +238 -238
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +34 -34
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +25 -25
  7. package/.github/pull_request_template.md +22 -22
  8. package/.github/workflows/npm-publish.yml +50 -47
  9. package/.husky/commit-msg +0 -0
  10. package/CHANGELOG.md +750 -491
  11. package/CODE_OF_CONDUCT.md +79 -79
  12. package/CONTRIBUTING.md +60 -60
  13. package/LICENSE +21 -21
  14. package/README.md +632 -609
  15. package/SECURITY.md +20 -20
  16. package/db/index.js +204 -204
  17. package/docs/NETLIFY_DEPLOYMENT.md +125 -0
  18. package/docs/PLESK_DEPLOYMENT.md +170 -0
  19. package/docs/WORKFLOW-BEST-PRACTICES.md +58 -0
  20. package/docs/antigravity/EXAMPLES.md +535 -535
  21. package/docs/antigravity/GETTING-STARTED.md +292 -292
  22. package/docs/antigravity/TROUBLESHOOTING.md +742 -742
  23. package/docs/antigravity/WALKTHROUGH.md +25 -25
  24. package/docs/antigravity/WORKFLOW-TEMPLATES.md +670 -670
  25. package/docs/product/PRD.md +67 -64
  26. package/docs/release-notes/RELEASE_NOTES.md +226 -132
  27. package/docs/web-dashboard.md +175 -163
  28. package/exec.js +49 -49
  29. package/index.js +279 -279
  30. package/install.js +73 -73
  31. package/package.json +11 -9
  32. package/release-wrapper.js +192 -157
  33. package/scripts/build-docs.js +63 -63
  34. package/scripts/hello-world.js +1 -1
  35. package/scripts/release.cjs +252 -252
  36. package/scripts/update-release-notes.cjs +178 -182
  37. package/server.json +23 -0
  38. package/tailwind.config.js +8 -10
  39. package/tests/build.test.js +83 -48
  40. package/tests/exec.test.js +35 -35
  41. package/tests/handlers.test.js +1058 -980
  42. package/tests/hello-world.test.js +13 -13
  43. package/tests/mcpRegistry.test.js +65 -0
  44. package/tests/release-wrapper.test.js +107 -105
  45. package/tests/workflowState.test.js +505 -502
  46. package/tools/definitions.js +332 -332
  47. package/tools/handlers.js +1019 -1019
  48. package/vite.config.js +43 -43
  49. package/vite.web.config.js +23 -0
  50. package/web/README.md +36 -0
  51. package/web/app/docs/page.tsx +202 -0
  52. package/web/app/favicon.ico +0 -0
  53. package/web/app/globals.css +91 -0
  54. package/web/app/layout.tsx +36 -0
  55. package/web/app/page.tsx +15 -0
  56. package/web/components/ApiReference.tsx +20 -0
  57. package/web/components/Features.tsx +61 -0
  58. package/web/components/Footer.tsx +9 -0
  59. package/web/components/Hero.tsx +96 -0
  60. package/web/components/History.tsx +143 -0
  61. package/web/components/Navbar.tsx +64 -0
  62. package/web/components/Terminal.tsx +114 -0
  63. package/web/eslint.config.mjs +18 -0
  64. package/web/lib/db.js +131 -0
  65. package/web/lib/docs.js +73 -0
  66. package/web/netlify.toml +3 -0
  67. package/web/next.config.ts +12 -0
  68. package/web/package-lock.json +6560 -0
  69. package/web/package.json +28 -0
  70. package/web/postcss.config.mjs +9 -0
  71. package/web/public/assets/android-chrome-192x192.png +0 -0
  72. package/web/public/assets/android-chrome-512x512.png +0 -0
  73. package/web/public/assets/apple-touch-icon.png +0 -0
  74. package/web/public/assets/favicon-16x16.png +0 -0
  75. package/web/public/assets/favicon-32x32.png +0 -0
  76. package/web/public/assets/favicon.ico +0 -0
  77. package/web/public/assets/favicon.png +0 -0
  78. package/web/public/assets/logo.png +0 -0
  79. package/web/public/assets/og-preview.png +0 -0
  80. package/web/public/assets/site.webmanifest +1 -0
  81. package/web/public/file.svg +1 -0
  82. package/web/public/globe.svg +1 -0
  83. package/web/public/next.svg +1 -0
  84. package/web/public/vercel.svg +1 -0
  85. package/web/public/window.svg +1 -0
  86. package/web/server.js +31 -159
  87. package/web/tailwind.config.ts +19 -0
  88. package/web/tsconfig.json +42 -0
  89. package/workflow-state.js +612 -626
  90. package/dist/docs/EXAMPLES.html +0 -411
  91. package/dist/docs/GETTING-STARTED.html +0 -233
  92. package/dist/docs/README.html +0 -535
  93. package/dist/docs/RELEASE_NOTES.html +0 -167
  94. package/dist/docs/TROUBLESHOOTING.html +0 -542
  95. package/dist/docs/WORKFLOW-TEMPLATES.html +0 -591
  96. package/dist/docs/web-dashboard.html +0 -158
  97. package/web/public/index.html +0 -1046
  98. package/web/public/input.css +0 -3
  99. package/web/public/output.css +0 -1
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "web",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "eslint"
10
+ },
11
+ "dependencies": {
12
+ "lucide-react": "^0.555.0",
13
+ "next": "16.0.4",
14
+ "react": "19.2.0",
15
+ "react-dom": "19.2.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^20",
19
+ "@types/react": "^19",
20
+ "@types/react-dom": "^19",
21
+ "autoprefixer": "^10.4.22",
22
+ "eslint": "^9",
23
+ "eslint-config-next": "16.0.4",
24
+ "postcss": "^8.5.6",
25
+ "tailwindcss": "^3.4.18",
26
+ "typescript": "^5"
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ autoprefixer: {},
6
+ },
7
+ };
8
+
9
+ export default config;
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
package/web/server.js CHANGED
@@ -1,159 +1,31 @@
1
- import { createServer } from "http";
2
- import { readFile, access } from "fs/promises";
3
- import { fileURLToPath } from "url";
4
- import { dirname, join } from "path";
5
- import getPort from "get-port";
6
- import { getHistoryForUser, getSummaryForUser, getHistorySummary } from "../db/index.js";
7
-
8
- const __filename = fileURLToPath(import.meta.url);
9
- const __dirname = dirname(__filename);
10
- const projectRoot = join(__dirname, "..");
11
-
12
- const docSources = {
13
- "README.md": {
14
- markdown: join(projectRoot, "README.md"),
15
- html: join(projectRoot, "dist", "docs", "README.html"),
16
- },
17
- "web-dashboard.md": {
18
- markdown: join(projectRoot, "docs", "web-dashboard.md"),
19
- html: join(projectRoot, "dist", "docs", "web-dashboard.html"),
20
- },
21
- "GETTING-STARTED.md": {
22
- markdown: join(projectRoot, "docs", "antigravity", "GETTING-STARTED.md"),
23
- html: join(projectRoot, "dist", "docs", "GETTING-STARTED.html"),
24
- },
25
- "EXAMPLES.md": {
26
- markdown: join(projectRoot, "docs", "antigravity", "EXAMPLES.md"),
27
- html: join(projectRoot, "dist", "docs", "EXAMPLES.html"),
28
- },
29
- "WORKFLOW-TEMPLATES.md": {
30
- markdown: join(projectRoot, "docs", "antigravity", "WORKFLOW-TEMPLATES.md"),
31
- html: join(projectRoot, "dist", "docs", "WORKFLOW-TEMPLATES.html"),
32
- },
33
- "TROUBLESHOOTING.md": {
34
- markdown: join(projectRoot, "docs", "antigravity", "TROUBLESHOOTING.md"),
35
- html: join(projectRoot, "dist", "docs", "TROUBLESHOOTING.html"),
36
- },
37
- "RELEASE_NOTES.md": {
38
- markdown: join(projectRoot, "docs", "release-notes", "RELEASE_NOTES.md"),
39
- html: join(projectRoot, "dist", "docs", "RELEASE_NOTES.html"),
40
- },
41
- };
42
-
43
- async function resolveDocContent(docKey) {
44
- const entry = docSources[docKey];
45
- if (!entry) {
46
- return { exists: false };
47
- }
48
-
49
- // Try HTML first, fall back to Markdown in development or if HTML missing.
50
- const candidates = [entry.html, entry.markdown];
51
- for (const candidate of candidates) {
52
- try {
53
- await access(candidate);
54
- const content = await readFile(candidate, "utf-8");
55
- const format = candidate.endsWith(".html") ? "html" : "markdown";
56
- return { exists: true, content, format };
57
- } catch {
58
- // try next candidate
59
- }
60
- }
61
-
62
- return { exists: false };
63
- }
64
-
65
- function getPreferredPort() {
66
- const fromEnv = process.env.PORT || process.env.DEV_WORKFLOW_WEB_PORT;
67
-
68
- if (!fromEnv) {
69
- return null;
70
- }
71
-
72
- const parsed = Number(fromEnv);
73
- return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
74
- }
75
-
76
- async function start() {
77
- const preferred = getPreferredPort();
78
- const PORT = preferred ?? await getPort({ port: 3111 });
79
-
80
- const server = createServer(async (req, res) => {
81
- try {
82
- const url = new URL(req.url, `http://${req.headers.host}`);
83
- const userId = url.searchParams.get("user") || "default";
84
-
85
- if (req.method === "GET" && url.pathname === "/output.css") {
86
- const css = await readFile(join(__dirname, "public", "output.css"), "utf-8");
87
- res.writeHead(200, { "Content-Type": "text/css" });
88
- res.end(css);
89
- } else if (req.method === "GET" && url.pathname === "/") {
90
- const html = await readFile(join(__dirname, "public", "index.html"), "utf-8");
91
- res.writeHead(200, { "Content-Type": "text/html" });
92
- res.end(html);
93
- } else if (req.method === "GET" && url.pathname === "/api/summary") {
94
- const summary = getSummaryForUser(userId);
95
- res.writeHead(200, { "Content-Type": "application/json" });
96
- res.end(JSON.stringify({ summary }));
97
- } else if (req.method === "GET" && url.pathname === "/api/history") {
98
- const page = Number(url.searchParams.get("page") || "1");
99
- const pageSize = Number(url.searchParams.get("pageSize") || "20");
100
- const startDate = url.searchParams.get("startDate") || undefined;
101
- const endDate = url.searchParams.get("endDate") || undefined;
102
- const history = getHistoryForUser(userId, { page, pageSize, startDate, endDate });
103
- res.writeHead(200, { "Content-Type": "application/json" });
104
- res.end(JSON.stringify(history));
105
- } else if (req.method === "GET" && url.pathname === "/api/history-summary") {
106
- const startDate = url.searchParams.get("startDate") || undefined;
107
- const endDate = url.searchParams.get("endDate") || undefined;
108
- const frequency = url.searchParams.get("frequency") || "daily";
109
- const summary = getHistorySummary(userId, { startDate, endDate, frequency });
110
- res.writeHead(200, { "Content-Type": "application/json" });
111
- res.end(JSON.stringify({ summary }));
112
- } else if (req.method === "GET" && url.pathname === "/api/docs") {
113
- const rawDocKey = url.searchParams.get("doc");
114
- const availableDocs = Object.keys(docSources);
115
-
116
- if (!rawDocKey) {
117
- res.writeHead(200, { "Content-Type": "application/json" });
118
- res.end(JSON.stringify({ docs: availableDocs }));
119
- return;
120
- }
121
-
122
- const docKey = rawDocKey.trim();
123
- const resolvedKey = availableDocs.find((key) => key.toLowerCase() === docKey.toLowerCase());
124
- if (!resolvedKey) {
125
- res.writeHead(404, { "Content-Type": "application/json" });
126
- res.end(JSON.stringify({ error: "Document not found", requested: docKey, available: availableDocs }));
127
- return;
128
- }
129
-
130
- const result = await resolveDocContent(resolvedKey);
131
- if (!result.exists) {
132
- res.writeHead(500, { "Content-Type": "application/json" });
133
- res.end(JSON.stringify({ error: "Document asset is missing" }));
134
- return;
135
- }
136
-
137
- res.writeHead(200, { "Content-Type": "application/json" });
138
- res.end(JSON.stringify({ doc: resolvedKey, content: result.content, format: result.format }));
139
- } else if (req.method === "GET" && url.pathname === "/api/version") {
140
- const packageJson = await readFile(join(projectRoot, "package.json"), "utf-8");
141
- const { version } = JSON.parse(packageJson);
142
- res.writeHead(200, { "Content-Type": "application/json" });
143
- res.end(JSON.stringify({ version }));
144
- } else {
145
- res.writeHead(404, { "Content-Type": "text/plain" });
146
- res.end("Not found");
147
- }
148
- } catch (err) {
149
- res.writeHead(500, { "Content-Type": "text/plain" });
150
- res.end(err.message);
151
- }
152
- });
153
-
154
- server.listen(PORT, () => {
155
- console.log(`🌐 Dev Workflow Dashboard running at http://localhost:${PORT}`);
156
- });
157
- }
158
-
159
- start();
1
+ const { createServer } = require('http');
2
+ const { parse } = require('url');
3
+ const next = require('next');
4
+
5
+ const dev = process.env.NODE_ENV !== 'production';
6
+ const hostname = 'localhost';
7
+ const port = process.env.PORT || 3000;
8
+
9
+ // Initialize Next.js app
10
+ const app = next({ dev, hostname, port });
11
+ const handle = app.getRequestHandler();
12
+
13
+ app.prepare().then(() => {
14
+ createServer(async (req, res) => {
15
+ try {
16
+ const parsedUrl = parse(req.url, true);
17
+ await handle(req, res, parsedUrl);
18
+ } catch (err) {
19
+ console.error('Error occurred handling', req.url, err);
20
+ res.statusCode = 500;
21
+ res.end('internal server error');
22
+ }
23
+ })
24
+ .once('error', (err) => {
25
+ console.error(err);
26
+ process.exit(1);
27
+ })
28
+ .listen(port, () => {
29
+ console.log(`> Ready on http://${hostname}:${port}`);
30
+ });
31
+ });
@@ -0,0 +1,19 @@
1
+ import type { Config } from "tailwindcss";
2
+
3
+ const config: Config = {
4
+ content: [
5
+ "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6
+ "./components/**/*.{js,ts,jsx,tsx,mdx}",
7
+ "./app/**/*.{js,ts,jsx,tsx,mdx}",
8
+ ],
9
+ theme: {
10
+ extend: {
11
+ colors: {
12
+ background: "var(--background)",
13
+ foreground: "var(--foreground)",
14
+ },
15
+ },
16
+ },
17
+ plugins: [],
18
+ };
19
+ export default config;
@@ -0,0 +1,42 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "noEmit": true,
13
+ "esModuleInterop": true,
14
+ "module": "esnext",
15
+ "moduleResolution": "bundler",
16
+ "resolveJsonModule": true,
17
+ "isolatedModules": true,
18
+ "jsx": "react-jsx",
19
+ "incremental": true,
20
+ "plugins": [
21
+ {
22
+ "name": "next"
23
+ }
24
+ ],
25
+ "paths": {
26
+ "@/*": [
27
+ "./*"
28
+ ]
29
+ }
30
+ },
31
+ "include": [
32
+ "next-env.d.ts",
33
+ "**/*.ts",
34
+ "**/*.tsx",
35
+ ".next/types/**/*.ts",
36
+ ".next/dev/types/**/*.ts",
37
+ "**/*.mts"
38
+ ],
39
+ "exclude": [
40
+ "node_modules"
41
+ ]
42
+ }