@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
@@ -1,13 +1,13 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
- import { execSync } from 'node:child_process';
4
- import path from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
-
9
- test('hello world script runs successfully', (t) => {
10
- const scriptPath = path.join(__dirname, '../scripts/hello-world.js');
11
- const output = execSync(`node ${scriptPath}`).toString();
12
- assert.match(output, /Hello from Antigravity!/);
13
- });
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import { execSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+
9
+ test('hello world script runs successfully', (t) => {
10
+ const scriptPath = path.join(__dirname, '../scripts/hello-world.js');
11
+ const output = execSync(`node ${scriptPath}`).toString();
12
+ assert.match(output, /Hello from Antigravity!/);
13
+ });
@@ -1,65 +1,65 @@
1
- import { test } from "node:test";
2
- import assert from "node:assert";
3
- import { readFile } from "node:fs/promises";
4
- import path from "node:path";
5
-
6
- const projectRoot = process.cwd();
7
-
8
- async function readJson(relativePath) {
9
- const fullPath = path.join(projectRoot, relativePath);
10
- const content = await readFile(fullPath, "utf-8");
11
- return JSON.parse(content);
12
- }
13
-
14
- test("package.json includes mcpName for MCP registry", async () => {
15
- const pkg = await readJson("package.json");
16
-
17
- assert.strictEqual(
18
- pkg.mcpName,
19
- "io.github.programinglive/dev-workflow-mcp-server",
20
- "package.json should declare mcpName matching the MCP server namespace",
21
- );
22
- });
23
-
24
- test("server.json is configured for npm package deployment", async () => {
25
- const server = await readJson("server.json");
26
-
27
- assert.strictEqual(
28
- server.name,
29
- "io.github.programinglive/dev-workflow-mcp-server",
30
- "server.json name should match the MCP server namespace",
31
- );
32
- assert.ok(Array.isArray(server.packages) && server.packages.length > 0,
33
- "server.json should declare at least one package entry",
34
- );
35
-
36
- const npmPkg = server.packages[0];
37
-
38
- assert.strictEqual(
39
- npmPkg.registryType,
40
- "npm",
41
- "First server.json package entry should use npm registryType",
42
- );
43
-
44
- assert.strictEqual(
45
- npmPkg.registryBaseUrl,
46
- "https://registry.npmjs.org",
47
- "server.json npm registryBaseUrl should point at the public npm registry",
48
- );
49
-
50
- assert.strictEqual(
51
- npmPkg.identifier,
52
- "@programinglive/dev-workflow-mcp-server",
53
- "server.json npm identifier should match the published npm package name",
54
- );
55
-
56
- assert.ok(
57
- typeof npmPkg.version === "string" && npmPkg.version.length > 0,
58
- "server.json npm package version should be a non-empty string",
59
- );
60
-
61
- assert.ok(
62
- npmPkg.transport && npmPkg.transport.type === "stdio",
63
- "server.json npm package transport should be stdio",
64
- );
65
- });
1
+ import { test } from "node:test";
2
+ import assert from "node:assert";
3
+ import { readFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+
6
+ const projectRoot = process.cwd();
7
+
8
+ async function readJson(relativePath) {
9
+ const fullPath = path.join(projectRoot, relativePath);
10
+ const content = await readFile(fullPath, "utf-8");
11
+ return JSON.parse(content);
12
+ }
13
+
14
+ test("package.json includes mcpName for MCP registry", async () => {
15
+ const pkg = await readJson("package.json");
16
+
17
+ assert.strictEqual(
18
+ pkg.mcpName,
19
+ "io.github.programinglive/dev-workflow-mcp-server",
20
+ "package.json should declare mcpName matching the MCP server namespace",
21
+ );
22
+ });
23
+
24
+ test("server.json is configured for npm package deployment", async () => {
25
+ const server = await readJson("server.json");
26
+
27
+ assert.strictEqual(
28
+ server.name,
29
+ "io.github.programinglive/dev-workflow-mcp-server",
30
+ "server.json name should match the MCP server namespace",
31
+ );
32
+ assert.ok(Array.isArray(server.packages) && server.packages.length > 0,
33
+ "server.json should declare at least one package entry",
34
+ );
35
+
36
+ const npmPkg = server.packages[0];
37
+
38
+ assert.strictEqual(
39
+ npmPkg.registryType,
40
+ "npm",
41
+ "First server.json package entry should use npm registryType",
42
+ );
43
+
44
+ assert.strictEqual(
45
+ npmPkg.registryBaseUrl,
46
+ "https://registry.npmjs.org",
47
+ "server.json npm registryBaseUrl should point at the public npm registry",
48
+ );
49
+
50
+ assert.strictEqual(
51
+ npmPkg.identifier,
52
+ "@programinglive/dev-workflow-mcp-server",
53
+ "server.json npm identifier should match the published npm package name",
54
+ );
55
+
56
+ assert.ok(
57
+ typeof npmPkg.version === "string" && npmPkg.version.length > 0,
58
+ "server.json npm package version should be a non-empty string",
59
+ );
60
+
61
+ assert.ok(
62
+ npmPkg.transport && npmPkg.transport.type === "stdio",
63
+ "server.json npm package transport should be stdio",
64
+ );
65
+ });
@@ -1,107 +1,107 @@
1
- import test from "node:test";
2
- import assert from "node:assert/strict";
3
- import { mkdtemp, rm, writeFile, readFile, mkdir } from "node:fs/promises";
4
- import { tmpdir } from "node:os";
5
- import path from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- import { spawn } from "node:child_process";
8
-
9
- const __filename = fileURLToPath(import.meta.url);
10
- const __dirname = path.dirname(__filename);
11
- const releaseWrapperUrl = new URL("../release-wrapper.js", import.meta.url);
12
- const RELEASE_WRAPPER = fileURLToPath(releaseWrapperUrl);
13
- const PROJECT_ROOT = path.dirname(RELEASE_WRAPPER);
14
-
15
- async function runWrapper({ state, args = ["patch"], env = {} }) {
16
- const dir = await mkdtemp(path.join(tmpdir(), "release-wrapper-test-"));
17
- const stateDir = path.join(dir, ".state");
18
- const statePath = path.join(stateDir, "workflow-state.json");
19
- await mkdir(stateDir, { recursive: true });
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" }));
23
-
24
- const childEnv = {
25
- ...process.env,
26
- INIT_CWD: dir,
27
- DEV_WORKFLOW_SKIP_RELEASE: "1",
28
- DEV_WORKFLOW_FORCE_RELEASE: undefined,
29
- ...env,
30
- };
31
-
32
- const nodeBinary = process.platform === "win32" ? "node" : process.execPath || "node";
33
- const spawnShell = process.platform === "win32";
34
-
35
- return await new Promise((resolve) => {
36
- const child = spawn(
37
- nodeBinary,
38
- [RELEASE_WRAPPER, ...args],
39
- {
40
- cwd: PROJECT_ROOT,
41
- env: childEnv,
42
- stdio: ["ignore", "pipe", "pipe"],
43
- shell: spawnShell,
44
- }
45
- );
46
-
47
- let stdout = "";
48
- let stderr = "";
49
-
50
- child.stdout.on("data", (chunk) => {
51
- stdout += chunk;
52
- });
53
- child.stderr.on("data", (chunk) => {
54
- stderr += chunk;
55
- });
56
-
57
- child.on("close", async (code) => {
58
- let updatedState = null;
59
- try {
60
- const rawState = await readFile(statePath, "utf8");
61
- updatedState = JSON.parse(rawState);
62
- } catch {
63
- // ignore
64
- }
65
-
66
- await rm(dir, { recursive: true, force: true });
67
- resolve({ code, stdout, stderr, updatedState });
68
- });
69
- });
70
- }
71
-
72
- test("release-wrapper blocks when workflow phase is not release", async () => {
73
- const result = await runWrapper({
74
- state: {
75
- currentPhase: "commit",
76
- readyCheckCompleted: true,
77
- commitAndPushCompleted: true,
78
- released: false,
79
- },
80
- });
81
-
82
- assert.equal(result.code, 1);
83
- assert.ok(result.stderr.includes("Release guard blocked the release"));
84
- assert.ok(result.stderr.includes("Current workflow phase"));
85
- assert.equal(result.updatedState.released, false);
86
- });
87
-
88
- test("release-wrapper marks release after validation passes", async () => {
89
- const result = await runWrapper({
90
- state: {
91
- currentPhase: "release",
92
- readyCheckCompleted: true,
93
- commitAndPushCompleted: true,
94
- released: false,
95
- releaseCommand: "",
96
- },
97
- });
98
-
99
- assert.equal(result.code, 0);
100
- assert.ok(result.stdout.includes("Release recorded"));
101
- assert.equal(result.updatedState.released, true);
102
- assert.equal(result.updatedState.currentPhase, "ready_to_complete");
103
- assert.equal(
104
- result.updatedState.releaseCommand,
105
- "node node_modules/@programinglive/commiter/scripts/release.js patch"
106
- );
107
- });
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtemp, rm, writeFile, readFile, mkdir } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { spawn } from "node:child_process";
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ const releaseWrapperUrl = new URL("../release-wrapper.js", import.meta.url);
12
+ const RELEASE_WRAPPER = fileURLToPath(releaseWrapperUrl);
13
+ const PROJECT_ROOT = path.dirname(RELEASE_WRAPPER);
14
+
15
+ async function runWrapper({ state, args = ["patch"], env = {} }) {
16
+ const dir = await mkdtemp(path.join(tmpdir(), "release-wrapper-test-"));
17
+ const stateDir = path.join(dir, ".state");
18
+ const statePath = path.join(stateDir, "workflow-state.json");
19
+ await mkdir(stateDir, { recursive: true });
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" }));
23
+
24
+ const childEnv = {
25
+ ...process.env,
26
+ INIT_CWD: dir,
27
+ DEV_WORKFLOW_SKIP_RELEASE: "1",
28
+ DEV_WORKFLOW_FORCE_RELEASE: undefined,
29
+ ...env,
30
+ };
31
+
32
+ const nodeBinary = process.platform === "win32" ? "node" : process.execPath || "node";
33
+ const spawnShell = process.platform === "win32";
34
+
35
+ return await new Promise((resolve) => {
36
+ const child = spawn(
37
+ nodeBinary,
38
+ [RELEASE_WRAPPER, ...args],
39
+ {
40
+ cwd: PROJECT_ROOT,
41
+ env: childEnv,
42
+ stdio: ["ignore", "pipe", "pipe"],
43
+ shell: spawnShell,
44
+ }
45
+ );
46
+
47
+ let stdout = "";
48
+ let stderr = "";
49
+
50
+ child.stdout.on("data", (chunk) => {
51
+ stdout += chunk;
52
+ });
53
+ child.stderr.on("data", (chunk) => {
54
+ stderr += chunk;
55
+ });
56
+
57
+ child.on("close", async (code) => {
58
+ let updatedState = null;
59
+ try {
60
+ const rawState = await readFile(statePath, "utf8");
61
+ updatedState = JSON.parse(rawState);
62
+ } catch {
63
+ // ignore
64
+ }
65
+
66
+ await rm(dir, { recursive: true, force: true });
67
+ resolve({ code, stdout, stderr, updatedState });
68
+ });
69
+ });
70
+ }
71
+
72
+ test("release-wrapper blocks when workflow phase is not release", async () => {
73
+ const result = await runWrapper({
74
+ state: {
75
+ currentPhase: "commit",
76
+ readyCheckCompleted: true,
77
+ commitAndPushCompleted: true,
78
+ released: false,
79
+ },
80
+ });
81
+
82
+ assert.equal(result.code, 1);
83
+ assert.ok(result.stderr.includes("Release guard blocked the release"));
84
+ assert.ok(result.stderr.includes("Current workflow phase"));
85
+ assert.equal(result.updatedState.released, false);
86
+ });
87
+
88
+ test("release-wrapper marks release after validation passes", async () => {
89
+ const result = await runWrapper({
90
+ state: {
91
+ currentPhase: "release",
92
+ readyCheckCompleted: true,
93
+ commitAndPushCompleted: true,
94
+ released: false,
95
+ releaseCommand: "",
96
+ },
97
+ });
98
+
99
+ assert.equal(result.code, 0);
100
+ assert.ok(result.stdout.includes("Release recorded"));
101
+ assert.equal(result.updatedState.released, true);
102
+ assert.equal(result.updatedState.currentPhase, "ready_to_complete");
103
+ assert.equal(
104
+ result.updatedState.releaseCommand,
105
+ "node node_modules/@programinglive/commiter/scripts/release.js patch"
106
+ );
107
+ });