@programinglive/dev-workflow-mcp-server 1.3.12 → 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.
- package/.github/workflows/npm-publish.yml +3 -0
- package/CHANGELOG.md +108 -0
- package/README.md +1 -1
- package/docs/PLESK_DEPLOYMENT.md +170 -0
- package/docs/WORKFLOW-BEST-PRACTICES.md +14 -0
- package/docs/release-notes/RELEASE_NOTES.md +26 -0
- package/package.json +7 -6
- package/release-wrapper.js +68 -33
- package/tests/build.test.js +3 -3
- package/tests/handlers.test.js +78 -0
- package/tests/release-wrapper.test.js +2 -0
- package/tests/workflowState.test.js +7 -4
- package/tools/definitions.js +2 -2
- package/tools/handlers.js +2 -2
- package/vite.web.config.js +23 -0
- package/web/README.md +36 -0
- package/web/app/api/docs/route.ts +32 -0
- package/web/app/api/history/route.ts +19 -0
- package/web/app/api/npm-downloads/route.ts +21 -0
- package/web/app/api/summary/route.ts +15 -0
- package/web/app/api/version/route.ts +15 -0
- package/web/app/docs/page.tsx +202 -0
- package/web/app/favicon.ico +0 -0
- package/web/app/globals.css +91 -0
- package/web/app/layout.tsx +36 -0
- package/web/app/page.tsx +15 -0
- package/web/components/ApiReference.tsx +20 -0
- package/web/components/Features.tsx +61 -0
- package/web/components/Footer.tsx +9 -0
- package/web/components/Hero.tsx +91 -0
- package/web/components/History.tsx +143 -0
- package/web/components/Navbar.tsx +64 -0
- package/web/components/Terminal.tsx +114 -0
- package/web/eslint.config.mjs +18 -0
- package/web/lib/db.js +131 -0
- package/web/lib/docs.js +73 -0
- package/web/next.config.ts +8 -0
- package/web/package-lock.json +6971 -0
- package/web/package.json +29 -0
- package/web/postcss.config.mjs +9 -0
- package/web/public/assets/android-chrome-192x192.png +0 -0
- package/web/public/assets/android-chrome-512x512.png +0 -0
- package/web/public/assets/apple-touch-icon.png +0 -0
- package/web/public/assets/favicon-16x16.png +0 -0
- package/web/public/assets/favicon-32x32.png +0 -0
- package/web/public/assets/favicon.ico +0 -0
- package/web/public/assets/favicon.png +0 -0
- package/web/public/assets/logo.png +0 -0
- package/web/public/assets/og-preview.png +0 -0
- package/web/public/assets/site.webmanifest +1 -0
- package/web/public/file.svg +1 -0
- package/web/public/globe.svg +1 -0
- package/web/public/next.svg +1 -0
- package/web/public/vercel.svg +1 -0
- package/web/public/window.svg +1 -0
- package/web/server.js +30 -158
- package/web/tailwind.config.ts +19 -0
- package/web/tsconfig.json +42 -0
- package/web-legacy/public/assets/android-chrome-192x192.png +0 -0
- package/web-legacy/public/assets/android-chrome-512x512.png +0 -0
- package/web-legacy/public/assets/apple-touch-icon.png +0 -0
- package/web-legacy/public/assets/favicon-16x16.png +0 -0
- package/web-legacy/public/assets/favicon-32x32.png +0 -0
- package/web-legacy/public/assets/favicon.ico +0 -0
- package/web-legacy/public/assets/favicon.png +0 -0
- package/web-legacy/public/assets/logo.png +0 -0
- package/web-legacy/public/assets/og-preview.png +0 -0
- package/web-legacy/public/assets/site.webmanifest +1 -0
- package/{dist → web-legacy/public}/docs/EXAMPLES.html +87 -2
- package/{dist → web-legacy/public}/docs/GETTING-STARTED.html +87 -2
- package/{dist → web-legacy/public}/docs/README.html +87 -2
- package/{dist → web-legacy/public}/docs/RELEASE_NOTES.html +92 -2
- package/{dist → web-legacy/public}/docs/TROUBLESHOOTING.html +87 -2
- package/{dist → web-legacy/public}/docs/WORKFLOW-TEMPLATES.html +87 -2
- package/{dist → web-legacy/public}/docs/web-dashboard.html +87 -2
- package/web-legacy/public/index.html +223 -0
- package/web-legacy/public/input.css +80 -0
- package/web-legacy/public/main.js +167 -0
- package/web-legacy/public/output.css +1559 -0
- package/web-legacy/server.js +207 -0
- package/workflow-state.js +11 -25
- package/web/public/index.html +0 -1046
- package/web/public/input.css +0 -3
- package/web/public/output.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,114 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.4.4](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.4.1...v1.4.4) (2025-11-27)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ♻️ Refactors
|
|
9
|
+
|
|
10
|
+
* consolidate workflow state to root .state folder only ([3d69a14](https://github.com/programinglive/dev-workflow-mcp-server/commit/3d69a14e2abd7897bc91ede5e3c484b90eefc726))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### 🐛 Bug Fixes
|
|
14
|
+
|
|
15
|
+
* ensure release guard uses freshest workflow state ([e07eb42](https://github.com/programinglive/dev-workflow-mcp-server/commit/e07eb42179f17f2da282bff70392ce1b4652346a))
|
|
16
|
+
* remove invalid turbopack experimental config from next.config.ts ([af0a7ea](https://github.com/programinglive/dev-workflow-mcp-server/commit/af0a7ea7906654755a2520693fd81d7fb6633c13))
|
|
17
|
+
* **web:** configure next.js root to silence warnings ([22ed002](https://github.com/programinglive/dev-workflow-mcp-server/commit/22ed00256a4c6d7dbca13d2733baf0f4392b6650))
|
|
18
|
+
* **web:** improve mobile layout for hero section ([53b26bf](https://github.com/programinglive/dev-workflow-mcp-server/commit/53b26bf3271cab3ac029be8ddb72a8d5312b150e))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### 📝 Documentation
|
|
22
|
+
|
|
23
|
+
* add Plesk deployment guide ([de35675](https://github.com/programinglive/dev-workflow-mcp-server/commit/de356753231d1bb29fd3c87fdd9d095932fae4b0))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### 🧹 Chores
|
|
27
|
+
|
|
28
|
+
* add 1.4.3 release notes ([8b165f7](https://github.com/programinglive/dev-workflow-mcp-server/commit/8b165f7a8201f6b8484dce60f3f907cb195abb83))
|
|
29
|
+
* fix release state detection ([ed5dfd1](https://github.com/programinglive/dev-workflow-mcp-server/commit/ed5dfd15d296c555bd5c2731267a87ad4a371af9))
|
|
30
|
+
* prepare for release ([a6ea2d0](https://github.com/programinglive/dev-workflow-mcp-server/commit/a6ea2d0c44f35f2a1e06c4e01bbe026177e9cff2))
|
|
31
|
+
* **release:** 1.4.2 ([fac8999](https://github.com/programinglive/dev-workflow-mcp-server/commit/fac899992d370c0198954a6f7c97ab7645514e25))
|
|
32
|
+
* **release:** 1.4.2 🚀 ([01b0b3c](https://github.com/programinglive/dev-workflow-mcp-server/commit/01b0b3c791c10b76c05bae01e4e8c5ce7435ce14))
|
|
33
|
+
* **release:** 1.4.3 🚀 ([04d8c3b](https://github.com/programinglive/dev-workflow-mcp-server/commit/04d8c3b2873ce819633c95a12f6c48e73fe671ea))
|
|
34
|
+
* update task list ([35663dd](https://github.com/programinglive/dev-workflow-mcp-server/commit/35663dd661d3b97a5fedb5013fbbca36e75605d8))
|
|
35
|
+
* **web:** fix next.js lockfile warning ([05ffce0](https://github.com/programinglive/dev-workflow-mcp-server/commit/05ffce0b171cb804c6a14223521cd1fa876b80ae))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### ✨ Features
|
|
39
|
+
|
|
40
|
+
* add core doc types (PRD/README/RELEASE_NOTES) and fix CI build ([8ed0567](https://github.com/programinglive/dev-workflow-mcp-server/commit/8ed0567e8de772b95de6fb744a936b07ed3e1c32))
|
|
41
|
+
* update hero text and meta description to emphasize Indonesian programmer community ([681547b](https://github.com/programinglive/dev-workflow-mcp-server/commit/681547b764b2fcf3a874cc637d9653c12bf62640))
|
|
42
|
+
* update program tracks and fix fast refresh warning ([aa5bc9c](https://github.com/programinglive/dev-workflow-mcp-server/commit/aa5bc9cbc8a9bf9c9552e00e89b0b97ddeac0592))
|
|
43
|
+
|
|
44
|
+
### [1.4.3](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.4.2...v1.4.3) (2025-11-27)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### 🧹 Chores
|
|
48
|
+
|
|
49
|
+
* **release:** 1.4.2 ([fac8999](https://github.com/programinglive/dev-workflow-mcp-server/commit/fac899992d370c0198954a6f7c97ab7645514e25))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### 🐛 Bug Fixes
|
|
53
|
+
|
|
54
|
+
* remove invalid turbopack experimental config from next.config.ts ([af0a7ea](https://github.com/programinglive/dev-workflow-mcp-server/commit/af0a7ea7906654755a2520693fd81d7fb6633c13))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### 📝 Documentation
|
|
58
|
+
|
|
59
|
+
* add Plesk deployment guide ([de35675](https://github.com/programinglive/dev-workflow-mcp-server/commit/de356753231d1bb29fd3c87fdd9d095932fae4b0))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### ✨ Features
|
|
63
|
+
|
|
64
|
+
* update program tracks and fix fast refresh warning ([aa5bc9c](https://github.com/programinglive/dev-workflow-mcp-server/commit/aa5bc9cbc8a9bf9c9552e00e89b0b97ddeac0592))
|
|
65
|
+
|
|
66
|
+
### [1.4.2](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.4.1...v1.4.2) (2025-11-27)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### 🧹 Chores
|
|
70
|
+
|
|
71
|
+
* fix release state detection ([ed5dfd1](https://github.com/programinglive/dev-workflow-mcp-server/commit/ed5dfd15d296c555bd5c2731267a87ad4a371af9))
|
|
72
|
+
* prepare for release ([a6ea2d0](https://github.com/programinglive/dev-workflow-mcp-server/commit/a6ea2d0c44f35f2a1e06c4e01bbe026177e9cff2))
|
|
73
|
+
* update task list ([35663dd](https://github.com/programinglive/dev-workflow-mcp-server/commit/35663dd661d3b97a5fedb5013fbbca36e75605d8))
|
|
74
|
+
* **web:** fix next.js lockfile warning ([05ffce0](https://github.com/programinglive/dev-workflow-mcp-server/commit/05ffce0b171cb804c6a14223521cd1fa876b80ae))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
### 🐛 Bug Fixes
|
|
78
|
+
|
|
79
|
+
* ensure release guard uses freshest workflow state ([e07eb42](https://github.com/programinglive/dev-workflow-mcp-server/commit/e07eb42179f17f2da282bff70392ce1b4652346a))
|
|
80
|
+
* **web:** configure next.js root to silence warnings ([22ed002](https://github.com/programinglive/dev-workflow-mcp-server/commit/22ed00256a4c6d7dbca13d2733baf0f4392b6650))
|
|
81
|
+
* **web:** improve mobile layout for hero section ([53b26bf](https://github.com/programinglive/dev-workflow-mcp-server/commit/53b26bf3271cab3ac029be8ddb72a8d5312b150e))
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
### ♻️ Refactors
|
|
85
|
+
|
|
86
|
+
* consolidate workflow state to root .state folder only ([3d69a14](https://github.com/programinglive/dev-workflow-mcp-server/commit/3d69a14e2abd7897bc91ede5e3c484b90eefc726))
|
|
87
|
+
|
|
88
|
+
### [1.4.1](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.4.0...v1.4.1) (2025-11-27)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
### 🐛 Bug Fixes
|
|
92
|
+
|
|
93
|
+
* update build test to include postbuild ([b1e2f48](https://github.com/programinglive/dev-workflow-mcp-server/commit/b1e2f481334df825109e3f2934c88b8f14c1b4d0))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
### ✨ Features
|
|
97
|
+
|
|
98
|
+
* add custom server.js for Plesk ([b3912cd](https://github.com/programinglive/dev-workflow-mcp-server/commit/b3912cdaf50085ae30cab553a9ebac2b7281ee28))
|
|
99
|
+
|
|
100
|
+
## [1.4.0](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.3.12...v1.4.0) (2025-11-26)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
### ✨ Features
|
|
104
|
+
|
|
105
|
+
* migrate dashboard to Next.js with TypeScript and Tailwind CSS ([bce1fec](https://github.com/programinglive/dev-workflow-mcp-server/commit/bce1fec98a7b5e5542644271a77ccaf1019dd83c))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
### 🧹 Chores
|
|
109
|
+
|
|
110
|
+
* fix package.json scripts ([fb25e98](https://github.com/programinglive/dev-workflow-mcp-server/commit/fb25e98c763d4b5cac5c321f56a2e533577fc38b))
|
|
111
|
+
* fix tsconfig and remove dist artifact ([282759f](https://github.com/programinglive/dev-workflow-mcp-server/commit/282759f14de6231ad6374dc891b551ca0d70ac28))
|
|
112
|
+
|
|
5
113
|
### [1.3.12](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.3.11...v1.3.12) (2025-11-22)
|
|
6
114
|
|
|
7
115
|
|
package/README.md
CHANGED
|
@@ -431,7 +431,7 @@ Use run_tests with:
|
|
|
431
431
|
Mark that documentation has been created/updated. This is required before committing.
|
|
432
432
|
|
|
433
433
|
**Parameters:**
|
|
434
|
-
- `documentationType` (enum, required): "README", "inline-comments", "API-docs", "changelog", or "other"
|
|
434
|
+
- `documentationType` (enum, required): "PRD", "README", "RELEASE_NOTES", "inline-comments", "API-docs", "changelog", or "other"
|
|
435
435
|
- `summary` (string, required): What was documented
|
|
436
436
|
|
|
437
437
|
### `check_ready_to_commit`
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Deploying dev-workflow-mcp-server to Plesk
|
|
2
|
+
|
|
3
|
+
This guide covers deploying the dev-workflow MCP server (Node.js backend + Next.js frontend) to Plesk hosting.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Plesk control panel access
|
|
8
|
+
- Node.js 18+ installed on the server
|
|
9
|
+
- Git installed on the server
|
|
10
|
+
- Domain/subdomain configured in Plesk
|
|
11
|
+
|
|
12
|
+
## Deployment Steps
|
|
13
|
+
|
|
14
|
+
### 1. Set Up Node.js Application in Plesk
|
|
15
|
+
|
|
16
|
+
1. Log in to Plesk control panel
|
|
17
|
+
2. Go to **Domains** → Select your domain
|
|
18
|
+
3. Click **Node.js** (or **Applications** if using newer Plesk)
|
|
19
|
+
4. Click **Add Application**
|
|
20
|
+
5. Configure:
|
|
21
|
+
- **Application root**: `/var/www/vhosts/yourdomain.com/dev-workflow-mcp-server` (or your path)
|
|
22
|
+
- **Startup file**: `index.js`
|
|
23
|
+
- **Node.js version**: 18.x or higher
|
|
24
|
+
- **Port**: Leave as auto (Plesk assigns a port)
|
|
25
|
+
|
|
26
|
+
### 2. Clone Repository
|
|
27
|
+
|
|
28
|
+
SSH into your Plesk server:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd /var/www/vhosts/yourdomain.com
|
|
32
|
+
git clone https://github.com/programinglive/dev-workflow-mcp-server.git
|
|
33
|
+
cd dev-workflow-mcp-server
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Install Dependencies
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 4. Build the Application
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm run build
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This builds:
|
|
49
|
+
- **Backend**: Vite bundle → `dist/index.mjs`
|
|
50
|
+
- **Frontend**: Next.js static + server → `web/.next/`
|
|
51
|
+
- **Docs**: HTML files → `dist/docs/`
|
|
52
|
+
|
|
53
|
+
### 5. Configure Environment (if needed)
|
|
54
|
+
|
|
55
|
+
Create `.env` file in the project root if you need custom settings:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Example (adjust as needed)
|
|
59
|
+
NODE_ENV=production
|
|
60
|
+
PORT=3000
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 6. Start the Application
|
|
64
|
+
|
|
65
|
+
In Plesk:
|
|
66
|
+
1. Go back to **Node.js Applications**
|
|
67
|
+
2. Find your application
|
|
68
|
+
3. Click **Start** (or it may auto-start)
|
|
69
|
+
|
|
70
|
+
Alternatively, via SSH:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm start
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 7. Configure Reverse Proxy (Plesk)
|
|
77
|
+
|
|
78
|
+
Plesk automatically sets up a reverse proxy. Verify:
|
|
79
|
+
1. Go to **Domains** → Your domain → **Web Server Settings**
|
|
80
|
+
2. Ensure **Proxy** is enabled
|
|
81
|
+
3. Verify the proxy points to the Node.js app port
|
|
82
|
+
|
|
83
|
+
### 8. Verify Deployment
|
|
84
|
+
|
|
85
|
+
- Visit `https://yourdomain.com` → Should see the Next.js frontend
|
|
86
|
+
- Visit `https://yourdomain.com/docs` → Should see documentation
|
|
87
|
+
- Check browser console for any `_next/static` 500 errors
|
|
88
|
+
|
|
89
|
+
If you see 500 errors on `_next/static` requests:
|
|
90
|
+
- SSH to server and check logs: `tail -f /var/log/plesk/nodejs/yourdomain.com.log`
|
|
91
|
+
- Ensure `.next` directory exists: `ls -la web/.next/`
|
|
92
|
+
- Verify Node.js is running: `ps aux | grep node`
|
|
93
|
+
|
|
94
|
+
### 9. Set Up Auto-Restart (Optional)
|
|
95
|
+
|
|
96
|
+
In Plesk, the Node.js app should auto-restart on failure. To verify:
|
|
97
|
+
1. Go to **Node.js Applications**
|
|
98
|
+
2. Check **Restart policy** is set to auto-restart
|
|
99
|
+
|
|
100
|
+
### 10. Enable HTTPS (Recommended)
|
|
101
|
+
|
|
102
|
+
1. Go to **Domains** → Your domain → **SSL/TLS Certificates**
|
|
103
|
+
2. Click **Install** (use Let's Encrypt free certificate)
|
|
104
|
+
3. Plesk auto-redirects HTTP → HTTPS
|
|
105
|
+
|
|
106
|
+
## Troubleshooting
|
|
107
|
+
|
|
108
|
+
### `_next/static` returns 500
|
|
109
|
+
|
|
110
|
+
**Cause**: Next.js build output not deployed or server crashed.
|
|
111
|
+
|
|
112
|
+
**Fix**:
|
|
113
|
+
```bash
|
|
114
|
+
# SSH to server
|
|
115
|
+
npm run build --prefix web
|
|
116
|
+
npm start
|
|
117
|
+
# Check logs
|
|
118
|
+
tail -f /var/log/plesk/nodejs/yourdomain.com.log
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Application won't start
|
|
122
|
+
|
|
123
|
+
**Check**:
|
|
124
|
+
1. Node.js version: `node --version` (must be 18+)
|
|
125
|
+
2. Dependencies: `npm install`
|
|
126
|
+
3. Build output: `ls -la dist/` and `ls -la web/.next/`
|
|
127
|
+
4. Logs: Check Plesk control panel logs
|
|
128
|
+
|
|
129
|
+
### Port conflicts
|
|
130
|
+
|
|
131
|
+
Plesk assigns ports automatically. If you get a port conflict:
|
|
132
|
+
1. Go to **Node.js Applications** → Edit
|
|
133
|
+
2. Let Plesk auto-assign a new port
|
|
134
|
+
3. Restart the app
|
|
135
|
+
|
|
136
|
+
## Updating the Application
|
|
137
|
+
|
|
138
|
+
To deploy a new version:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
cd /var/www/vhosts/yourdomain.com/dev-workflow-mcp-server
|
|
142
|
+
git pull origin main
|
|
143
|
+
npm install
|
|
144
|
+
npm run build
|
|
145
|
+
# Plesk will auto-restart the app
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Or manually restart in Plesk control panel:
|
|
149
|
+
1. **Node.js Applications** → Select app → **Restart**
|
|
150
|
+
|
|
151
|
+
## Production Checklist
|
|
152
|
+
|
|
153
|
+
- [ ] Node.js 18+ installed
|
|
154
|
+
- [ ] `npm install` completed
|
|
155
|
+
- [ ] `npm run build` succeeded (no errors)
|
|
156
|
+
- [ ] `.next` directory exists with static files
|
|
157
|
+
- [ ] HTTPS/SSL certificate installed
|
|
158
|
+
- [ ] Reverse proxy configured
|
|
159
|
+
- [ ] Application started and running
|
|
160
|
+
- [ ] `https://yourdomain.com` loads without 500 errors
|
|
161
|
+
- [ ] `_next/static` assets load correctly
|
|
162
|
+
- [ ] Logs show no errors
|
|
163
|
+
|
|
164
|
+
## Support
|
|
165
|
+
|
|
166
|
+
For issues:
|
|
167
|
+
1. Check Plesk logs: `/var/log/plesk/nodejs/`
|
|
168
|
+
2. SSH and run `npm start` manually to see real-time errors
|
|
169
|
+
3. Verify Node.js and npm versions
|
|
170
|
+
4. Ensure all dependencies installed: `npm install`
|
|
@@ -42,3 +42,17 @@ check_ready → commit → release → complete // CORRECT!
|
|
|
42
42
|
## Solution
|
|
43
43
|
|
|
44
44
|
Always call `perform_release` BEFORE `complete_task`. Never use `--force` unless absolutely necessary.
|
|
45
|
+
|
|
46
|
+
## Documentation Phase Expectations
|
|
47
|
+
|
|
48
|
+
During the documentation step (`mcp0_create_documentation`), make sure the core project docs are created or updated as needed:
|
|
49
|
+
|
|
50
|
+
1. `docs/product/PRD.md` – Product Requirements Document
|
|
51
|
+
2. `README.md` – Project overview and usage
|
|
52
|
+
3. `docs/release-notes/RELEASE_NOTES.md` – Release notes for changes in this task/version
|
|
53
|
+
|
|
54
|
+
If one or more of these files already exist, **update them** instead of creating new variants. Use the `documentationType` argument to reflect what you touched:
|
|
55
|
+
|
|
56
|
+
- `"PRD"` when you added/updated the PRD
|
|
57
|
+
- `"README"` when you updated the main README
|
|
58
|
+
- `"RELEASE_NOTES"` when you updated the release notes
|
|
@@ -4,6 +4,32 @@ Authoritative history of user-visible changes for the Development Workflow MCP S
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.4.3 — 2025-11-27 — 🧹 Chores
|
|
8
|
+
- **release:** 1.4.2 (fac8999)
|
|
9
|
+
- remove invalid turbopack experimental config from next.config.ts (af0a7ea)
|
|
10
|
+
- add Plesk deployment guide (de35675)
|
|
11
|
+
- update program tracks and fix fast refresh warning (aa5bc9c)
|
|
12
|
+
|
|
13
|
+
## 1.4.2 — 2025-11-27 — 🧹 Chores
|
|
14
|
+
- fix release state detection (ed5dfd1)
|
|
15
|
+
- prepare for release (a6ea2d0)
|
|
16
|
+
- update task list (35663dd)
|
|
17
|
+
- **web:** fix next.js lockfile warning (05ffce0)
|
|
18
|
+
- ensure release guard uses freshest workflow state (e07eb42)
|
|
19
|
+
- **web:** configure next.js root to silence warnings (22ed002)
|
|
20
|
+
- **web:** improve mobile layout for hero section (53b26bf)
|
|
21
|
+
- consolidate workflow state to root .state folder only (3d69a14)
|
|
22
|
+
|
|
23
|
+
## 1.4.1 — 2025-11-27 — 🐛 Bug Fixes
|
|
24
|
+
- update build test to include postbuild (b1e2f48)
|
|
25
|
+
- add custom server.js for Plesk (b3912cd)
|
|
26
|
+
- migrate dashboard to Next.js with TypeScript and Tailwind CSS (bce1fec)
|
|
27
|
+
- fix package.json scripts (fb25e98)
|
|
28
|
+
- fix tsconfig and remove dist artifact (282759f)
|
|
29
|
+
|
|
30
|
+
## 1.4.0 — 2025-11-26
|
|
31
|
+
- See CHANGELOG for details.
|
|
32
|
+
|
|
7
33
|
## 1.3.11 — 2025-11-23
|
|
8
34
|
- Re-applied Plesk security fix (moved static files to `web/public/`).
|
|
9
35
|
- Updated build configuration and server paths.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@programinglive/dev-workflow-mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "MCP server to enforce development workflow discipline",
|
|
5
5
|
"homepage": "https://devworkflow.programinglive.com/",
|
|
6
6
|
"type": "module",
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
"dev-workflow-mcp": "index.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "
|
|
13
|
-
"build:
|
|
14
|
-
"
|
|
15
|
-
"
|
|
12
|
+
"build": "npm run build:server && npm run build:web",
|
|
13
|
+
"build:server": "vite build",
|
|
14
|
+
"build:web": "npm run build --prefix web",
|
|
15
|
+
"watch:web": "npm run dev --prefix web",
|
|
16
|
+
"postbuild": "node scripts/build-docs.js",
|
|
16
17
|
"dev": "node --watch index.js",
|
|
17
18
|
"start": "node index.js",
|
|
18
19
|
"local": "node index.js",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"release:major": "node release-wrapper.js major",
|
|
25
26
|
"release:minor": "node release-wrapper.js minor",
|
|
26
27
|
"release:patch": "node release-wrapper.js patch",
|
|
27
|
-
"web": "
|
|
28
|
+
"web": "npm start --prefix web"
|
|
28
29
|
},
|
|
29
30
|
"keywords": [
|
|
30
31
|
"mcp",
|
package/release-wrapper.js
CHANGED
|
@@ -3,9 +3,71 @@
|
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import fs from 'node:fs/promises';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
+
import { resolveStateFile } from './workflow-state.js';
|
|
6
7
|
|
|
7
8
|
const RELEASE_TYPES = new Set(['major', 'minor', 'patch']);
|
|
8
9
|
|
|
10
|
+
async function readStateCandidate(filePath) {
|
|
11
|
+
if (!filePath) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const [raw, stats] = await Promise.all([fs.readFile(filePath, 'utf8'), fs.stat(filePath)]);
|
|
17
|
+
return {
|
|
18
|
+
state: JSON.parse(raw),
|
|
19
|
+
path: filePath,
|
|
20
|
+
mtimeMs: stats.mtimeMs,
|
|
21
|
+
};
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function loadWorkflowStateCandidates(projectRoot) {
|
|
28
|
+
const candidates = [];
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
candidates.push(resolveStateFile());
|
|
32
|
+
} catch {
|
|
33
|
+
// resolver may throw before state exists; fall through to other candidates
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const legacyStatePath = path.join(projectRoot, '.state', 'workflow-state.json');
|
|
37
|
+
candidates.push(legacyStatePath);
|
|
38
|
+
|
|
39
|
+
// Add explicit DEV_WORKFLOW_STATE_FILE if provided (resolver would have used it, but keep explicit just in case)
|
|
40
|
+
if (process.env.DEV_WORKFLOW_STATE_FILE) {
|
|
41
|
+
candidates.push(path.resolve(process.env.DEV_WORKFLOW_STATE_FILE));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const seen = new Set();
|
|
45
|
+
let freshest = null;
|
|
46
|
+
|
|
47
|
+
for (const candidate of candidates) {
|
|
48
|
+
if (!candidate) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const resolved = path.resolve(candidate);
|
|
53
|
+
if (seen.has(resolved)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
seen.add(resolved);
|
|
57
|
+
|
|
58
|
+
const result = await readStateCandidate(resolved);
|
|
59
|
+
if (!result) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!freshest || result.mtimeMs > freshest.mtimeMs) {
|
|
64
|
+
freshest = result;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return freshest;
|
|
69
|
+
}
|
|
70
|
+
|
|
9
71
|
async function main() {
|
|
10
72
|
const releaseTypeArg = (process.argv[2] || '').toLowerCase();
|
|
11
73
|
const forceFlag = process.argv.includes('--force') || process.env.DEV_WORKFLOW_FORCE_RELEASE === '1';
|
|
@@ -26,44 +88,17 @@ async function main() {
|
|
|
26
88
|
}
|
|
27
89
|
const projectRoot = projectRootCandidate;
|
|
28
90
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const baseStateDir = path.join(projectRoot, '.state');
|
|
32
|
-
const legacyStatePath = path.join(baseStateDir, 'workflow-state.json');
|
|
33
|
-
let resolvedUserId = (process.env.DEV_WORKFLOW_USER_ID || '').trim();
|
|
34
|
-
if (!resolvedUserId) {
|
|
35
|
-
try {
|
|
36
|
-
const fileUserId = (await fs.readFile(path.join(baseStateDir, 'user-id'), 'utf8')).trim();
|
|
37
|
-
if (fileUserId) {
|
|
38
|
-
resolvedUserId = fileUserId;
|
|
39
|
-
}
|
|
40
|
-
} catch {
|
|
41
|
-
// no user-id file; legacy layout likely
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const userStatePath = resolvedUserId ? path.join(baseStateDir, 'users', resolvedUserId, 'workflow-state.json') : null;
|
|
45
|
-
|
|
46
|
-
let statePath = legacyStatePath;
|
|
47
|
-
if (userStatePath) {
|
|
48
|
-
try {
|
|
49
|
-
await fs.access(userStatePath);
|
|
50
|
-
statePath = userStatePath;
|
|
51
|
-
} catch {
|
|
52
|
-
// fall back to legacy path
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
let state;
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
const raw = await fs.readFile(statePath, 'utf8');
|
|
59
|
-
state = JSON.parse(raw);
|
|
60
|
-
} catch (error) {
|
|
91
|
+
const result = await loadWorkflowStateCandidates(projectRoot);
|
|
92
|
+
if (!result) {
|
|
61
93
|
console.error(
|
|
62
|
-
`❌ Release guard: cannot locate workflow state
|
|
94
|
+
`❌ Release guard: cannot locate workflow state under ${path.join(projectRoot, '.state')}.
|
|
95
|
+
Make sure the dev-workflow MCP is installed and you have started a task.`
|
|
63
96
|
);
|
|
64
97
|
process.exit(1);
|
|
65
98
|
}
|
|
66
99
|
|
|
100
|
+
const { state, path: statePath } = result;
|
|
101
|
+
|
|
67
102
|
const errors = [];
|
|
68
103
|
if (state.currentPhase !== 'release') {
|
|
69
104
|
errors.push(
|
package/tests/build.test.js
CHANGED
|
@@ -8,7 +8,7 @@ import path from 'path';
|
|
|
8
8
|
const exec = promisify(execCallback);
|
|
9
9
|
|
|
10
10
|
test('build generates dist/index.mjs file', async () => {
|
|
11
|
-
const { stderr } = await exec('npm run build');
|
|
11
|
+
const { stderr } = await exec('npm run build:server && npm run postbuild');
|
|
12
12
|
// Allow the known vite warning about node:process
|
|
13
13
|
const knownWarning = '[plugin vite:resolve] Module "node:process" has been externalized for browser compatibility';
|
|
14
14
|
const tailwindOutput = '≈ tailwindcss';
|
|
@@ -43,6 +43,6 @@ test('build script exists in package.json', async () => {
|
|
|
43
43
|
const content = await readFile(packagePath, 'utf-8');
|
|
44
44
|
const pkg = JSON.parse(content);
|
|
45
45
|
|
|
46
|
-
assert.strictEqual(typeof pkg.scripts
|
|
47
|
-
assert(pkg.scripts
|
|
46
|
+
assert.strictEqual(typeof pkg.scripts['build:server'], 'string');
|
|
47
|
+
assert(pkg.scripts['build:server'].includes('vite build'));
|
|
48
48
|
});
|
package/tests/handlers.test.js
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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"
|