@programinglive/dev-workflow-mcp-server 1.5.2 โ†’ 1.5.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 (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/github-release.yml +56 -0
  9. package/.github/workflows/npm-publish.yml +50 -50
  10. package/.husky/commit-msg +0 -0
  11. package/CHANGELOG.md +759 -741
  12. package/CODE_OF_CONDUCT.md +79 -79
  13. package/CONTRIBUTING.md +60 -60
  14. package/LICENSE +21 -21
  15. package/README.md +632 -632
  16. package/SECURITY.md +20 -20
  17. package/db/index.js +204 -204
  18. package/docs/NETLIFY_DEPLOYMENT.md +125 -125
  19. package/docs/PLESK_DEPLOYMENT.md +170 -170
  20. package/docs/WORKFLOW-BEST-PRACTICES.md +58 -58
  21. package/docs/antigravity/EXAMPLES.md +535 -535
  22. package/docs/antigravity/GETTING-STARTED.md +292 -292
  23. package/docs/antigravity/TROUBLESHOOTING.md +742 -742
  24. package/docs/antigravity/WALKTHROUGH.md +25 -25
  25. package/docs/antigravity/WORKFLOW-TEMPLATES.md +670 -670
  26. package/docs/product/PRD.md +67 -67
  27. package/docs/release-notes/RELEASE_NOTES.md +233 -226
  28. package/docs/web-dashboard.md +175 -175
  29. package/exec.js +49 -49
  30. package/index.js +279 -279
  31. package/install.js +73 -73
  32. package/package.json +4 -4
  33. package/release-wrapper.js +192 -192
  34. package/scripts/build-docs.js +63 -63
  35. package/scripts/extract-release-notes.cjs +78 -0
  36. package/scripts/hello-world.js +1 -1
  37. package/scripts/release.cjs +252 -252
  38. package/scripts/release.js +252 -0
  39. package/scripts/update-release-notes.cjs +178 -178
  40. package/scripts/update-release-notes.js +182 -0
  41. package/server.json +23 -23
  42. package/tailwind.config.js +8 -8
  43. package/tests/build.test.js +83 -83
  44. package/tests/exec.test.js +35 -35
  45. package/tests/handlers.test.js +1058 -1058
  46. package/tests/hello-world.test.js +13 -13
  47. package/tests/mcpRegistry.test.js +65 -65
  48. package/tests/patch-release.test.js +7 -0
  49. package/tests/release-wrapper.test.js +107 -107
  50. package/tests/workflowState.test.js +505 -505
  51. package/tools/definitions.js +332 -332
  52. package/tools/handlers.js +1019 -1019
  53. package/vite.config.js +43 -43
  54. package/vite.web.config.js +23 -23
  55. package/web/README.md +36 -36
  56. package/web/app/docs/page.tsx +202 -202
  57. package/web/app/globals.css +90 -90
  58. package/web/app/layout.tsx +36 -36
  59. package/web/app/page.tsx +15 -15
  60. package/web/components/ApiReference.tsx +20 -20
  61. package/web/components/Features.tsx +61 -61
  62. package/web/components/Footer.tsx +9 -9
  63. package/web/components/Hero.tsx +96 -96
  64. package/web/components/History.tsx +143 -143
  65. package/web/components/Navbar.tsx +64 -64
  66. package/web/components/Terminal.tsx +114 -114
  67. package/web/eslint.config.mjs +18 -18
  68. package/web/lib/db.js +131 -131
  69. package/web/lib/docs.js +73 -73
  70. package/web/netlify.toml +3 -3
  71. package/web/next.config.ts +12 -12
  72. package/web/package-lock.json +6560 -6560
  73. package/web/package.json +28 -28
  74. package/web/postcss.config.mjs +9 -9
  75. package/web/server.js +31 -31
  76. package/web/tailwind.config.ts +19 -19
  77. package/web/tsconfig.json +42 -42
  78. package/workflow-state.js +612 -612
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
+ }