@lifeaitools/rdc-skills 0.19.1 → 0.20.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.19.1",
3
+ "version": "0.20.1",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rdc:deploy
3
- description: "Usage `rdc:deploy <slug> [new|diagnose|audit|promote] [--fix|--hotfix <sha>]` — Deploy an app to Coolify (production) or PM2 (staging), promote a verified dev change to production (one-command cherry-pick → PR → admin-merge → explicit Coolify trigger → verify), add a new Coolify app, diagnose a failed deploy, or audit watch paths. Handles DNS, branch protection, health checks, and post-deploy verification."
3
+ description: "Usage `rdc:deploy <slug> [new|diagnose|audit|promote|convert] [--fix|--hotfix <sha>]` — Deploy an app to Coolify (production) or PM2 (staging), promote a verified dev change to production (one-command cherry-pick → PR → admin-merge → explicit Coolify trigger → verify), convert a prod app's runtime in place static→Next, add a new Coolify app, diagnose a failed deploy, or audit watch paths. Handles DNS, branch protection, health checks, and post-deploy verification."
4
4
  ---
5
5
 
6
6
  > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
@@ -20,6 +20,7 @@ No raw MCP dumps. No UUIDs unless asked.
20
20
  ## When to Use
21
21
  - Project lead says "deploy", "ship it", "push to production", "update the server"
22
22
  - Project lead says "promote", "patch prod", "hotfix production", "push this fix live" — use `rdc:deploy <slug> promote`
23
+ - Dev is a Next.js app but prod is still a static site for the same slug ("dev is XJS, prod is static", "make prod Next") — use `rdc:deploy <slug> convert` (Mode 6)
23
24
  - A new app needs to be registered and deployed for the first time (`rdc:deploy new`)
24
25
  - A deployed app is behaving unexpectedly and needs diagnosis (`rdc:deploy diagnose`)
25
26
  - Running a compliance/health audit of all deployed apps (`rdc:deploy audit`)
@@ -30,6 +31,7 @@ No raw MCP dumps. No UUIDs unless asked.
30
31
  - `rdc:deploy <slug> <build-id>` — deploy specific commit/tag
31
32
  - `rdc:deploy <slug> promote` — promote the verified `develop` change for this app to production (Mode 5)
32
33
  - `rdc:deploy <slug> promote --hotfix <sha>` — promote a specific commit (cherry-pick just that sha to `main`)
34
+ - `rdc:deploy <slug> convert` — convert a prod app's runtime in place from static→Next (Mode 6); use when dev is Next but prod is still a static Coolify build
33
35
  - `rdc:deploy new <slug>` — create a new Coolify app from registry
34
36
  - `rdc:deploy diagnose <slug>` — debug why an app is broken
35
37
  - `rdc:deploy audit` — fleet-wide scan for missed failures
@@ -187,6 +189,56 @@ curl -s -H "Authorization: Bearer $_COOLIFY" \
187
189
  - `develop` was 87 commits ahead of `main` (unrelated apps' WIP). Promoting must be surgical (this app's paths / one sha), never a develop→main merge.
188
190
  - HTTP 200 was returned by the stale origin the whole time — only a content-level assertion (`curl … | grep '<new string>'`) proves the promote landed.
189
191
 
192
+ ### Mode 6 — convert <slug> (prod runtime static→Next, in place)
193
+
194
+ One-time conversion of an existing **production** Coolify app from a static/nixpacks build to the Next.js (dockerfile) runtime, **in place** — same UUID, same fqdn, same DNS. After this, the slug is a normal Next app and every future ship is just `rdc:deploy <slug> promote`. This is the mode for "dev is Next, prod is still static" (the `vlas.earth` / `life.ai` class). `promote` alone CANNOT do this — it re-triggers the prod app's existing (static) build; only `convert` changes the build config.
195
+
196
+ **Authorization:** this changes a production app's runtime — **architectural** per `.claude/rules/production-stack-nextjs.md` + `.claude/rules/architectural-change-approval.md`. Requires explicit user go-ahead for THIS slug. Stop and ask if not given.
197
+
198
+ **Why in-place PATCH, not recreate:** keeps the application UUID, fqdn (apex + `www`), DNS binding, and project — zero DNS cutover, zero window where the domain is unbound. PATCH switches the build pack; the next deploy builds the Next app on the same application object.
199
+
200
+ ```
201
+ rdc:deploy convert: <slug> → <prod-domain> (static→Next, in place)
202
+ [ ] Go-ahead confirmed for THIS slug (production runtime change — architectural)
203
+ [ ] Registry lookup: PROD coolify_uuid, fqdn, project/env, current build_pack
204
+ [ ] Confirm it IS a convert: dev runtime=next AND prod build_pack ∈ {static, nixpacks}. If prod build_pack already `dockerfile` → already converted, fall through to Mode 5 promote.
205
+ [ ] Source Next-prod-readiness preflight (BLOCK on any miss):
206
+ - apps/<name>/Dockerfile present (prod build) — BLOCK "source not Next-prod-ready: add Dockerfile" if missing
207
+ - start/listen port reconciled with intended ports_exposes (no dev-only port like :3214 leaking to prod)
208
+ - PUBLISH.md present, build_type=nextjs, status=active, prod in environments
209
+ [ ] Mandatory pre-convert code-review (pr-review-toolkit:code-reviewer on the apps/<name> diff being promoted). Block on critical/high.
210
+ [ ] Promote app code to main (Mode 5 path): clean worktree off origin/main → checkout apps/<name> paths (or cherry-pick) → confirm diff = expected files only → branch → PR base=main → `gh pr merge --squash --admin --delete-branch`
211
+ [ ] LOCKFILE IMPORTER (mandatory for an app NEW to main): if `git show origin/main:pnpm-lock.yaml | grep -c "apps/<name>:"` is 0, the Docker `pnpm install --frozen-lockfile` WILL fail. In the clean main worktree run `pnpm install --lockfile-only` (adds only the apps/<name> importer; verify the diff is minimal — do NOT promote develop's whole lockfile, it carries unrelated drift) and include `pnpm-lock.yaml` in the SAME promote PR.
212
+ [ ] In-place PATCH prod Coolify app <uuid> to nextjs-app template fields:
213
+ build_pack=dockerfile · dockerfile_location=/apps/<name>/Dockerfile · base_directory=/ ·
214
+ build_command="pnpm turbo run build --filter=<pkg>" · start_command="pnpm --filter=<pkg> start" ·
215
+ install_command="pnpm install --frozen-lockfile" · ports_exposes=<port> ·
216
+ watch_paths="apps/<name>/**\npackages/**"
217
+ (clear publish_directory; static-only field)
218
+ [ ] PROXY LABELS (mandatory — the static-app `custom_labels` are read-only and do NOT auto-update on a build_pack PATCH): fetch `custom_labels`, base64-decode, rewrite `loadbalancer.server.port=80`→`=<port>` (all routers) AND `upstreams 80}}`→`upstreams <port>}}`, and STRIP the static `caddy_*.try_files=…/index.html /index.php` lines (wrong for a Next app), re-base64, PATCH `custom_labels`. Skipping this = container serves on :<port> but the proxy still routes :80 → **502** even though the build "finished" and the app logs "Ready". (Note: the API rejects `is_container_label_readonly_enabled` and a non-base64 `custom_labels` — you must hand-rewrite the base64.)
219
+ [ ] Env vars present in Coolify (compare registry.env_vars_needed); set any missing
220
+ [ ] EXPLICITLY trigger deploy: GET /api/v1/deploy?uuid=<PROD_UUID>&force=true — never rely on the webhook
221
+ [ ] Deployment reached "finished" state (poll coolify_events)
222
+ [ ] Gate: SSR proof — prod HTML now contains `/_next/static` (it is the Next app, not the old static build)
223
+ [ ] Gate: HTTP 200 + content-level assertion of a known string from the Next render
224
+ [ ] Gate: TLS valid; cache headers correct on HTML
225
+ [ ] Gate: metadata audit (see § Metadata Audit) — BLOCK on any required gap
226
+ [ ] Cloudflare cache purged (apex + www)
227
+ [ ] app_deployments updated: runtime intent → next, notes (converted static→Next <date>), last_deploy_at, last_deploy_commit, status=active
228
+ [ ] `apps` row runtime=next confirmed
229
+ ✅ rdc:deploy convert: <slug> now Next.js in prod — SSR verified at <prod-domain>
230
+ ```
231
+
232
+ **Rollback:** PATCH the app back to static (`build_pack=static`, `base_directory=/sites/<name>`, `publish_directory=/sites/<name>`, `ports_exposes=80`, `watch_paths=sites/<name>/**`) and redeploy. `sites/<name>` stays in the repo precisely so this rollback is always available.
233
+
234
+ **PATCH command (in-place build-pack switch):**
235
+ ```bash
236
+ _COOLIFY=$(curl -s http://127.0.0.1:52437/v/coolify-api)
237
+ curl -s -X PATCH -H "Authorization: Bearer $_COOLIFY" -H "Content-Type: application/json" \
238
+ -d '{"build_pack":"dockerfile","dockerfile_location":"/apps/<name>/Dockerfile","base_directory":"/","build_command":"pnpm turbo run build --filter=<pkg>","start_command":"pnpm --filter=<pkg> start","install_command":"pnpm install --frozen-lockfile","ports_exposes":"<port>","watch_paths":"apps/<name>/**\npackages/**"}' \
239
+ "$DEPLOY_API_BASE/api/v1/applications/<PROD_UUID>"
240
+ ```
241
+
190
242
  ## Metadata Audit
191
243
 
192
244
  After a successful deploy or promote, audit the live site's `<head>` metadata. Run this against the deployed URL (not a local file).