@programinglive/dev-workflow-mcp-server 1.9.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Dev Workflow MCP Server
2
2
 
3
- MCP server yang memaksa kamu mengikuti disiplin development workflow: **test → dokumentasi → commit → release**, tanpa bisa dilewatkan.
3
+ An MCP server that enforces development workflow discipline: **tests → documentation → commit → release**, with no way to skip a step.
4
4
 
5
5
  ```mermaid
6
6
  graph LR
@@ -18,9 +18,9 @@ graph LR
18
18
 
19
19
  ---
20
20
 
21
- ## Quick Start — 3 Menit
21
+ ## Quick Start
22
22
 
23
- ### 1. Clone & Install
23
+ ### 1. Clone and install
24
24
 
25
25
  ```bash
26
26
  git clone https://github.com/programinglive/dev-workflow-mcp-server.git
@@ -28,62 +28,138 @@ cd dev-workflow-mcp-server
28
28
  npm install
29
29
  ```
30
30
 
31
- > **Windows**: `better-sqlite3` butuh native build. Install [Python 3](https://python.org) + [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) dulu sebelum `npm install`.
31
+ `better-sqlite3` ships prebuilt binaries for Node 22 and newer (ABI 127, 137,
32
+ 141, 147). On Node 20 there is no prebuild for the current version, so npm falls
33
+ back to `node-gyp` and you need [Python 3](https://python.org) and
34
+ [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
35
+ on Windows. See [Troubleshooting](#troubleshooting).
32
36
 
33
- ### 2. Test Server Berjalan
37
+ ### 2. Verify the server runs
34
38
 
35
39
  ```bash
36
40
  node index.js call get_workflow_status
37
41
  ```
38
42
 
39
- Output:
43
+ Expected output:
40
44
 
41
45
  ```
42
46
  📊 Current Workflow Status:
47
+
43
48
  Phase: idle
44
49
  Task: (none)
45
- Next step: idle
50
+ Feature flow: ❌
51
+ ...
46
52
  ```
47
53
 
48
- ### 3. Hubungkan ke MCP Client
54
+ ### 3. Connect an MCP client
49
55
 
50
- Lihat bagian [Konfigurasi MCP Client](#-konfigurasi-mcp-client) di bawah.
56
+ See [MCP client configuration](#mcp-client-configuration).
51
57
 
52
58
  ---
53
59
 
54
- ## 🛠️ Available Tools
60
+ ## Available Tools
61
+
62
+ 22 tools.
55
63
 
56
- | Tool | Fungsi |
64
+ | Tool | Purpose |
57
65
  |---|---|
58
- | `start_task` | Mulai task baru (wajib pertama) |
59
- | `create_feature_flow` | Catat alur fitur dengan Mermaid |
60
- | `mark_bug_fixed` | Tandai implementasi selesai |
61
- | `create_tests` | Tandai tests sudah dibuat |
62
- | `skip_tests` | Lewati tests dengan alasan |
63
- | `run_tests` | Catat hasil test (blokir commit jika fail) |
64
- | `create_documentation` | Tandai docs sudah dibuat |
65
- | `check_ready_to_commit` | Verifikasi semua step selesai |
66
- | `commit_and_push` | `git add` → `commit` → `push` otomatis |
67
- | `perform_release` | Catat release version |
68
- | `skip_release` | Lewati release (docs-only task) |
69
- | `complete_task` | Selesai & reset workflow |
70
- | `get_workflow_status` | Cek fase saat ini |
71
- | `view_history` | Lihat riwayat task selesai |
72
- | `run_full_workflow` | Jalankan semua step sekaligus (1 command) |
73
- | `project_summary` | Ringkasan aktivitas project |
74
-
75
- ### Contoh Percakapan
66
+ | `start_task` | Begin a task (always the first step) |
67
+ | `create_feature_flow` | Record the feature flow as Mermaid |
68
+ | `mark_bug_fixed` | Mark the implementation done |
69
+ | `create_tests` | Mark tests as written |
70
+ | `skip_tests` | Skip tests with a justification |
71
+ | `run_tests` | Record test results (blocks commit when failing) |
72
+ | `create_documentation` | Mark docs as written |
73
+ | `check_ready_to_commit` | Verify every required step is complete |
74
+ | `commit_and_push` | `git add` → `commit` → `push` |
75
+ | `perform_release` | Record a release |
76
+ | `skip_release` | Skip the release step with a justification |
77
+ | `complete_task` | Finish and reset the workflow |
78
+ | `get_workflow_status` | Show the current phase |
79
+ | `continue_workflow` | Get guidance on the next step |
80
+ | `view_history` | List completed tasks |
81
+ | `run_full_workflow` | Run every step in one call |
82
+ | `rerun_workflow` | Restart the current task from the beginning |
83
+ | `drop_task` | Abandon the task without completing it |
84
+ | `force_complete_task` | Complete despite missing steps, with a reason |
85
+ | `project_summary` | Aggregate activity for the project |
86
+ | `project_summary_data` | Read the persisted `project-summary.json` |
87
+ | `project_summary_db` | Read the per-user summary from SQLite |
88
+ | `list_factory_tasks` | List your Factory task queue (requires config) |
89
+ | `claim_factory_task` | Claim a Factory task and start a local workflow |
90
+ | `sync_task_status` | Report a status change back to Factory |
91
+
92
+ ### Factory task integration
93
+
94
+ Three tools connect this server to the **Factory** board at
95
+ `factory.programinglive.com`. They read and write the real task table
96
+ (`factory_tasks`), not the retired PocketBase `activity_tasks` collection
97
+ (which still exists but holds 0 records and never reached the board).
98
+
99
+ They stay **inert** until configured. With no configuration the server behaves
100
+ exactly as before, and the tools reply with setup instructions.
101
+
102
+ ```bash
103
+ FACTORY_URL=https://factory.programinglive.com
104
+ FACTORY_EMAIL=<activity_users email>
105
+ FACTORY_PASSWORD=<password>
106
+ ```
107
+
108
+ Or supply a ready token instead of a password:
109
+
110
+ ```bash
111
+ FACTORY_TOKEN=<PocketBase activity_users token>
112
+ ```
113
+
114
+ Optional:
115
+
116
+ ```bash
117
+ FACTORY_PB_URL=https://pocketbase.programinglive.com # where the login happens
118
+ FACTORY_MACHINE_ID=<name shown on the device row> # defaults to the hostname
119
+ FACTORY_DEVICE_ID=<fixed device UUID> # else derived from the name
120
+ FACTORY_AGENT=dev-workflow-mcp # max 40 chars
121
+ ```
122
+
123
+ Use an **`activity_users` account, not a PocketBase superuser**. Factory accepts
124
+ that token as `Authorization: Bearer <token>` for non-browser clients, and the
125
+ account only sees its own tasks.
126
+
127
+ | Tool | Writes? | What it does |
128
+ |---|---|---|
129
+ | `list_factory_tasks` | no | Reads `GET /api/factory`, maps tasks plus their latest work session, and orders them status → priority. Defaults to `running, queued, backlog, review, blocked` |
130
+ | `claim_factory_task` | yes | Opens a work session (`POST /api/work {action:start}`), which is what turns the task `running` on the board, then starts a local workflow |
131
+ | `sync_task_status` | yes | Uses the only endpoint that can produce the status; see the table below |
132
+
133
+ #### Status mapping is not free-form
134
+
135
+ Factory has no generic "set status" endpoint, so the tool routes each status to
136
+ the endpoint that actually supports it:
137
+
138
+ | Requested status | Endpoint used | Result |
139
+ |---|---|---|
140
+ | `review`, `blocked`, `paused` | `POST /api/work {action:finish}` | Session closes, task changes accordingly |
141
+ | `backlog`, `queued`, `cancelled` | `POST /api/factory {action:move_task}` | Board column changes |
142
+ | `running` | — rejected | Point the caller at `claim_factory_task` |
143
+ | `done` | — rejected | A human approves the work in Factory |
144
+
145
+ `review` requires an active work session. Asking for it without one fails with
146
+ "no active work session" instead of silently doing nothing — the task must be
147
+ claimed first. Full behaviour, limits (summary 2000 chars, step 240 chars) and
148
+ troubleshooting live in [docs/factory-integration.md](docs/factory-integration.md).
149
+
150
+
151
+ ### Example session
76
152
 
77
153
  ```
78
154
  "Start a new task: add user authentication, type: feature"
79
- → start_task called, phase moves to coding
155
+ → start_task, phase moves to coding
80
156
 
81
- [kamu ngoding]
157
+ [you write code]
82
158
 
83
159
  "Mark as fixed: login with JWT token"
84
160
  → mark_bug_fixed, phase moves to testing
85
161
 
86
- [tulis test]
162
+ [you write tests]
87
163
 
88
164
  "Create tests done"
89
165
  → create_tests
@@ -95,10 +171,10 @@ Lihat bagian [Konfigurasi MCP Client](#-konfigurasi-mcp-client) di bawah.
95
171
  → create_documentation, phase moves to ready_to_commit
96
172
 
97
173
  "Check if ready to commit"
98
- → check_ready_to_commit → ✅ READY
174
+ → check_ready_to_commit → READY
99
175
 
100
176
  "Commit and push: message='feat(auth): add JWT authentication'"
101
- → commit_and_push (auto git add/commit/push), phase moves to release
177
+ → commit_and_push, phase moves to release
102
178
 
103
179
  "Perform release: command='npm run release:minor'"
104
180
  → perform_release, phase moves to ready_to_complete
@@ -109,27 +185,37 @@ Lihat bagian [Konfigurasi MCP Client](#-konfigurasi-mcp-client) di bawah.
109
185
 
110
186
  ---
111
187
 
112
- ## ⚙️ Konfigurasi MCP Client
188
+ ## MCP client configuration
113
189
 
114
190
  ### OpenCode
115
191
 
116
- Tambahkan ke `~/.config/opencode/opencode.json`:
192
+ OpenCode V2 nests servers under `mcp.servers` and does **not** accept an
193
+ `enabled` key there. Config path is reported by `opencode debug paths`
194
+ (`~/.config/opencode` on every platform, including Windows).
117
195
 
118
196
  ```json
119
197
  {
120
198
  "mcp": {
121
- "dev-workflow": {
122
- "type": "local",
123
- "command": ["node", "C:\\path\\to\\dev-workflow-mcp-server\\index.js"],
124
- "enabled": true
199
+ "servers": {
200
+ "dev-workflow": {
201
+ "type": "local",
202
+ "command": ["node", "C:\\path\\to\\dev-workflow-mcp-server\\index.js"]
203
+ }
125
204
  }
126
205
  }
127
206
  }
128
207
  ```
129
208
 
209
+ The simplest way to write this correctly is to let OpenCode do it:
210
+
211
+ ```bash
212
+ opencode mcp add dev-workflow --global -- node "C:\path\to\dev-workflow-mcp-server\index.js"
213
+ ```
214
+
130
215
  ### Claude Desktop
131
216
 
132
- File: `%APPDATA%\Claude\claude_desktop_config.json` (Windows) atau `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
217
+ `%APPDATA%\Claude\claude_desktop_config.json` (Windows) or
218
+ `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
133
219
 
134
220
  ```json
135
221
  {
@@ -144,7 +230,8 @@ File: `%APPDATA%\Claude\claude_desktop_config.json` (Windows) atau `~/Library/Ap
144
230
 
145
231
  ### Windsurf
146
232
 
147
- File: `%APPDATA%\Windsurf\config.json` (Windows) atau `~/Library/Application Support/Windsurf/config.json` (macOS)
233
+ `%APPDATA%\Windsurf\config.json` (Windows) or
234
+ `~/Library/Application Support/Windsurf/config.json` (macOS):
148
235
 
149
236
  ```json
150
237
  {
@@ -160,7 +247,7 @@ File: `%APPDATA%\Windsurf\config.json` (Windows) atau `~/Library/Application Sup
160
247
 
161
248
  ### Antigravity
162
249
 
163
- File: `%APPDATA%\Antigravity\mcp_config.json`
250
+ `%APPDATA%\Antigravity\mcp_config.json`:
164
251
 
165
252
  ```json
166
253
  {
@@ -173,35 +260,46 @@ File: `%APPDATA%\Antigravity\mcp_config.json`
173
260
  }
174
261
  ```
175
262
 
176
- > **Performance tip**: Gunakan `node index.js` langsung, jangan `npx`, agar startup lebih cepat.
263
+ > **Performance:** run `node index.js` directly rather than through `npx`.
264
+ > Startup is noticeably faster.
177
265
 
178
266
  ---
179
267
 
180
- ## 🔧 Configuration
268
+ ## Configuration
181
269
 
182
270
  ### Database
183
271
 
184
- Default pakai **SQLite** (file-based, zero config). Bisa ganti ke PostgreSQL/MySQL:
272
+ Defaults to **SQLite** (file-based, zero config). PostgreSQL and MySQL are also
273
+ supported:
185
274
 
186
275
  ```bash
187
- # .env atau environment variable
276
+ # .env or environment variable
188
277
  DEV_WORKFLOW_DB_TYPE=postgres
189
278
  DEV_WORKFLOW_DB_URL=postgresql://user:pass@localhost:5432/devworkflow
190
279
  ```
191
280
 
192
- | Var | Default | Deskripsi |
281
+ | Variable | Default | Description |
193
282
  |---|---|---|
194
- | `DEV_WORKFLOW_DB_TYPE` | `sqlite` | `sqlite`, `mysql`, atau `postgres` |
195
- | `DEV_WORKFLOW_DB_URL` | — | Connection string (untuk MySQL/Postgres) |
196
- | `DEV_WORKFLOW_DB_PATH` | `.state/dev-workflow.db` | Path SQLite (opsional) |
197
- | `DEV_WORKFLOW_USER_ID` | auto-generated | ID user untuk isolasi multi-user |
198
- | `DEV_WORKFLOW_STATE_FILE` | auto-resolve | Path override workflow-state.json |
199
-
200
- ### Project-Specific State
201
-
202
- Setiap project punya workflow state sendiri di `.state/users/<user-id>/workflow-state.json`. File ini otomatis di-gitignore.
203
-
204
- Untuk isolasi multi-client (misal Windsurf + Antigravity pakai state terpisah):
283
+ | `DEV_WORKFLOW_DB_TYPE` | `sqlite` | `sqlite`, `mysql`, or `postgres` |
284
+ | `DEV_WORKFLOW_DB_URL` | — | Connection string (MySQL/Postgres) |
285
+ | `DEV_WORKFLOW_DB_PATH` | `.state/dev-workflow.db` | SQLite path (optional) |
286
+ | `DEV_WORKFLOW_USER_ID` | auto-generated | User ID for multi-user isolation |
287
+ | `DEV_WORKFLOW_STATE_FILE` | auto-resolved | Override for `workflow-state.json` |
288
+ | `FACTORY_URL` | - | Factory base URL, e.g. `https://factory.programinglive.com` |
289
+ | `FACTORY_TOKEN` | - | PocketBase `activity_users` token sent as a Bearer header |
290
+ | `FACTORY_EMAIL` | - | `activity_users` email, exchanged for a token on demand |
291
+ | `FACTORY_PASSWORD` | - | Password for that account |
292
+ | `FACTORY_PB_URL` | `https://pocketbase.programinglive.com` | Where the token is obtained |
293
+ | `FACTORY_MACHINE_ID` | hostname | Device name shown on the Factory board |
294
+ | `FACTORY_DEVICE_ID` | derived from the name | Stable device UUID |
295
+
296
+ ### Project-specific state
297
+
298
+ Each project keeps its own state in `.state/users/<user-id>/workflow-state.json`.
299
+ The `.state/` directory is gitignored.
300
+
301
+ For multi-client isolation (for example separate state for Windsurf and
302
+ Antigravity), set a different user ID per client:
205
303
 
206
304
  ```json
207
305
  {
@@ -217,17 +315,18 @@ Untuk isolasi multi-client (misal Windsurf + Antigravity pakai state terpisah):
217
315
 
218
316
  ---
219
317
 
220
- ## 🧰 One-Command Stack Setup (OpenCode V2)
318
+ ## One-command stack setup (OpenCode V2)
221
319
 
222
- `scripts/setup-stack.js` installs the whole AI agent stack: the dev-workflow MCP
223
- server, [obra/superpowers](https://github.com/obra/superpowers) skills, and
320
+ `scripts/setup-stack.js` installs the whole agent stack: this MCP server,
321
+ [obra/superpowers](https://github.com/obra/superpowers) skills, and
224
322
  [RTK](https://github.com/rtk-ai/rtk) token compression.
225
323
 
226
324
  ```bash
227
325
  node scripts/setup-stack.js # any platform
228
326
  ```
229
327
 
230
- Platform wrappers (they only install RTK, run `npm install`, then delegate):
328
+ Platform wrappers install RTK, run `npm install`, then delegate to the same
329
+ script:
231
330
 
232
331
  ```powershell
233
332
  pwsh scripts/bootstrap-windows.ps1
@@ -240,35 +339,68 @@ bash scripts/bootstrap-unix.sh
240
339
  ### What it does
241
340
 
242
341
  1. **Finds the real config directory.** Runs `opencode debug paths` and uses the
243
- reported `config` path. OpenCode V2 resolves this to `~/.config/opencode` on
244
- **every** platform, including Windows - `%APPDATA%\opencode` is not read.
342
+ reported `config` path, falling back to `~/.config/opencode`. OpenCode V2
343
+ uses that path on Windows too — `%APPDATA%\opencode` is not read.
245
344
  2. **Backs up `opencode.json`** to `secrets/opencode-backup-<timestamp>.json`
246
345
  before touching it.
247
- 3. **Registers Superpowers** under the V2 `plugins` key (the V1 `plugin` key is
248
- deprecated and ignored by V2).
249
- 4. **Registers the MCP server** under `mcp.servers` via `opencode mcp add`, which
250
- writes a schema-valid `Mcp.LocalConfigEncoded` entry.
346
+ 3. **Registers Superpowers** under the V2 `plugins` key. The V1 `plugin` key is
347
+ deprecated and ignored by V2.
348
+ 4. **Registers the MCP server** via `opencode mcp add`, which writes a
349
+ schema-valid `mcp.servers` entry.
251
350
  5. **Installs dependencies.** Without `npm install` the server dies at startup
252
351
  with `ERR_MODULE_NOT_FOUND: Cannot find package 'dotenv'`.
253
352
  6. **Smoke tests the server**, then verifies with `opencode mcp list` and
254
- `opencode plugin list`. Exits non-zero when any check fails, so a broken
255
- install can no longer report success.
353
+ `opencode plugin list`. Exits non-zero when a check fails.
256
354
  7. **Creates `AGENTS.md`** in the current project if missing.
257
355
 
258
- ### Tests
356
+ ---
357
+
358
+ ## Tests
259
359
 
260
360
  ```bash
261
361
  npm test # full suite
262
362
  node --test tests/setup-stack.test.js
263
363
  ```
264
364
 
365
+ ```
366
+ ℹ tests 112
367
+ ℹ pass 110
368
+ ℹ fail 0
369
+ ℹ skipped 2
370
+ ```
371
+
372
+ The two skipped tests are the MySQL and PostgreSQL adapters. They run only when a
373
+ database is reachable:
374
+
375
+ ```bash
376
+ TEST_MYSQL_URL=mysql://user:pass@localhost:3306/db npm test
377
+ TEST_POSTGRES_URL=postgres://user:pass@localhost:5432/db npm test
378
+ ```
379
+
380
+ To exercise them against real servers without exposing them publicly:
381
+
382
+ ```bash
383
+ # on the database host, once: creates isolated devworkflow_test databases
384
+ ./scripts/setup-test-dbs.sh
385
+
386
+ # locally: opens an SSH tunnel, runs only the adapter tests, closes the tunnel
387
+ TEST_POSTGRES_URL=... TEST_MYSQL_URL=... ./scripts/test-db-adapters.sh
388
+ ```
389
+
390
+ Both adapters pass against live MySQL and PostgreSQL this way (19/19 tests, none
391
+ skipped). The tests **write real rows**, so `setup-test-dbs.sh` creates separate
392
+ `devworkflow_test` databases and grants the test role access only to those. Never
393
+ point these variables at a production database.
394
+
395
+ Everything else, including the SQLite adapter, always runs.
396
+
265
397
  `tests/test-helpers.js` exports `stripNpmNotices()`, which removes npm's own
266
- `npm warn`/`npm notice` chatter and Rollup's third-party annotation warnings from
267
- captured stderr before the build test asserts on it. Without it, a clean build
268
- could look broken on machines with a user-level `.npmrc` or with dependency
269
- versions that emit annotation warnings.
398
+ `npm warn`/`npm notice` output and Rollup's third-party annotation warnings from
399
+ captured stderr before the build test asserts on it.
400
+
401
+ ---
270
402
 
271
- ### CI
403
+ ## CI
272
404
 
273
405
  `.github/workflows/ci.yml` runs on the **self-hosted runner on MMCH**, not on
274
406
  GitHub-hosted minutes:
@@ -277,151 +409,157 @@ GitHub-hosted minutes:
277
409
  runs-on: [self-hosted, windows, mmch]
278
410
  ```
279
411
 
280
- Two jobs:
281
-
282
412
  | Job | Steps |
283
413
  |---|---|
284
- | `test` | `npm ci` → `npm test` → `build:server` → `npm audit --omit=dev --audit-level=high` → setup-stack suite |
414
+ | `test` | `npm ci` → `npm test` → `build:server` → **verify the bundle starts** → `npm audit --omit=dev --audit-level=high` → setup-stack suite |
285
415
  | `web` | `npm ci` in `web/` → static export build → verify `out/index.html` and CSS size → `npm audit --audit-level=high` |
286
416
 
287
- The `web` job exists because the dashboard is deployed to Netlify from `web/`
288
- and previously had no CI coverage at all. The CSS size check catches a Tailwind
289
- regression that a green build would otherwise hide.
417
+ The bundle verification step exists because a successful build does not mean
418
+ the artefact runs. `dist/index.mjs` is the published package entry, and a
419
+ bundler upgrade once produced a green build whose output crashed on startup.
420
+ `scripts/verify-bundle.mjs` starts the bundle and requires the stdio startup
421
+ banner, so that class of failure fails the pull request instead of the release.
290
422
 
291
- A pull request cannot merge green if either job fails.
423
+ The `web` job exists because the dashboard is deployed to Netlify from `web/`.
424
+ The CSS size check catches a Tailwind regression that a green build would
425
+ otherwise hide.
292
426
 
293
- Runner provisioning and troubleshooting are documented in
294
- [docs/homelab/ci-runner.md](./docs/homelab/ci-runner.md).
427
+ ### Tailwind stays on v3
295
428
 
296
- ### Dependency hygiene
429
+ `web/` uses Tailwind 3.4 and is **not** being migrated to v4. Tailwind 4 is a
430
+ rewrite of the CSS pipeline: the `@tailwind` directives become
431
+ `@import "tailwindcss"`, the config moves into CSS, and the PostCSS plugin is
432
+ replaced by `@tailwindcss/postcss`. The dashboard is finished and stable, so
433
+ rewriting its styling pipeline risks the entire visual design for no functional
434
+ gain.
297
435
 
298
- ```bash
299
- npm audit # full tree (production + dev)
300
- npm audit --omit=dev # production only
301
- ```
436
+ `dependabot.yml` ignores `tailwindcss`, `@tailwindcss/postcss` and
437
+ `@tailwindcss/cli` entirely — not just majors — so no v4 pull request
438
+ reappears.
302
439
 
303
- Both report `0 vulnerabilities`. `tar` is pinned via `overrides` in
304
- `package.json`; bump that pin when a new advisory lands rather than relying on
305
- the transitive range.
306
-
307
- The root `tailwindcss` devDependency was removed: it was added when the web
308
- dashboard still shipped a static HTML page, but that build step no longer
309
- exists. The dashboard under `web/` has its own Tailwind setup
310
- (`web/tailwind.config.ts`). The root `tailwind.config.js` pointed `content` at
311
- `web/public/**/*.{html,js}`, a directory that holds only SVG icons, so it
312
- generated nothing and was referenced by no script.
440
+ Runner provisioning and troubleshooting: [docs/homelab/ci-runner.md](./docs/homelab/ci-runner.md).
313
441
 
314
442
  ---
315
443
 
316
- ## Release Workflow
444
+ ## Release workflow
317
445
 
318
- `.github/workflows/github-release.yml` runs on a `v*` tag and is split in two:
446
+ `.github/workflows/github-release.yml` runs on a `v*` tag, split in two:
319
447
 
320
- | Job | Runner | What it does |
448
+ | Job | Runner | Work |
321
449
  |---|---|---|
322
- | `build` | self-hosted MMCH | `npm ci` -> `npm test` -> `build:server` -> verify the built bundle starts -> `npm pack` -> upload tarball + metadata |
323
- | `publish` | `ubuntu-latest` | download tarball -> `npm publish --provenance` -> create/update the GitHub release |
324
-
325
- **Why publish is not on MMCH:** npm provenance requires a supported cloud CI/CD
326
- provider with a **cloud-hosted** runner
327
- ([docs](https://docs.npmjs.com/generating-provenance-statements)). A self-hosted
328
- runner cannot produce an attestation, so `--provenance` would have to be dropped
329
- and consumers would lose the ability to verify which commit the package was
330
- built from.
450
+ | `build` | self-hosted MMCH | `npm ci` → `npm test` → `build:server` → verify the bundle starts → `npm pack` → upload tarball |
451
+ | `publish` | `ubuntu-latest` | download tarball → `npm publish` → create/update the GitHub release |
331
452
 
332
- The split keeps the expensive part - install, test, build, pack - on our own
333
- hardware, and spends hosted minutes only on a single publish step that runs when
334
- a release tag is pushed. Pull requests never touch the hosted runner.
453
+ Publishing uses **Trusted Publishing (OIDC)**: no long-lived npm token is stored
454
+ anywhere, and `id-token: write` plus `registry-url` on `setup-node` is the whole
455
+ configuration. The trusted publisher is registered with `npm trust`:
335
456
 
336
- Publishing authenticates through **npm Trusted Publishing (OIDC)** - no
337
- `NPM_TOKEN` secret is required, and `id-token: write` plus `registry-url` on
338
- `setup-node` is the whole configuration.
457
+ ```bash
458
+ npm trust github @programinglive/dev-workflow-mcp-server \
459
+ --file .github/workflows/github-release.yml \
460
+ --repo programinglive/dev-workflow-mcp-server \
461
+ --allow-publish -y
462
+ ```
339
463
 
340
- ### What goes into the package
464
+ The `file` must match the workflow filename exactly, or OIDC is rejected.
341
465
 
342
- `.npmignore` keeps the published tarball to the runtime server: roughly 60 files
343
- and 65 kB. It excludes `.env*` (only `.env.example` ships), `.state/`, tests,
344
- CI config, `web/`, and docs. Without it npm falls back to `.gitignore`, which
345
- still allows tracked files such as `.env.production` into the tarball.
466
+ ### No provenance
346
467
 
347
- `scripts/install-husky.js` runs from `prepare`. It installs git hooks only when
348
- a `.git` directory is present, so installing the package from the registry as a
349
- dependency does not fail on husky. The `husky || true` idiom is not portable to
350
- Windows, where npm runs scripts through `cmd.exe`.
468
+ `--provenance` is intentionally **not** used. npm rejects provenance bundles
469
+ whose source repository is private:
351
470
 
352
- ---
471
+ ```
472
+ 422 Unprocessable Entity - Unsupported GitHub Actions source repository
473
+ visibility: "private". Only public source repositories are supported when
474
+ publishing with provenance.
475
+ ```
353
476
 
354
- ## 🏠 Homelab Development Guide
477
+ This repository is private by policy, so provenance is unavailable. Consumers
478
+ cannot cryptographically verify which commit produced a published tarball.
355
479
 
356
- Repo ini juga berisi panduan konfigurasi homelab internal **programinglive** — Tailscale + SSH antar 3 mesin (MMCH, HELLOWORLD, Mac).
480
+ ### What ships in the package
357
481
 
358
- | Dokumen | Isi |
359
- |---|---|
360
- | [docs/homelab/README.md](./docs/homelab/README.md) | Overview & quick reference |
361
- | [docs/homelab/infra-tailnet-ssh.md](./docs/homelab/infra-tailnet-ssh.md) | Tailnet + SSH setup lengkap |
362
- | [docs/homelab/cli-tools.md](./docs/homelab/cli-tools.md) | CLI tools per machine |
363
- | [docs/homelab/ci-runner.md](./docs/homelab/ci-runner.md) | Self-hosted CI runner di MMCH |
364
- | [docs/homelab/security-rules.md](./docs/homelab/security-rules.md) | Aturan keamanan |
365
- | [.agent/workflows/homelab-setup.md](./.agent/workflows/homelab-setup.md) | Workflow MCP untuk onboarding mesin baru |
482
+ `.npmignore` limits the tarball to the runtime server: about 60 files and 66 kB.
483
+ It excludes `.env*` (only `.env.example` ships), `.state/`, tests, CI config,
484
+ `web/`, and docs.
366
485
 
367
- > ⚠️ Repo ini **private**. Jangan bagikan ke publik.
486
+ `scripts/install-husky.js` runs from `prepare`. It installs git hooks only when a
487
+ `.git` directory is present, so installing the package as a dependency does not
488
+ fail on husky.
368
489
 
369
490
  ---
370
491
 
371
- ## 🚫 What This Server Prevents
492
+ ## What this server prevents
372
493
 
373
- - ❌ Commit tanpa tests
374
- - ❌ Commit dengan tests yang fail
375
- - ❌ Commit tanpa dokumentasi
376
- - ❌ Lupa langkah workflow
377
- - ❌ Release tanpa commit & push
494
+ - Committing without tests
495
+ - Committing with failing tests
496
+ - Committing without documentation
497
+ - Forgetting a workflow step
498
+ - Releasing without committing and pushing
378
499
 
379
500
  ---
380
501
 
381
- ## 💡 Tips
502
+ ## Tips
382
503
 
383
- 1. Selalu mulai dengan `start_task` — ini yang set intention kamu
384
- 2. Jangan skip tests kecuali darurat — pakai `skip_tests` dengan alasan jelas
385
- 3. Pakai `get_workflow_status` kapanpun untuk cek progress
386
- 4. `run_full_workflow` = shortcut untuk task sederhana yang semua datanya sudah siap
387
- 5. Untuk docs-only task, gunakan `skip_release` daripada memaksakan release
504
+ 1. Always start with `start_task` — it sets the intent for the session
505
+ 2. Do not skip tests unless it is genuinely impossible — use `skip_tests` with a clear reason
506
+ 3. Call `get_workflow_status` whenever you lose track of the phase
507
+ 4. `run_full_workflow` is a shortcut for simple tasks where all the data is already known
508
+ 5. For docs-only work, use `skip_release` rather than forcing a release
388
509
 
389
510
  ---
390
511
 
391
- ## 🧪 Run Tests
512
+ ## Troubleshooting
392
513
 
393
- ```bash
394
- npm test
395
- ```
514
+ **`ERR_MODULE_NOT_FOUND: Cannot find package 'dotenv'`** — dependencies are not
515
+ installed. Run `npm install` in the repo.
396
516
 
397
- ```
398
- ℹ tests 112
399
- ℹ pass 110
400
- ℹ fail 0
401
- ℹ skipped 2
402
- ```
517
+ **`gyp ERR! find VS` on Windows** — the native module is compiling from source
518
+ because there is no prebuild for your Node ABI. Either switch to a Node version
519
+ that has one, or install Visual Studio Build Tools.
403
520
 
404
- The two skipped tests are the MySQL and PostgreSQL adapters, which need a real
405
- database connection (`MYSQL_URL` / `PG_URL`). Everything else, including the
406
- SQLite adapter, runs.
521
+ **`EPERM ... better_sqlite3.node`** — a running process holds the file. Stop it,
522
+ then reinstall.
407
523
 
408
- If a Windows install fails on a native module, it is almost always a missing
409
- prebuild for your Node ABI rather than a broken test - see
410
- [docs/homelab/ci-runner.md](./docs/homelab/ci-runner.md#troubleshooting).
524
+ **OpenCode does not load the server** — check the config shape. V2 requires
525
+ `mcp.servers` and rejects `enabled`:
526
+
527
+ ```bash
528
+ opencode mcp list # should show: dev-workflow connected
529
+ ```
411
530
 
412
531
  ---
413
532
 
414
- ## 📦 Build
533
+ ## Build
415
534
 
416
535
  ```bash
417
- npm run build # → dist/index.mjs (optimized bundle)
418
- npm run web # → dashboard di http://localhost:3111
536
+ npm run build # → dist/index.mjs (optimized bundle, used for npm distribution)
537
+ npm run web # → dashboard on http://localhost:3000
419
538
  ```
420
539
 
421
- Build output主要用于 npm distribution. Untuk MCP usage, gunakan source `index.js` langsung (lebih cepat startup).
540
+ For MCP use, point the client at `index.js` directly — startup is faster than the
541
+ bundled `dist/index.mjs`.
542
+
543
+ ---
544
+
545
+ ## Homelab Development Guide
546
+
547
+ This repository also documents the internal **programinglive** homelab: Tailscale
548
+ plus SSH across three machines (MMCH, HELLOWORLD, Mac).
549
+
550
+ | Document | Contents |
551
+ |---|---|
552
+ | [docs/homelab/README.md](./docs/homelab/README.md) | Overview and quick reference |
553
+ | [docs/homelab/infra-tailnet-ssh.md](./docs/homelab/infra-tailnet-ssh.md) | Tailnet and SSH setup |
554
+ | [docs/homelab/cli-tools.md](./docs/homelab/cli-tools.md) | CLI tools per machine |
555
+ | [docs/homelab/ci-runner.md](./docs/homelab/ci-runner.md) | Self-hosted CI runner on MMCH |
556
+ | [docs/homelab/security-rules.md](./docs/homelab/security-rules.md) | Security rules |
557
+ | [.agent/workflows/homelab-setup.md](./.agent/workflows/homelab-setup.md) | MCP workflow for onboarding a new machine |
558
+
559
+ > ⚠️ This repository is **private**. Do not share it publicly.
422
560
 
423
561
  ---
424
562
 
425
- ## 📄 License
563
+ ## License
426
564
 
427
565
  MIT