@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.
Files changed (87) hide show
  1. package/.github/workflows/npm-publish.yml +3 -0
  2. package/CHANGELOG.md +125 -2
  3. package/README.md +1 -1
  4. package/docs/PLESK_DEPLOYMENT.md +170 -0
  5. package/docs/WORKFLOW-BEST-PRACTICES.md +58 -0
  6. package/docs/release-notes/RELEASE_NOTES.md +40 -0
  7. package/package.json +7 -6
  8. package/release-wrapper.js +68 -33
  9. package/scripts/update-release-notes.cjs +14 -18
  10. package/tailwind.config.js +2 -4
  11. package/tests/build.test.js +3 -3
  12. package/tests/handlers.test.js +78 -0
  13. package/tests/release-wrapper.test.js +2 -0
  14. package/tests/workflowState.test.js +7 -4
  15. package/tools/definitions.js +2 -2
  16. package/tools/handlers.js +2 -2
  17. package/vite.web.config.js +23 -0
  18. package/web/README.md +36 -0
  19. package/web/app/api/docs/route.ts +32 -0
  20. package/web/app/api/history/route.ts +19 -0
  21. package/web/app/api/npm-downloads/route.ts +21 -0
  22. package/web/app/api/summary/route.ts +15 -0
  23. package/web/app/api/version/route.ts +15 -0
  24. package/web/app/docs/page.tsx +202 -0
  25. package/web/app/favicon.ico +0 -0
  26. package/web/app/globals.css +91 -0
  27. package/web/app/layout.tsx +36 -0
  28. package/web/app/page.tsx +15 -0
  29. package/web/components/ApiReference.tsx +20 -0
  30. package/web/components/Features.tsx +61 -0
  31. package/web/components/Footer.tsx +9 -0
  32. package/web/components/Hero.tsx +91 -0
  33. package/web/components/History.tsx +143 -0
  34. package/web/components/Navbar.tsx +64 -0
  35. package/web/components/Terminal.tsx +114 -0
  36. package/web/eslint.config.mjs +18 -0
  37. package/web/lib/db.js +131 -0
  38. package/web/lib/docs.js +73 -0
  39. package/web/next.config.ts +8 -0
  40. package/web/package-lock.json +6971 -0
  41. package/web/package.json +29 -0
  42. package/web/postcss.config.mjs +9 -0
  43. package/web/public/assets/android-chrome-192x192.png +0 -0
  44. package/web/public/assets/android-chrome-512x512.png +0 -0
  45. package/web/public/assets/apple-touch-icon.png +0 -0
  46. package/web/public/assets/favicon-16x16.png +0 -0
  47. package/web/public/assets/favicon-32x32.png +0 -0
  48. package/web/public/assets/favicon.ico +0 -0
  49. package/web/public/assets/favicon.png +0 -0
  50. package/web/public/assets/logo.png +0 -0
  51. package/web/public/assets/og-preview.png +0 -0
  52. package/web/public/assets/site.webmanifest +1 -0
  53. package/web/public/file.svg +1 -0
  54. package/web/public/globe.svg +1 -0
  55. package/web/public/next.svg +1 -0
  56. package/web/public/vercel.svg +1 -0
  57. package/web/public/window.svg +1 -0
  58. package/web/server.js +30 -158
  59. package/web/tailwind.config.ts +19 -0
  60. package/web/tsconfig.json +42 -0
  61. package/web-legacy/public/assets/android-chrome-192x192.png +0 -0
  62. package/web-legacy/public/assets/android-chrome-512x512.png +0 -0
  63. package/web-legacy/public/assets/apple-touch-icon.png +0 -0
  64. package/web-legacy/public/assets/favicon-16x16.png +0 -0
  65. package/web-legacy/public/assets/favicon-32x32.png +0 -0
  66. package/web-legacy/public/assets/favicon.ico +0 -0
  67. package/web-legacy/public/assets/favicon.png +0 -0
  68. package/web-legacy/public/assets/logo.png +0 -0
  69. package/web-legacy/public/assets/og-preview.png +0 -0
  70. package/web-legacy/public/assets/site.webmanifest +1 -0
  71. package/{dist → web-legacy/public}/docs/EXAMPLES.html +87 -2
  72. package/{dist → web-legacy/public}/docs/GETTING-STARTED.html +87 -2
  73. package/{dist → web-legacy/public}/docs/README.html +87 -2
  74. package/web-legacy/public/docs/RELEASE_NOTES.html +275 -0
  75. package/{dist → web-legacy/public}/docs/TROUBLESHOOTING.html +87 -2
  76. package/{dist → web-legacy/public}/docs/WORKFLOW-TEMPLATES.html +87 -2
  77. package/{dist → web-legacy/public}/docs/web-dashboard.html +87 -2
  78. package/web-legacy/public/index.html +223 -0
  79. package/web-legacy/public/input.css +80 -0
  80. package/web-legacy/public/main.js +167 -0
  81. package/web-legacy/public/output.css +1559 -0
  82. package/web-legacy/server.js +207 -0
  83. package/workflow-state.js +11 -25
  84. package/dist/docs/RELEASE_NOTES.html +0 -167
  85. package/web/public/index.html +0 -1046
  86. package/web/public/input.css +0 -3
  87. package/web/public/output.css +0 -1
@@ -40,6 +40,84 @@ function createRequest(name, args) {
40
40
  };
41
41
  }
42
42
 
43
+ test("run_tests guidance mentions core documentation types", async () => {
44
+ await withWorkflowState(async (workflowState) => {
45
+ workflowState.state.bugFixed = true;
46
+ workflowState.state.testsCreated = true;
47
+ await workflowState.save();
48
+
49
+ const response = await handleToolCall({
50
+ request: createRequest("run_tests", {
51
+ passed: true,
52
+ testCommand: "npm test",
53
+ }),
54
+ normalizeRequestArgs,
55
+ workflowState,
56
+ exec: async () => ({ stdout: "" }),
57
+ git: {
58
+ hasWorkingChanges: async () => false,
59
+ hasStagedChanges: async () => false,
60
+ hasTestChanges: async () => true,
61
+ getStagedChanges: async () => [],
62
+ getCurrentBranch: async () => "main",
63
+ getPrimaryBranch: async () => "main",
64
+ getLastCommitMessage: async () => "",
65
+ workingTreeSummary: () => ({ hasChanges: false, lines: [] }),
66
+ },
67
+ utils,
68
+ });
69
+
70
+ const text = response.content[0].text;
71
+ assert.ok(
72
+ text.includes("create or update documentation using 'create_documentation'"),
73
+ "run_tests guidance should mention create or update documentation",
74
+ );
75
+ assert.ok(
76
+ text.includes('"PRD", "README", "RELEASE_NOTES"'),
77
+ "run_tests guidance should list core documentation types",
78
+ );
79
+ });
80
+ });
81
+
82
+ test("create_documentation accepts PRD and records created/updated message", async () => {
83
+ await withWorkflowState(async (workflowState) => {
84
+ workflowState.state.testsPassed = true;
85
+ await workflowState.save();
86
+
87
+ const response = await handleToolCall({
88
+ request: createRequest("create_documentation", {
89
+ documentationType: "PRD",
90
+ summary: "Updated PRD for documentation workflow expectations",
91
+ }),
92
+ normalizeRequestArgs,
93
+ workflowState,
94
+ exec: async () => ({ stdout: "" }),
95
+ git: {
96
+ hasWorkingChanges: async () => false,
97
+ hasStagedChanges: async () => false,
98
+ hasTestChanges: async () => true,
99
+ getStagedChanges: async () => [],
100
+ getCurrentBranch: async () => "main",
101
+ getPrimaryBranch: async () => "main",
102
+ getLastCommitMessage: async () => "",
103
+ workingTreeSummary: () => ({ hasChanges: false, lines: [] }),
104
+ },
105
+ utils,
106
+ });
107
+
108
+ assert.equal(workflowState.state.documentationCreated, true);
109
+ assert.equal(workflowState.state.documentationType, "PRD");
110
+ assert.equal(
111
+ workflowState.state.documentationSummary,
112
+ "Updated PRD for documentation workflow expectations",
113
+ );
114
+ assert.ok(
115
+ response.content[0].text.includes("Documentation created/updated!"),
116
+ "create_documentation response should mention created/updated",
117
+ );
118
+ });
119
+ });
120
+
43
121
  test("commit_and_push commits changes and pushes", async () => {
44
122
  await withWorkflowState(async (workflowState) => {
45
123
  workflowState.state.readyToCommit = true;
@@ -18,6 +18,8 @@ async function runWrapper({ state, args = ["patch"], env = {} }) {
18
18
  const statePath = path.join(stateDir, "workflow-state.json");
19
19
  await mkdir(stateDir, { recursive: true });
20
20
  await writeFile(statePath, JSON.stringify(state, null, 2));
21
+ // Create package.json so resolveStateFile recognizes this as a project root
22
+ await writeFile(path.join(dir, "package.json"), JSON.stringify({ name: "test-project" }));
21
23
 
22
24
  const childEnv = {
23
25
  ...process.env,
@@ -67,14 +67,16 @@ test("resolveStateFile prefers current working directory when multiple project m
67
67
 
68
68
  const state = new TempWorkflowState();
69
69
  const resolvedStateFile = state.stateFile;
70
+ const resolvedProjectA = await realpath(projectA);
71
+ const resolvedProjectB = await realpath(projectB);
70
72
 
71
73
  assert.ok(
72
- resolvedStateFile.startsWith(path.join(projectB, ".state", "users")),
74
+ resolvedStateFile.startsWith(path.join(resolvedProjectB, ".state", "users")),
73
75
  "State file should resolve under the current working directory's project"
74
76
  );
75
77
 
76
78
  assert.ok(
77
- !resolvedStateFile.startsWith(path.join(projectA, ".state")),
79
+ !resolvedStateFile.startsWith(path.join(resolvedProjectA, ".state")),
78
80
  "State file should not use INIT_CWD project when cwd has its own markers"
79
81
  );
80
82
  } finally {
@@ -303,9 +305,11 @@ test("WorkflowState resolves state file relative to project root", async () => {
303
305
  if (devStateWasSet) {
304
306
  delete process.env.DEV_WORKFLOW_STATE_FILE;
305
307
  }
308
+ const resolvedProjectRoot = await realpath(projectRoot);
309
+
306
310
  const state = new WorkflowState();
307
311
  assert.ok(
308
- state.stateFile.startsWith(path.join(projectRoot, ".state", "users")),
312
+ state.stateFile.startsWith(path.join(resolvedProjectRoot, ".state", "users")),
309
313
  "state file should resolve under project .state/users directory"
310
314
  );
311
315
 
@@ -314,7 +318,6 @@ test("WorkflowState resolves state file relative to project root", async () => {
314
318
  delete process.env.DEV_WORKFLOW_STATE_FILE;
315
319
 
316
320
  const state2 = new WorkflowState();
317
- const resolvedProjectRoot = await realpath(projectRoot);
318
321
  assert.ok(
319
322
  state2.stateFile.startsWith(path.join(resolvedProjectRoot, ".state", "users")),
320
323
  "state file should resolve to project root"
@@ -90,7 +90,7 @@ export function getToolList() {
90
90
  properties: {
91
91
  documentationType: {
92
92
  type: "string",
93
- enum: ["README", "inline-comments", "API-docs", "changelog", "other"],
93
+ enum: ["PRD", "README", "RELEASE_NOTES", "inline-comments", "API-docs", "changelog", "other"],
94
94
  description: "Type of documentation created",
95
95
  },
96
96
  summary: {
@@ -259,7 +259,7 @@ export function getToolList() {
259
259
  },
260
260
  documentationType: {
261
261
  type: "string",
262
- enum: ["README", "inline-comments", "API-docs", "changelog", "other"],
262
+ enum: ["PRD", "README", "RELEASE_NOTES", "inline-comments", "API-docs", "changelog", "other"],
263
263
  description: "Type of documentation created",
264
264
  },
265
265
  documentationSummary: {
package/tools/handlers.js CHANGED
@@ -346,7 +346,7 @@ async function handleRunTests(args, workflowState) {
346
346
  await workflowState.save();
347
347
 
348
348
  return textResponse(
349
- `✅ All tests passed! 🎉\n\nTest command: ${args.testCommand}\n\n📝 Now create documentation using 'create_documentation' with:\n- documentationType: "README", "inline-comments", "API-docs", "changelog", or "other"\n- summary: Brief description of what was documented\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ✓ Create tests\n3. ✓ Run tests (GREEN!)\n4. ⏳ Create/update documentation\n5. ⏳ Run 'check_ready_to_commit'\n6. ⏳ Run 'commit_and_push'\n7. ⏳ Run 'perform_release'\n8. ⏳ Complete task`
349
+ `✅ All tests passed! 🎉\n\nTest command: ${args.testCommand}\n\n📝 Now create or update documentation using 'create_documentation' with:\n- documentationType: "PRD", "README", "RELEASE_NOTES", "inline-comments", "API-docs", "changelog", or "other"\n- summary: Brief description of what was documented\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ✓ Create tests\n3. ✓ Run tests (GREEN!)\n4. ⏳ Create/update documentation\n5. ⏳ Run 'check_ready_to_commit'\n6. ⏳ Run 'commit_and_push'\n7. ⏳ Run 'perform_release'\n8. ⏳ Complete task`
350
350
  );
351
351
  }
352
352
 
@@ -368,7 +368,7 @@ async function handleCreateDocumentation(args, workflowState) {
368
368
  await workflowState.save();
369
369
 
370
370
  return textResponse(
371
- `✅ Documentation created!\n\nType: ${args.documentationType}\nSummary: ${args.summary}\n\n🎉 You're ready to verify your work!\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ✓ Create tests\n3. ✓ Run tests (GREEN!)\n4. ✓ Create documentation\n5. ⏳ Run 'check_ready_to_commit' to verify\n6. ⏳ Run 'commit_and_push'\n7. ⏳ Run 'perform_release'\n8. ⏳ Mark as complete with 'complete_task'`
371
+ `✅ Documentation created/updated!\n\nType: ${args.documentationType}\nSummary: ${args.summary}\n\n🎉 You're ready to verify your work!\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ✓ Create tests\n3. ✓ Run tests (GREEN!)\n4. ✓ Create/update documentation\n5. ⏳ Run 'check_ready_to_commit' to verify\n6. ⏳ Run 'commit_and_push'\n7. ⏳ Run 'perform_release'\n8. ⏳ Mark as complete with 'complete_task'`
372
372
  );
373
373
  }
374
374
 
@@ -0,0 +1,23 @@
1
+ import { defineConfig } from 'vite';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ export default defineConfig({
9
+ root: 'web/public',
10
+ build: {
11
+ outDir: '../../dist/web',
12
+ emptyOutDir: true,
13
+ rollupOptions: {
14
+ input: path.resolve(__dirname, 'web/public/index.html'),
15
+ },
16
+ },
17
+ server: {
18
+ port: 3111,
19
+ proxy: {
20
+ '/api': 'http://localhost:3112'
21
+ }
22
+ }
23
+ });
package/web/README.md ADDED
@@ -0,0 +1,36 @@
1
+ This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
@@ -0,0 +1,32 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ import { resolveDocContent, getAvailableDocs } from "@/lib/docs";
3
+
4
+ export async function GET(request: NextRequest) {
5
+ const searchParams = request.nextUrl.searchParams;
6
+ const rawDocKey = searchParams.get("doc");
7
+ const availableDocs = getAvailableDocs();
8
+
9
+ if (!rawDocKey) {
10
+ return NextResponse.json({ docs: availableDocs });
11
+ }
12
+
13
+ const docKey = rawDocKey.trim();
14
+ const resolvedKey = availableDocs.find((key) => key.toLowerCase() === docKey.toLowerCase());
15
+
16
+ if (!resolvedKey) {
17
+ return NextResponse.json(
18
+ { error: "Document not found", requested: docKey, available: availableDocs },
19
+ { status: 404 }
20
+ );
21
+ }
22
+
23
+ const result = await resolveDocContent(resolvedKey);
24
+ if (!result.exists) {
25
+ return NextResponse.json(
26
+ { error: "Document asset is missing" },
27
+ { status: 500 }
28
+ );
29
+ }
30
+
31
+ return NextResponse.json({ doc: resolvedKey, content: result.content, format: result.format });
32
+ }
@@ -0,0 +1,19 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ import { getHistoryForUser } from "@/lib/db";
3
+
4
+ export async function GET(request: NextRequest) {
5
+ const searchParams = request.nextUrl.searchParams;
6
+ const userId = searchParams.get("user") || "default";
7
+ const page = Number(searchParams.get("page") || "1");
8
+ const pageSize = Number(searchParams.get("pageSize") || "20");
9
+ const startDate = searchParams.get("startDate") || undefined;
10
+ const endDate = searchParams.get("endDate") || undefined;
11
+
12
+ try {
13
+ const history = getHistoryForUser(userId, { page, pageSize, startDate, endDate });
14
+ return NextResponse.json(history);
15
+ } catch (error) {
16
+ console.error("Error fetching history:", error);
17
+ return NextResponse.json({ error: "Failed to fetch history" }, { status: 500 });
18
+ }
19
+ }
@@ -0,0 +1,21 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ export async function GET() {
4
+ try {
5
+ const packageName = "@programinglive/dev-workflow-mcp-server";
6
+ const response = await fetch(
7
+ `https://api.npmjs.org/downloads/point/last-month/${packageName}`,
8
+ { next: { revalidate: 3600 } } // Cache for 1 hour
9
+ );
10
+
11
+ if (!response.ok) {
12
+ return NextResponse.json({ downloads: 0 }, { status: 200 });
13
+ }
14
+
15
+ const data = await response.json();
16
+ return NextResponse.json({ downloads: data.downloads || 0 });
17
+ } catch (error) {
18
+ console.error("Error fetching npm downloads:", error);
19
+ return NextResponse.json({ downloads: 0 }, { status: 200 });
20
+ }
21
+ }
@@ -0,0 +1,15 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ import { getSummaryForUser } from "@/lib/db";
3
+
4
+ export async function GET(request: NextRequest) {
5
+ const searchParams = request.nextUrl.searchParams;
6
+ const userId = searchParams.get("user") || "default";
7
+
8
+ try {
9
+ const summary = getSummaryForUser(userId);
10
+ return NextResponse.json({ summary });
11
+ } catch (error) {
12
+ console.error("Error fetching summary:", error);
13
+ return NextResponse.json({ error: "Failed to fetch summary" }, { status: 500 });
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ import { NextResponse } from "next/server";
2
+ import { readFile } from "fs/promises";
3
+ import { join } from "path";
4
+
5
+ export async function GET() {
6
+ try {
7
+ const packageJsonPath = join(process.cwd(), "..", "package.json");
8
+ const packageJson = await readFile(packageJsonPath, "utf-8");
9
+ const { version } = JSON.parse(packageJson);
10
+ return NextResponse.json({ version });
11
+ } catch (error) {
12
+ console.error("Error fetching version:", error);
13
+ return NextResponse.json({ error: "Failed to fetch version" }, { status: 500 });
14
+ }
15
+ }
@@ -0,0 +1,202 @@
1
+ import Link from "next/link";
2
+ import { ArrowLeft, CheckCircle, GitBranch, FileText, TestTube, Rocket } from "lucide-react";
3
+
4
+ export default function DocsPage() {
5
+ return (
6
+ <div className="min-h-screen bg-[#0a0a0f] text-white pt-20 px-4 pb-12">
7
+ <div className="max-w-4xl mx-auto">
8
+ <div className="mb-8">
9
+ <Link href="/" className="inline-flex items-center gap-2 text-indigo-400 hover:text-indigo-300 transition">
10
+ <ArrowLeft className="w-4 h-4" />
11
+ Back to Dashboard
12
+ </Link>
13
+ </div>
14
+
15
+ <div className="prose prose-invert max-w-none">
16
+ <h1 className="text-5xl font-bold mb-4 bg-gradient-to-r from-indigo-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">
17
+ Dev Workflow MCP Server
18
+ </h1>
19
+ <p className="text-xl text-gray-400 mb-8">
20
+ An MCP server that acts as your coding conscience. Enforce test-driven development, ensure documentation,
21
+ and never skip a step in your release process.
22
+ </p>
23
+
24
+ <div className="bg-emerald-500/10 border border-emerald-500/20 rounded-lg p-4 mb-8">
25
+ <p className="text-emerald-400 font-semibold">Version: 1.3.12</p>
26
+ </div>
27
+
28
+ <h2 className="text-3xl font-bold mt-12 mb-6">Features</h2>
29
+ <div className="grid md:grid-cols-2 gap-4 mb-8">
30
+ <div className="p-4 rounded-lg bg-white/5 border border-white/10">
31
+ <div className="flex items-center gap-3 mb-2">
32
+ <CheckCircle className="w-5 h-5 text-indigo-400" />
33
+ <h3 className="text-lg font-semibold">Enforced Discipline</h3>
34
+ </div>
35
+ <p className="text-gray-400 text-sm">Won't let you skip important steps. Follows a strict, proven development workflow.</p>
36
+ </div>
37
+ <div className="p-4 rounded-lg bg-white/5 border border-white/10">
38
+ <div className="flex items-center gap-3 mb-2">
39
+ <TestTube className="w-5 h-5 text-purple-400" />
40
+ <h3 className="text-lg font-semibold">Test-Driven</h3>
41
+ </div>
42
+ <p className="text-gray-400 text-sm">Blocks commits if tests fail. Encourages writing tests before marking tasks complete.</p>
43
+ </div>
44
+ <div className="p-4 rounded-lg bg-white/5 border border-white/10">
45
+ <div className="flex items-center gap-3 mb-2">
46
+ <FileText className="w-5 h-5 text-emerald-400" />
47
+ <h3 className="text-lg font-semibold">Documentation</h3>
48
+ </div>
49
+ <p className="text-gray-400 text-sm">Reminds you to update documentation (README, docs, changelog) for every change.</p>
50
+ </div>
51
+ <div className="p-4 rounded-lg bg-white/5 border border-white/10">
52
+ <div className="flex items-center gap-3 mb-2">
53
+ <GitBranch className="w-5 h-5 text-orange-400" />
54
+ <h3 className="text-lg font-semibold">State Tracking</h3>
55
+ </div>
56
+ <p className="text-gray-400 text-sm">Remembers exactly where you are in the workflow, even across sessions.</p>
57
+ </div>
58
+ </div>
59
+
60
+ <h2 className="text-3xl font-bold mt-12 mb-6">Installation</h2>
61
+ <div className="bg-[#1a1a24] rounded-lg p-6 border border-white/10 mb-8">
62
+ <pre className="text-sm overflow-x-auto">
63
+ <code className="text-gray-300">npm install -g @programinglive/dev-workflow-mcp-server</code>
64
+ </pre>
65
+ </div>
66
+
67
+ <h2 className="text-3xl font-bold mt-12 mb-6">Quick Start</h2>
68
+ <ol className="space-y-4 mb-8">
69
+ <li className="flex gap-4">
70
+ <span className="flex-shrink-0 w-8 h-8 rounded-full bg-indigo-500/20 flex items-center justify-center text-indigo-400 font-bold">1</span>
71
+ <div>
72
+ <h3 className="font-semibold mb-1">Start a Task</h3>
73
+ <p className="text-gray-400">Begin your coding session by defining what you're working on.</p>
74
+ <div className="bg-[#1a1a24] rounded-lg p-3 mt-2 border border-white/10">
75
+ <code className="text-sm text-gray-300">start_task</code>
76
+ </div>
77
+ </div>
78
+ </li>
79
+ <li className="flex gap-4">
80
+ <span className="flex-shrink-0 w-8 h-8 rounded-full bg-purple-500/20 flex items-center justify-center text-purple-400 font-bold">2</span>
81
+ <div>
82
+ <h3 className="font-semibold mb-1">Mark Bug Fixed</h3>
83
+ <p className="text-gray-400">Once you've implemented your feature or fix, mark it as complete.</p>
84
+ <div className="bg-[#1a1a24] rounded-lg p-3 mt-2 border border-white/10">
85
+ <code className="text-sm text-gray-300">mark_bug_fixed</code>
86
+ </div>
87
+ </div>
88
+ </li>
89
+ <li className="flex gap-4">
90
+ <span className="flex-shrink-0 w-8 h-8 rounded-full bg-emerald-500/20 flex items-center justify-center text-emerald-400 font-bold">3</span>
91
+ <div>
92
+ <h3 className="font-semibold mb-1">Create Tests</h3>
93
+ <p className="text-gray-400">Write tests to verify your changes work correctly.</p>
94
+ <div className="bg-[#1a1a24] rounded-lg p-3 mt-2 border border-white/10">
95
+ <code className="text-sm text-gray-300">create_tests</code>
96
+ </div>
97
+ </div>
98
+ </li>
99
+ <li className="flex gap-4">
100
+ <span className="flex-shrink-0 w-8 h-8 rounded-full bg-orange-500/20 flex items-center justify-center text-orange-400 font-bold">4</span>
101
+ <div>
102
+ <h3 className="font-semibold mb-1">Run Tests</h3>
103
+ <p className="text-gray-400">Execute your test suite and ensure everything passes.</p>
104
+ <div className="bg-[#1a1a24] rounded-lg p-3 mt-2 border border-white/10">
105
+ <code className="text-sm text-gray-300">run_tests</code>
106
+ </div>
107
+ </div>
108
+ </li>
109
+ <li className="flex gap-4">
110
+ <span className="flex-shrink-0 w-8 h-8 rounded-full bg-pink-500/20 flex items-center justify-center text-pink-400 font-bold">5</span>
111
+ <div>
112
+ <h3 className="font-semibold mb-1">Create Documentation</h3>
113
+ <p className="text-gray-400">Update relevant documentation for your changes.</p>
114
+ <div className="bg-[#1a1a24] rounded-lg p-3 mt-2 border border-white/10">
115
+ <code className="text-sm text-gray-300">create_documentation</code>
116
+ </div>
117
+ </div>
118
+ </li>
119
+ <li className="flex gap-4">
120
+ <span className="flex-shrink-0 w-8 h-8 rounded-full bg-blue-500/20 flex items-center justify-center text-blue-400 font-bold">6</span>
121
+ <div>
122
+ <h3 className="font-semibold mb-1">Commit and Push</h3>
123
+ <p className="text-gray-400">Commit your changes and push to the repository.</p>
124
+ <div className="bg-[#1a1a24] rounded-lg p-3 mt-2 border border-white/10">
125
+ <code className="text-sm text-gray-300">commit_and_push</code>
126
+ </div>
127
+ </div>
128
+ </li>
129
+ </ol>
130
+
131
+ <h2 className="text-3xl font-bold mt-12 mb-6">Available Commands</h2>
132
+ <div className="space-y-3 mb-8">
133
+ {[
134
+ { cmd: "start_task", desc: "Begin a new coding task" },
135
+ { cmd: "mark_bug_fixed", desc: "Mark feature/bugfix as complete" },
136
+ { cmd: "create_tests", desc: "Record that tests have been created" },
137
+ { cmd: "run_tests", desc: "Execute and record test results" },
138
+ { cmd: "skip_tests", desc: "Skip tests with justification" },
139
+ { cmd: "create_documentation", desc: "Record documentation updates" },
140
+ { cmd: "commit_and_push", desc: "Commit and push changes" },
141
+ { cmd: "perform_release", desc: "Execute release process" },
142
+ { cmd: "complete_task", desc: "Mark task as complete" },
143
+ { cmd: "get_workflow_status", desc: "Check current workflow state" },
144
+ { cmd: "view_history", desc: "View completed tasks" },
145
+ ].map((item) => (
146
+ <div key={item.cmd} className="p-4 rounded-lg bg-white/5 border border-white/10 hover:bg-white/10 transition">
147
+ <code className="text-indigo-400 font-mono">{item.cmd}</code>
148
+ <p className="text-gray-400 text-sm mt-1">{item.desc}</p>
149
+ </div>
150
+ ))}
151
+ </div>
152
+
153
+ <h2 className="text-3xl font-bold mt-12 mb-6">Configuration</h2>
154
+ <p className="text-gray-400 mb-4">
155
+ The server stores workflow state in a SQLite database located at <code className="text-indigo-400 bg-white/5 px-2 py-1 rounded">.state/dev-workflow.db</code>
156
+ </p>
157
+ <p className="text-gray-400 mb-8">
158
+ Set the <code className="text-indigo-400 bg-white/5 px-2 py-1 rounded">DEV_WORKFLOW_USER_ID</code> environment variable to isolate workflow state per user.
159
+ </p>
160
+
161
+ <h2 className="text-3xl font-bold mt-12 mb-6">Requirements</h2>
162
+ <ul className="space-y-2 mb-8">
163
+ <li className="flex items-center gap-2 text-gray-400">
164
+ <CheckCircle className="w-4 h-4 text-emerald-400" />
165
+ Node.js 18 or higher
166
+ </li>
167
+ <li className="flex items-center gap-2 text-gray-400">
168
+ <CheckCircle className="w-4 h-4 text-emerald-400" />
169
+ Git installed and configured
170
+ </li>
171
+ <li className="flex items-center gap-2 text-gray-400">
172
+ <CheckCircle className="w-4 h-4 text-emerald-400" />
173
+ MCP-compatible AI assistant (e.g., Claude Desktop)
174
+ </li>
175
+ </ul>
176
+
177
+ <h2 className="text-3xl font-bold mt-12 mb-6">License</h2>
178
+ <p className="text-gray-400 mb-8">
179
+ MIT License - Free to use for personal and commercial projects.
180
+ </p>
181
+
182
+ <div className="bg-gradient-to-r from-indigo-500/10 via-purple-500/10 to-pink-500/10 border border-white/10 rounded-lg p-6 mt-12">
183
+ <div className="flex items-center gap-3 mb-3">
184
+ <Rocket className="w-6 h-6 text-pink-400" />
185
+ <h3 className="text-xl font-bold">Ready to get started?</h3>
186
+ </div>
187
+ <p className="text-gray-400 mb-4">
188
+ Install the MCP server and start enforcing best practices in your development workflow today!
189
+ </p>
190
+ <Link
191
+ href="https://github.com/programinglive/dev-workflow-mcp-server"
192
+ target="_blank"
193
+ className="inline-flex items-center gap-2 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"
194
+ >
195
+ View on GitHub
196
+ </Link>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </div>
201
+ );
202
+ }
Binary file
@@ -0,0 +1,91 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --background: #0a0a0f;
7
+ --foreground: #ffffff;
8
+ }
9
+
10
+ body {
11
+ color: var(--foreground);
12
+ background: var(--background);
13
+ font-family: Arial, Helvetica, sans-serif;
14
+ }
15
+
16
+ @layer utilities {
17
+ @keyframes fadeInUp {
18
+ 0% {
19
+ opacity: 0;
20
+ transform: translateY(20px);
21
+ }
22
+
23
+ 100% {
24
+ opacity: 1;
25
+ transform: translateY(0px);
26
+ }
27
+ }
28
+
29
+ @keyframes fadeInRight {
30
+ 0% {
31
+ opacity: 0;
32
+ transform: translateY(-50%) translateX(40px);
33
+ }
34
+
35
+ 100% {
36
+ opacity: 1;
37
+ transform: translateY(-50%) translateX(0px);
38
+ }
39
+ }
40
+
41
+ @keyframes fadeIn {
42
+ 0% {
43
+ opacity: 0;
44
+ transform: translateX(-10px);
45
+ }
46
+
47
+ 100% {
48
+ opacity: 1;
49
+ transform: translateX(0px);
50
+ }
51
+ }
52
+
53
+ .animate-fade-in-up {
54
+ animation: fadeInUp 0.8s ease-out forwards;
55
+ opacity: 0;
56
+ }
57
+
58
+ .animate-fade-in-right {
59
+ animation: fadeInRight 0.8s ease-out forwards;
60
+ opacity: 0;
61
+ }
62
+
63
+ .terminal-line {
64
+ opacity: 0;
65
+ display: flex;
66
+ }
67
+
68
+ .terminal-line.visible {
69
+ opacity: 1;
70
+ transition: opacity 0.1s;
71
+ }
72
+
73
+ .typing-cursor::after {
74
+ content: '▋';
75
+ animation: blink 1s step-end infinite;
76
+ margin-left: 4px;
77
+ color: #a855f7;
78
+ }
79
+
80
+ @keyframes blink {
81
+
82
+ 0%,
83
+ 100% {
84
+ opacity: 1;
85
+ }
86
+
87
+ 50% {
88
+ opacity: 0;
89
+ }
90
+ }
91
+ }