@programinglive/dev-workflow-mcp-server 1.5.1 โ†’ 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 (78) 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 -50
  9. package/.husky/commit-msg +0 -0
  10. package/CHANGELOG.md +749 -739
  11. package/CODE_OF_CONDUCT.md +79 -79
  12. package/CONTRIBUTING.md +60 -60
  13. package/LICENSE +21 -21
  14. package/README.md +632 -632
  15. package/SECURITY.md +20 -20
  16. package/db/index.js +204 -204
  17. package/docs/NETLIFY_DEPLOYMENT.md +125 -125
  18. package/docs/PLESK_DEPLOYMENT.md +170 -170
  19. package/docs/WORKFLOW-BEST-PRACTICES.md +58 -58
  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 -67
  26. package/docs/release-notes/RELEASE_NOTES.md +226 -226
  27. package/docs/web-dashboard.md +175 -175
  28. package/exec.js +49 -49
  29. package/index.js +279 -279
  30. package/install.js +73 -73
  31. package/package.json +4 -4
  32. package/release-wrapper.js +192 -192
  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 -178
  37. package/server.json +23 -23
  38. package/tailwind.config.js +8 -8
  39. package/tests/build.test.js +83 -91
  40. package/tests/exec.test.js +35 -35
  41. package/tests/handlers.test.js +1058 -1058
  42. package/tests/hello-world.test.js +13 -13
  43. package/tests/mcpRegistry.test.js +65 -65
  44. package/tests/release-wrapper.test.js +107 -107
  45. package/tests/workflowState.test.js +505 -505
  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 -23
  50. package/web/README.md +36 -36
  51. package/web/app/docs/page.tsx +202 -202
  52. package/web/app/globals.css +90 -90
  53. package/web/app/layout.tsx +36 -36
  54. package/web/app/page.tsx +15 -15
  55. package/web/components/ApiReference.tsx +20 -20
  56. package/web/components/Features.tsx +61 -61
  57. package/web/components/Footer.tsx +9 -9
  58. package/web/components/Hero.tsx +96 -97
  59. package/web/components/History.tsx +143 -143
  60. package/web/components/Navbar.tsx +64 -64
  61. package/web/components/Terminal.tsx +114 -114
  62. package/web/eslint.config.mjs +18 -18
  63. package/web/lib/db.js +131 -131
  64. package/web/lib/docs.js +73 -73
  65. package/web/netlify.toml +3 -6
  66. package/web/next.config.ts +12 -7
  67. package/web/package-lock.json +6560 -6560
  68. package/web/package.json +28 -28
  69. package/web/postcss.config.mjs +9 -9
  70. package/web/server.js +31 -31
  71. package/web/tailwind.config.ts +19 -19
  72. package/web/tsconfig.json +42 -42
  73. package/workflow-state.js +612 -612
  74. package/web/app/api/docs/route.ts +0 -32
  75. package/web/app/api/history/route.ts +0 -12
  76. package/web/app/api/npm-downloads/route.ts +0 -21
  77. package/web/app/api/summary/route.ts +0 -13
  78. package/web/app/api/version/route.ts +0 -8
package/index.js CHANGED
@@ -1,279 +1,279 @@
1
- #!/usr/bin/env node
2
-
3
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import {
6
- CallToolRequestSchema,
7
- ListToolsRequestSchema,
8
- ListPromptsRequestSchema,
9
- GetPromptRequestSchema,
10
- } from "@modelcontextprotocol/sdk/types.js";
11
- import { fileURLToPath } from "url";
12
- import { exec } from "./exec.js";
13
- import { normalizeRequestArgs, shellEscape } from "./utils.js";
14
- import {
15
- getCurrentBranch,
16
- getLastCommitMessage,
17
- getPrimaryBranch,
18
- getStagedChanges,
19
- hasStagedChanges,
20
- hasTestChanges,
21
- hasWorkingChanges,
22
- workingTreeSummary,
23
- } from "./git-helpers.js";
24
- import {
25
- createCommitMessageParts,
26
- determineReleaseTypeFromCommit,
27
- } from "./commit-helpers.js";
28
- import { WorkflowState } from "./workflow-state.js";
29
- import { getToolList } from "./tools/definitions.js";
30
- import { handleToolCall } from "./tools/handlers.js";
31
-
32
- export { createCommitMessageParts, determineReleaseTypeFromCommit } from "./commit-helpers.js";
33
- export { containsTestFilesInStatus, workingTreeSummary } from "./git-helpers.js";
34
- export { WorkflowState } from "./workflow-state.js";
35
-
36
- export let workflowState = null;
37
-
38
- const __filename = fileURLToPath(import.meta.url);
39
-
40
- // Create MCP server
41
- export const server = new Server(
42
- {
43
- name: "@programinglive/dev-workflow-mcp-server",
44
- version: "1.0.0",
45
- },
46
- {
47
- capabilities: {
48
- tools: {},
49
- prompts: {},
50
- },
51
- }
52
- );
53
-
54
- // Define tools
55
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
56
- tools: getToolList(),
57
- }));
58
-
59
- // Handle tool calls
60
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
61
- // Reload state from disk before each request to ensure consistency
62
- if (workflowState) {
63
- await workflowState.load();
64
- }
65
- return handleToolCall({
66
- request,
67
- normalizeRequestArgs,
68
- workflowState,
69
- exec,
70
- git: {
71
- hasWorkingChanges,
72
- hasTestChanges,
73
- hasStagedChanges,
74
- getStagedChanges,
75
- getCurrentBranch,
76
- getPrimaryBranch,
77
- getLastCommitMessage,
78
- workingTreeSummary,
79
- },
80
- utils: { shellEscape, determineReleaseTypeFromCommit, createCommitMessageParts },
81
- });
82
- });
83
-
84
- // Helper function
85
- export function getNextStep(status) {
86
- if (!status.bugFixed) return "Mark feature/bug as fixed";
87
- if (!status.testsCreated) return "Create tests";
88
- if (!status.testsPassed) return "Run tests";
89
- if (!status.documentationCreated) return "Create documentation";
90
- if (!status.readyCheckCompleted) return "Run 'check_ready_to_commit'";
91
- if (!status.commitAndPushCompleted) return "Run 'commit_and_push'";
92
- if (!status.released) return "Run 'perform_release'";
93
- return "Complete the task";
94
- }
95
-
96
- // Define prompts
97
- server.setRequestHandler(ListPromptsRequestSchema, async () => {
98
- return {
99
- prompts: [
100
- {
101
- name: "workflow_reminder",
102
- description: "Get a reminder of the complete development workflow",
103
- },
104
- {
105
- name: "pre_commit_checklist",
106
- description: "Pre-commit checklist to ensure nothing is missed",
107
- },
108
- ],
109
- };
110
- });
111
-
112
- server.setRequestHandler(GetPromptRequestSchema, async (request) => {
113
- const { name } = request.params;
114
-
115
- if (name === "workflow_reminder") {
116
- return {
117
- messages: [
118
- {
119
- role: "user",
120
- content: {
121
- type: "text",
122
- text: `Development Workflow Discipline:
123
-
124
- 1. ๐ŸŽฏ START CONSCIOUS
125
- - Use 'start_task' to declare what you're coding
126
- - Be clear about your intention
127
-
128
- 2. ๐Ÿ”จ CODE WITH PURPOSE
129
- - Implement your feature or fix
130
- - Follow best practices
131
-
132
- 3. ๐Ÿงช ALWAYS CREATE TESTS
133
- - After fixing/implementing, create tests
134
- - Use 'mark_bug_fixed' when done
135
-
136
- 4. โœ… TESTS MUST PASS
137
- - Run your tests with 'run_tests'
138
- - If tests fail: FIX THEM, never skip!
139
- - Only proceed when all tests are GREEN
140
-
141
- 5. ๐Ÿ“ DOCUMENT YOUR WORK
142
- - Update README, comments, or docs
143
- - Use 'create_documentation' when done
144
-
145
- 6. ๐Ÿš€ COMMIT & PUSH
146
- - Use 'check_ready_to_commit' to verify
147
- - Use 'commit_and_push' (stages, commits, and pushes)
148
- - Then use 'perform_release' to handle versioning and tags
149
- - Use 'complete_task' to finish
150
-
151
- Remember: No shortcuts! Each step is important for code quality.`,
152
- },
153
- },
154
- ],
155
- };
156
- }
157
-
158
- if (name === "pre_commit_checklist") {
159
- return {
160
- messages: [
161
- {
162
- role: "user",
163
- content: {
164
- type: "text",
165
- text: `Pre-Commit Checklist:
166
-
167
- Before you commit and push, verify:
168
-
169
- โ–ก Feature/bug is fully implemented
170
- โ–ก Tests are created for the changes
171
- โ–ก All tests pass (GREEN) - run 'run_tests'
172
- โ–ก Documentation is updated
173
- โ–ก Code is clean (no console.logs, unused imports)
174
- โ–ก No TypeScript 'any' types
175
- โ–ก Followed project coding standards
176
-
177
- Use 'check_ready_to_commit' to verify workflow completion.
178
-
179
- ๐Ÿšซ NEVER commit if tests are failing!
180
- โœ… Only commit when everything is green!`,
181
- },
182
- },
183
- ],
184
- };
185
- }
186
-
187
- throw new Error(`Unknown prompt: ${name}`);
188
- });
189
-
190
- // Start server
191
- export async function main() {
192
- try {
193
- // Initialize workflow state
194
- workflowState = new WorkflowState();
195
- await workflowState.load();
196
- await workflowState.ensurePrimaryFile();
197
- } catch (error) {
198
- console.error("Warning: Failed to initialize workflow state:", error.message);
199
- // Continue anyway - workflow state is optional for MCP to function
200
- workflowState = new WorkflowState();
201
- }
202
-
203
- const transport = new StdioServerTransport();
204
- await server.connect(transport);
205
- console.error("Dev Workflow MCP Server running on stdio");
206
- }
207
-
208
- // --- Lightweight CLI: dev-workflow-mcp call <toolName> [--args '<json>'] ---
209
- async function cliMain(argv) {
210
- const [, , subcommand, toolName, ...rest] = argv;
211
- if (subcommand !== "call") return false;
212
-
213
- if (!toolName || typeof toolName !== "string" || toolName.trim() === "") {
214
- console.error("Usage: dev-workflow-mcp call <toolName> [--args '<json>']");
215
- process.exit(2);
216
- }
217
-
218
- // Parse --args '<json>' if provided
219
- let rawArgs = undefined;
220
- for (let i = 0; i < rest.length; i++) {
221
- if (rest[i] === "--args") {
222
- rawArgs = rest[i + 1];
223
- break;
224
- }
225
- }
226
-
227
- try {
228
- // Initialize workflow state similar to the server path
229
- workflowState = new WorkflowState();
230
- await workflowState.load();
231
- await workflowState.ensurePrimaryFile();
232
-
233
- const request = {
234
- params: {
235
- name: toolName,
236
- arguments: rawArgs ?? {},
237
- },
238
- };
239
-
240
- const response = await handleToolCall({
241
- request,
242
- normalizeRequestArgs,
243
- workflowState,
244
- exec,
245
- git: {
246
- hasWorkingChanges,
247
- hasTestChanges,
248
- hasStagedChanges,
249
- getStagedChanges,
250
- getCurrentBranch,
251
- getPrimaryBranch,
252
- getLastCommitMessage,
253
- workingTreeSummary,
254
- },
255
- utils: { shellEscape, determineReleaseTypeFromCommit, createCommitMessageParts },
256
- });
257
-
258
- const text = response?.content?.[0]?.text || "";
259
- console.log(text);
260
- const isError = /^\s*[โš ๏ธโŒ]/u.test(text);
261
- process.exit(isError ? 1 : 0);
262
- } catch (error) {
263
- console.error("CLI error:", error.message || String(error));
264
- process.exit(1);
265
- }
266
- }
267
-
268
- const isDirectRun = process.argv[1] === __filename;
269
- if (isDirectRun) {
270
- // If invoked with a CLI subcommand, run it; otherwise start MCP server
271
- if (process.argv[2] === "call") {
272
- cliMain(process.argv);
273
- } else {
274
- main().catch((error) => {
275
- console.error("Server error:", error);
276
- process.exit(1);
277
- });
278
- }
279
- }
1
+ #!/usr/bin/env node
2
+
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import {
6
+ CallToolRequestSchema,
7
+ ListToolsRequestSchema,
8
+ ListPromptsRequestSchema,
9
+ GetPromptRequestSchema,
10
+ } from "@modelcontextprotocol/sdk/types.js";
11
+ import { fileURLToPath } from "url";
12
+ import { exec } from "./exec.js";
13
+ import { normalizeRequestArgs, shellEscape } from "./utils.js";
14
+ import {
15
+ getCurrentBranch,
16
+ getLastCommitMessage,
17
+ getPrimaryBranch,
18
+ getStagedChanges,
19
+ hasStagedChanges,
20
+ hasTestChanges,
21
+ hasWorkingChanges,
22
+ workingTreeSummary,
23
+ } from "./git-helpers.js";
24
+ import {
25
+ createCommitMessageParts,
26
+ determineReleaseTypeFromCommit,
27
+ } from "./commit-helpers.js";
28
+ import { WorkflowState } from "./workflow-state.js";
29
+ import { getToolList } from "./tools/definitions.js";
30
+ import { handleToolCall } from "./tools/handlers.js";
31
+
32
+ export { createCommitMessageParts, determineReleaseTypeFromCommit } from "./commit-helpers.js";
33
+ export { containsTestFilesInStatus, workingTreeSummary } from "./git-helpers.js";
34
+ export { WorkflowState } from "./workflow-state.js";
35
+
36
+ export let workflowState = null;
37
+
38
+ const __filename = fileURLToPath(import.meta.url);
39
+
40
+ // Create MCP server
41
+ export const server = new Server(
42
+ {
43
+ name: "@programinglive/dev-workflow-mcp-server",
44
+ version: "1.0.0",
45
+ },
46
+ {
47
+ capabilities: {
48
+ tools: {},
49
+ prompts: {},
50
+ },
51
+ }
52
+ );
53
+
54
+ // Define tools
55
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
56
+ tools: getToolList(),
57
+ }));
58
+
59
+ // Handle tool calls
60
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
61
+ // Reload state from disk before each request to ensure consistency
62
+ if (workflowState) {
63
+ await workflowState.load();
64
+ }
65
+ return handleToolCall({
66
+ request,
67
+ normalizeRequestArgs,
68
+ workflowState,
69
+ exec,
70
+ git: {
71
+ hasWorkingChanges,
72
+ hasTestChanges,
73
+ hasStagedChanges,
74
+ getStagedChanges,
75
+ getCurrentBranch,
76
+ getPrimaryBranch,
77
+ getLastCommitMessage,
78
+ workingTreeSummary,
79
+ },
80
+ utils: { shellEscape, determineReleaseTypeFromCommit, createCommitMessageParts },
81
+ });
82
+ });
83
+
84
+ // Helper function
85
+ export function getNextStep(status) {
86
+ if (!status.bugFixed) return "Mark feature/bug as fixed";
87
+ if (!status.testsCreated) return "Create tests";
88
+ if (!status.testsPassed) return "Run tests";
89
+ if (!status.documentationCreated) return "Create documentation";
90
+ if (!status.readyCheckCompleted) return "Run 'check_ready_to_commit'";
91
+ if (!status.commitAndPushCompleted) return "Run 'commit_and_push'";
92
+ if (!status.released) return "Run 'perform_release'";
93
+ return "Complete the task";
94
+ }
95
+
96
+ // Define prompts
97
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
98
+ return {
99
+ prompts: [
100
+ {
101
+ name: "workflow_reminder",
102
+ description: "Get a reminder of the complete development workflow",
103
+ },
104
+ {
105
+ name: "pre_commit_checklist",
106
+ description: "Pre-commit checklist to ensure nothing is missed",
107
+ },
108
+ ],
109
+ };
110
+ });
111
+
112
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
113
+ const { name } = request.params;
114
+
115
+ if (name === "workflow_reminder") {
116
+ return {
117
+ messages: [
118
+ {
119
+ role: "user",
120
+ content: {
121
+ type: "text",
122
+ text: `Development Workflow Discipline:
123
+
124
+ 1. ๐ŸŽฏ START CONSCIOUS
125
+ - Use 'start_task' to declare what you're coding
126
+ - Be clear about your intention
127
+
128
+ 2. ๐Ÿ”จ CODE WITH PURPOSE
129
+ - Implement your feature or fix
130
+ - Follow best practices
131
+
132
+ 3. ๐Ÿงช ALWAYS CREATE TESTS
133
+ - After fixing/implementing, create tests
134
+ - Use 'mark_bug_fixed' when done
135
+
136
+ 4. โœ… TESTS MUST PASS
137
+ - Run your tests with 'run_tests'
138
+ - If tests fail: FIX THEM, never skip!
139
+ - Only proceed when all tests are GREEN
140
+
141
+ 5. ๐Ÿ“ DOCUMENT YOUR WORK
142
+ - Update README, comments, or docs
143
+ - Use 'create_documentation' when done
144
+
145
+ 6. ๐Ÿš€ COMMIT & PUSH
146
+ - Use 'check_ready_to_commit' to verify
147
+ - Use 'commit_and_push' (stages, commits, and pushes)
148
+ - Then use 'perform_release' to handle versioning and tags
149
+ - Use 'complete_task' to finish
150
+
151
+ Remember: No shortcuts! Each step is important for code quality.`,
152
+ },
153
+ },
154
+ ],
155
+ };
156
+ }
157
+
158
+ if (name === "pre_commit_checklist") {
159
+ return {
160
+ messages: [
161
+ {
162
+ role: "user",
163
+ content: {
164
+ type: "text",
165
+ text: `Pre-Commit Checklist:
166
+
167
+ Before you commit and push, verify:
168
+
169
+ โ–ก Feature/bug is fully implemented
170
+ โ–ก Tests are created for the changes
171
+ โ–ก All tests pass (GREEN) - run 'run_tests'
172
+ โ–ก Documentation is updated
173
+ โ–ก Code is clean (no console.logs, unused imports)
174
+ โ–ก No TypeScript 'any' types
175
+ โ–ก Followed project coding standards
176
+
177
+ Use 'check_ready_to_commit' to verify workflow completion.
178
+
179
+ ๐Ÿšซ NEVER commit if tests are failing!
180
+ โœ… Only commit when everything is green!`,
181
+ },
182
+ },
183
+ ],
184
+ };
185
+ }
186
+
187
+ throw new Error(`Unknown prompt: ${name}`);
188
+ });
189
+
190
+ // Start server
191
+ export async function main() {
192
+ try {
193
+ // Initialize workflow state
194
+ workflowState = new WorkflowState();
195
+ await workflowState.load();
196
+ await workflowState.ensurePrimaryFile();
197
+ } catch (error) {
198
+ console.error("Warning: Failed to initialize workflow state:", error.message);
199
+ // Continue anyway - workflow state is optional for MCP to function
200
+ workflowState = new WorkflowState();
201
+ }
202
+
203
+ const transport = new StdioServerTransport();
204
+ await server.connect(transport);
205
+ console.error("Dev Workflow MCP Server running on stdio");
206
+ }
207
+
208
+ // --- Lightweight CLI: dev-workflow-mcp call <toolName> [--args '<json>'] ---
209
+ async function cliMain(argv) {
210
+ const [, , subcommand, toolName, ...rest] = argv;
211
+ if (subcommand !== "call") return false;
212
+
213
+ if (!toolName || typeof toolName !== "string" || toolName.trim() === "") {
214
+ console.error("Usage: dev-workflow-mcp call <toolName> [--args '<json>']");
215
+ process.exit(2);
216
+ }
217
+
218
+ // Parse --args '<json>' if provided
219
+ let rawArgs = undefined;
220
+ for (let i = 0; i < rest.length; i++) {
221
+ if (rest[i] === "--args") {
222
+ rawArgs = rest[i + 1];
223
+ break;
224
+ }
225
+ }
226
+
227
+ try {
228
+ // Initialize workflow state similar to the server path
229
+ workflowState = new WorkflowState();
230
+ await workflowState.load();
231
+ await workflowState.ensurePrimaryFile();
232
+
233
+ const request = {
234
+ params: {
235
+ name: toolName,
236
+ arguments: rawArgs ?? {},
237
+ },
238
+ };
239
+
240
+ const response = await handleToolCall({
241
+ request,
242
+ normalizeRequestArgs,
243
+ workflowState,
244
+ exec,
245
+ git: {
246
+ hasWorkingChanges,
247
+ hasTestChanges,
248
+ hasStagedChanges,
249
+ getStagedChanges,
250
+ getCurrentBranch,
251
+ getPrimaryBranch,
252
+ getLastCommitMessage,
253
+ workingTreeSummary,
254
+ },
255
+ utils: { shellEscape, determineReleaseTypeFromCommit, createCommitMessageParts },
256
+ });
257
+
258
+ const text = response?.content?.[0]?.text || "";
259
+ console.log(text);
260
+ const isError = /^\s*[โš ๏ธโŒ]/u.test(text);
261
+ process.exit(isError ? 1 : 0);
262
+ } catch (error) {
263
+ console.error("CLI error:", error.message || String(error));
264
+ process.exit(1);
265
+ }
266
+ }
267
+
268
+ const isDirectRun = process.argv[1] === __filename;
269
+ if (isDirectRun) {
270
+ // If invoked with a CLI subcommand, run it; otherwise start MCP server
271
+ if (process.argv[2] === "call") {
272
+ cliMain(process.argv);
273
+ } else {
274
+ main().catch((error) => {
275
+ console.error("Server error:", error);
276
+ process.exit(1);
277
+ });
278
+ }
279
+ }