@programinglive/dev-workflow-mcp-server 1.8.1 → 1.10.0

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 (114) hide show
  1. package/.env.example +21 -1
  2. package/AGENTS.md +25 -0
  3. package/README.md +372 -649
  4. package/factory-client.js +554 -0
  5. package/git-facade.js +35 -0
  6. package/index.js +9 -34
  7. package/package.json +21 -20
  8. package/scripts/bootstrap-unix.sh +55 -0
  9. package/scripts/bootstrap-windows.ps1 +75 -0
  10. package/scripts/install-husky.js +43 -0
  11. package/scripts/setup-stack.js +436 -0
  12. package/scripts/setup-test-dbs.sh +61 -0
  13. package/scripts/test-db-adapters.sh +71 -0
  14. package/scripts/verify-bundle.mjs +92 -0
  15. package/tools/definitions.js +143 -0
  16. package/tools/handler-modules/commit-handlers.js +2 -1
  17. package/tools/handler-modules/factory-handlers.js +276 -0
  18. package/tools/handler-modules/index.js +24 -7
  19. package/tools/handler-modules/shared.js +7 -41
  20. package/tools/handler-modules/status-handlers.js +25 -3
  21. package/tools/handler-modules/workflow-handlers.js +57 -10
  22. package/vite.config.js +6 -0
  23. package/workflow-state.js +176 -2
  24. package/.agent/workflows/dev-workflow-bugfix.md +0 -250
  25. package/.agent/workflows/dev-workflow-feature.md +0 -201
  26. package/.agent/workflows/dev-workflow-full-cycle.md +0 -400
  27. package/.agent/workflows/dev-workflow-refactor.md +0 -238
  28. package/.env.production +0 -16
  29. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -34
  30. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -25
  31. package/.github/pull_request_template.md +0 -22
  32. package/.github/workflows/github-release.yml +0 -131
  33. package/.husky/commit-msg +0 -3
  34. package/.husky/pre-commit +0 -2
  35. package/CHANGELOG.md +0 -1145
  36. package/docs/GCP_DEPLOYMENT.md +0 -298
  37. package/docs/NETLIFY_DEPLOYMENT.md +0 -125
  38. package/docs/PLESK_DEPLOYMENT.md +0 -170
  39. package/docs/PRD.md +0 -86
  40. package/docs/WORKFLOW-BEST-PRACTICES.md +0 -58
  41. package/docs/antigravity/EXAMPLES.md +0 -535
  42. package/docs/antigravity/GETTING-STARTED.md +0 -292
  43. package/docs/antigravity/TROUBLESHOOTING.md +0 -742
  44. package/docs/antigravity/WALKTHROUGH.md +0 -25
  45. package/docs/antigravity/WORKFLOW-TEMPLATES.md +0 -670
  46. package/docs/release-notes/RELEASE_NOTES.md +0 -524
  47. package/docs/web-dashboard.md +0 -175
  48. package/scripts/test-auth-flow.js +0 -75
  49. package/tailwind.config.js +0 -8
  50. package/tests/build.test.js +0 -74
  51. package/tests/db-adapters.test.js +0 -108
  52. package/tests/env-support.test.js +0 -46
  53. package/tests/exec.test.js +0 -35
  54. package/tests/handlers-commit.test.js +0 -174
  55. package/tests/handlers-release.test.js +0 -212
  56. package/tests/handlers-workflow.test.js +0 -68
  57. package/tests/handlers.test.js +0 -1142
  58. package/tests/hello-world.test.js +0 -13
  59. package/tests/mcpRegistry.test.js +0 -65
  60. package/tests/patch-release.test.js +0 -7
  61. package/tests/release-wrapper.test.js +0 -107
  62. package/tests/startup-resilience.test.js +0 -73
  63. package/tests/test-helpers.js +0 -50
  64. package/tests/workflowState.test.js +0 -520
  65. package/web/Dockerfile.api +0 -25
  66. package/web/README.md +0 -133
  67. package/web/__tests__/api/workflow-history.test.js +0 -63
  68. package/web/api-server.js +0 -211
  69. package/web/app/docs/page.tsx +0 -202
  70. package/web/app/favicon.ico +0 -0
  71. package/web/app/globals.css +0 -91
  72. package/web/app/history/page.tsx +0 -220
  73. package/web/app/layout.tsx +0 -39
  74. package/web/app/login/page.tsx +0 -142
  75. package/web/app/page.tsx +0 -13
  76. package/web/components/ApiReference.tsx +0 -20
  77. package/web/components/Features.tsx +0 -61
  78. package/web/components/Footer.tsx +0 -9
  79. package/web/components/Hero.tsx +0 -96
  80. package/web/components/History.tsx +0 -175
  81. package/web/components/Navbar.tsx +0 -208
  82. package/web/components/Terminal.tsx +0 -114
  83. package/web/components/ThemeProvider.tsx +0 -58
  84. package/web/eslint.config.mjs +0 -18
  85. package/web/lib/api-client.ts +0 -123
  86. package/web/lib/auth.js +0 -75
  87. package/web/lib/db.js +0 -131
  88. package/web/lib/docs.js +0 -73
  89. package/web/middleware/auth.js +0 -26
  90. package/web/netlify.toml +0 -8
  91. package/web/next.config.ts +0 -19
  92. package/web/package-lock.json +0 -10911
  93. package/web/package.json +0 -42
  94. package/web/postcss.config.mjs +0 -9
  95. package/web/public/assets/android-chrome-192x192.png +0 -0
  96. package/web/public/assets/android-chrome-512x512.png +0 -0
  97. package/web/public/assets/apple-touch-icon.png +0 -0
  98. package/web/public/assets/favicon-16x16.png +0 -0
  99. package/web/public/assets/favicon-32x32.png +0 -0
  100. package/web/public/assets/favicon.ico +0 -0
  101. package/web/public/assets/favicon.png +0 -0
  102. package/web/public/assets/logo.png +0 -0
  103. package/web/public/assets/og-preview.png +0 -0
  104. package/web/public/assets/site.webmanifest +0 -1
  105. package/web/public/file.svg +0 -1
  106. package/web/public/globe.svg +0 -1
  107. package/web/public/next.svg +0 -1
  108. package/web/public/vercel.svg +0 -1
  109. package/web/public/window.svg +0 -1
  110. package/web/scripts/db-query-history.js +0 -120
  111. package/web/scripts/smoke-test.js +0 -30
  112. package/web/server.js +0 -184
  113. package/web/tailwind.config.ts +0 -20
  114. package/web/tsconfig.json +0 -42
@@ -1,212 +0,0 @@
1
- import test from "node:test";
2
- import assert from "node:assert/strict";
3
- import { handleToolCall } from "../tools/handlers.js";
4
- import { withWorkflowState, testUtils, createRequest, createGitMock } from "./test-helpers.js";
5
-
6
- test("perform_release runs release command before pushing with tags", async () => {
7
- await withWorkflowState(async (workflowState) => {
8
- workflowState.state.currentPhase = "release";
9
- workflowState.state.commitAndPushCompleted = true;
10
- workflowState.state.readyCheckCompleted = true;
11
- workflowState.state.lastPushBranch = "feature/split";
12
- workflowState.state.lastCommitMessage = "fix: address issue";
13
- await workflowState.save();
14
-
15
- const commands = [];
16
- const execStub = async (command) => {
17
- commands.push(command);
18
- if (command === "git status --porcelain") {
19
- return { stdout: "" };
20
- }
21
- return { stdout: "" };
22
- };
23
-
24
- const response = await handleToolCall({
25
- request: createRequest("perform_release", { command: "npm run release" }),
26
- normalizeRequestArgs: (args) => ({ args, error: null }),
27
- workflowState,
28
- exec: execStub,
29
- git: createGitMock(),
30
- utils: testUtils,
31
- });
32
-
33
- const releaseCommand = commands.find((command) => command.startsWith("npm run release"));
34
- assert.ok(releaseCommand, "release command should run");
35
- assert.ok(
36
- commands.some((command) => command.startsWith("git push --follow-tags")),
37
- "release should push tags"
38
- );
39
- });
40
- });
41
-
42
- test("perform_release accepts shorthand patch command", async () => {
43
- await withWorkflowState(async (workflowState) => {
44
- workflowState.state.currentPhase = "release";
45
- workflowState.state.commitAndPushCompleted = true;
46
- workflowState.state.readyCheckCompleted = true;
47
- workflowState.state.lastCommitMessage = "fix: adjust labels";
48
- await workflowState.save();
49
-
50
- const commands = [];
51
- const execStub = async (command) => {
52
- commands.push(command);
53
- if (command === "git status --porcelain") {
54
- return { stdout: "" };
55
- }
56
- return { stdout: "" };
57
- };
58
-
59
- await handleToolCall({
60
- request: createRequest("perform_release", { command: "patch" }),
61
- normalizeRequestArgs: (args) => ({ args, error: null }),
62
- workflowState,
63
- exec: execStub,
64
- git: createGitMock(),
65
- utils: testUtils,
66
- });
67
-
68
- const releaseCommand = commands.find((command) => command.startsWith("npm run release"));
69
- assert.ok(releaseCommand, "release command should run with patch");
70
- });
71
- });
72
-
73
- test("perform_release respects explicit releaseType option", async () => {
74
- await withWorkflowState(async (workflowState) => {
75
- workflowState.state.currentPhase = "release";
76
- workflowState.state.commitAndPushCompleted = true;
77
- workflowState.state.readyCheckCompleted = true;
78
- await workflowState.save();
79
-
80
- const commands = [];
81
- const execStub = async (command) => {
82
- commands.push(command);
83
- if (command === "git status --porcelain") {
84
- return { stdout: "" };
85
- }
86
- return { stdout: "" };
87
- };
88
-
89
- await handleToolCall({
90
- request: createRequest("perform_release", {
91
- command: "npm run release",
92
- releaseType: "minor",
93
- }),
94
- normalizeRequestArgs: (args) => ({ args, error: null }),
95
- workflowState,
96
- exec: execStub,
97
- git: createGitMock(),
98
- utils: testUtils,
99
- });
100
-
101
- const releaseCommand = commands.find((command) => command.startsWith("npm run release"));
102
- assert.ok(releaseCommand, "release command should run");
103
- assert.ok(
104
- releaseCommand.includes("-- --release-as minor"),
105
- "release command should append provided releaseType"
106
- );
107
- });
108
- });
109
-
110
- test("perform_release blocks when new changes detected", async () => {
111
- await withWorkflowState(async (workflowState) => {
112
- workflowState.state.currentPhase = "release";
113
- workflowState.state.commitAndPushCompleted = true;
114
- workflowState.state.readyCheckCompleted = true;
115
- await workflowState.save();
116
-
117
- const commands = [];
118
- const execStub = async (command) => {
119
- commands.push(command);
120
- if (command === "git status --porcelain") {
121
- return { stdout: "?? new-file.js" };
122
- }
123
- return { stdout: "" };
124
- };
125
-
126
- const response = await handleToolCall({
127
- request: createRequest("perform_release", { command: "patch" }),
128
- normalizeRequestArgs: (args) => ({ args, error: null }),
129
- workflowState,
130
- exec: execStub,
131
- git: createGitMock({
132
- hasWorkingChanges: async () => true,
133
- getStatusOutput: async () => "?? new-file.js",
134
- containsTestFilesInStatus: (statusOutput) => statusOutput.includes("tests/"),
135
- workingTreeSummary: () => ({ hasChanges: true, lines: ["?? new-file.js"] }),
136
- }),
137
- utils: testUtils,
138
- });
139
-
140
- assert.ok(
141
- response.content[0].text.includes("run 'commit_and_push' again"),
142
- "response should instruct to recommit"
143
- );
144
- assert.equal(workflowState.state.currentPhase, "commit");
145
- assert.equal(workflowState.state.commitAndPushCompleted, false);
146
- });
147
- });
148
-
149
- test("perform_release requires commit_and_push completion when tree is clean", async () => {
150
- await withWorkflowState(async (workflowState) => {
151
- workflowState.state.currentPhase = "release";
152
- workflowState.state.commitAndPushCompleted = false;
153
- workflowState.state.readyCheckCompleted = true;
154
- workflowState.state.lastPushBranch = "";
155
- workflowState.state.lastCommitMessage = "";
156
- await workflowState.save();
157
-
158
- const commands = [];
159
- const execStub = async (command) => {
160
- commands.push(command);
161
- return { stdout: "" };
162
- };
163
-
164
- const response = await handleToolCall({
165
- request: createRequest("perform_release", { command: "npm run release" }),
166
- normalizeRequestArgs: (args) => ({ args, error: null }),
167
- workflowState,
168
- exec: execStub,
169
- git: createGitMock({
170
- getLastCommitMessage: async () => "chore: already pushed",
171
- getStatusOutput: async () => "",
172
- containsTestFilesInStatus: (statusOutput) => statusOutput.includes("tests/"),
173
- }),
174
- utils: testUtils,
175
- });
176
-
177
- assert.ok(
178
- response.content[0].text.includes("commit_and_push"),
179
- "response should mention commit_and_push requirement"
180
- );
181
- });
182
- });
183
-
184
- test("skip_release records justification and advances to completion phase", async () => {
185
- await withWorkflowState(async (workflowState) => {
186
- workflowState.state.currentPhase = "release";
187
- workflowState.state.commitAndPushCompleted = true;
188
- workflowState.state.readyCheckCompleted = true;
189
- workflowState.state.lastCommitMessage = "chore: docs";
190
- workflowState.state.releaseSkipped = false;
191
- workflowState.state.released = false;
192
- workflowState.state.releaseCommand = "";
193
- await workflowState.save();
194
-
195
- const response = await handleToolCall({
196
- request: createRequest("skip_release", { reason: "Python project – no npm release" }),
197
- normalizeRequestArgs: (args) => ({ args, error: null }),
198
- workflowState,
199
- exec: async () => ({ stdout: "" }),
200
- git: createGitMock(),
201
- utils: testUtils,
202
- });
203
-
204
- const text = response.content[0].text;
205
- assert.ok(text.includes("Release step skipped"), "response should mention release was skipped");
206
- assert.equal(workflowState.state.releaseSkipped, true);
207
- assert.equal(workflowState.state.releaseSkippedReason, "Python project – no npm release");
208
- assert.equal(workflowState.state.releaseCommand, "(skipped)");
209
- assert.equal(workflowState.state.currentPhase, "ready_to_complete");
210
- assert.equal(workflowState.state.released, false);
211
- });
212
- });
@@ -1,68 +0,0 @@
1
- import test from "node:test";
2
- import assert from "node:assert/strict";
3
- import { handleToolCall } from "../tools/handlers.js";
4
- import { withWorkflowState, testUtils, createRequest, createGitMock } from "./test-helpers.js";
5
-
6
- test("run_tests guidance mentions core documentation types", async () => {
7
- await withWorkflowState(async (workflowState) => {
8
- workflowState.state.bugFixed = true;
9
- workflowState.state.testsCreated = true;
10
- await workflowState.save();
11
-
12
- const response = await handleToolCall({
13
- request: createRequest("run_tests", {
14
- passed: true,
15
- testCommand: "npm test",
16
- }),
17
- normalizeRequestArgs: (args) => ({ args, error: null }),
18
- workflowState,
19
- exec: async () => ({ stdout: "" }),
20
- git: createGitMock(),
21
- utils: testUtils,
22
- });
23
-
24
- const text = response.content[0].text;
25
- assert.ok(
26
- text.includes("create or update documentation using 'create_documentation'"),
27
- "run_tests guidance should mention create or update documentation",
28
- );
29
- assert.ok(
30
- text.includes('"PRD", "README", "RELEASE_NOTES"'),
31
- "run_tests guidance should list core documentation types",
32
- );
33
- });
34
- });
35
-
36
- test("create_documentation verifies PRD file exists", async () => {
37
- await withWorkflowState(async (workflowState) => {
38
- workflowState.state.testsPassed = true;
39
- await workflowState.save();
40
-
41
- const response = await handleToolCall({
42
- request: createRequest("create_documentation", {
43
- documentationType: "PRD",
44
- summary: "Updated PRD for documentation workflow expectations",
45
- }),
46
- normalizeRequestArgs: (args) => ({ args, error: null }),
47
- workflowState,
48
- exec: async () => ({ stdout: "" }),
49
- git: createGitMock(),
50
- utils: testUtils,
51
- });
52
-
53
- assert.equal(workflowState.state.documentationCreated, true);
54
- assert.equal(workflowState.state.documentationType, "PRD");
55
- assert.equal(
56
- workflowState.state.documentationSummary,
57
- "Updated PRD for documentation workflow expectations",
58
- );
59
- assert.ok(
60
- response.content[0].text.includes("Documentation created/updated!"),
61
- "create_documentation response should mention created/updated",
62
- );
63
- assert.ok(
64
- response.content[0].text.includes("PRD verified"),
65
- "create_documentation response should verify PRD file",
66
- );
67
- });
68
- });