@polymorphism-tech/morph-spec 7.4.0 → 7.6.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 (66) hide show
  1. package/README.md +2 -2
  2. package/bin/morph-spec.js +18 -0
  3. package/claude-plugin.json +1 -1
  4. package/docs/CHEATSHEET.md +1 -1
  5. package/docs/QUICKSTART.md +1 -1
  6. package/framework/CLAUDE.md +9 -4
  7. package/framework/MORPH.md +4 -4
  8. package/framework/agents.json +1 -1
  9. package/framework/commands/create-umbraco-lp.md +35 -0
  10. package/framework/commands/migrate-lp-to-umbraco.md +33 -0
  11. package/framework/commands/morph-archive.md +17 -27
  12. package/framework/commands/morph-preflight.md +10 -5
  13. package/framework/hooks/claude-code/core/enforce-phase-writes.js +115 -90
  14. package/framework/hooks/claude-code/core/protect-spec-files.js +32 -30
  15. package/framework/hooks/claude-code/core/state-sync.js +16 -48
  16. package/framework/hooks/shared/state-reader.js +74 -8
  17. package/framework/hooks/shared/state-writer.js +124 -0
  18. package/framework/rules/infrastructure-standards.md +4 -4
  19. package/framework/rules/morph-task-tracking.md +69 -49
  20. package/framework/rules/morph-workflow.md +192 -191
  21. package/framework/skills/core/create-umbraco-lp/SKILL.md +272 -0
  22. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +531 -0
  23. package/framework/skills/core/morph-apply/SKILL.md +15 -15
  24. package/framework/skills/core/morph-brainstorming/SKILL.md +5 -5
  25. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  26. package/framework/skills/core/morph-implement/SKILL.md +5 -4
  27. package/framework/skills/core/morph-plan/SKILL.md +6 -6
  28. package/framework/skills/core/morph-proposal/SKILL.md +8 -7
  29. package/framework/skills/core/morph-review/SKILL.md +3 -3
  30. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  31. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  32. package/framework/standards/STANDARDS.json +80 -8
  33. package/framework/standards/ai-agents/durable-workflows-hitl.md +191 -0
  34. package/framework/standards/ai-agents/rag-custom-pgvector.md +246 -243
  35. package/framework/standards/ai-agents/setup.md +3 -0
  36. package/framework/standards/ai-agents/vector-data-extensions.md +170 -0
  37. package/framework/standards/ai-agents/workflows.md +190 -187
  38. package/framework/standards/infrastructure/docker/{easypanel-deploy.md → coolify-deploy.md} +49 -20
  39. package/framework/templates/README.md +7 -7
  40. package/framework/templates/REGISTRY.json +15 -17
  41. package/framework/templates/context/CONTEXT-FEATURE.md +10 -17
  42. package/framework/templates/context/CONTEXT.md +181 -180
  43. package/framework/templates/docs/onboarding.md +122 -118
  44. package/framework/templates/docs/proposal.md +12 -2
  45. package/framework/templates/docs/spec.md +228 -228
  46. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +1 -1
  47. package/framework/templates/infrastructure/docker/coolify.template.json +49 -0
  48. package/framework/templates/infrastructure/github/README.md +6 -6
  49. package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +33 -0
  50. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -80
  51. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -89
  52. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +2 -1
  53. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +44 -43
  54. package/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -107
  55. package/package.json +1 -1
  56. package/src/commands/project/update.js +415 -368
  57. package/src/commands/project/worktree.js +212 -210
  58. package/src/commands/state/advance.js +82 -0
  59. package/src/commands/state/archive.js +111 -0
  60. package/src/commands/validation/validate-feature.js +229 -105
  61. package/src/core/state/state-manager.js +238 -66
  62. package/src/dashboard/scanner/state-scanner.js +35 -8
  63. package/src/lib/generators/context-generator.js +12 -8
  64. package/src/utils/file-copier.js +7 -0
  65. package/framework/templates/infrastructure/docker/easypanel.template.json +0 -46
  66. package/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
@@ -1,23 +1,39 @@
1
- # EasyPanel Deployment Standard
1
+ # Coolify Deployment Standard
2
2
 
3
3
  > **Scope:** nextjs-neon
4
4
  > **Layer:** 2 (on keyword)
5
- > **Keywords:** easypanel, docker, deploy, deployment, container
6
- > **Load When:** easypanel or docker deployment keywords detected
5
+ > **Keywords:** coolify, docker, deploy, deployment, container, vps, ssh
6
+ > **Load When:** coolify or docker deployment keywords detected
7
7
 
8
- **Verified against:** .NET 10 + Next.js 15 + Node 22 (Docker base images). Last-verified: 2026-05-20.
8
+ **Verified against:** .NET 10 + Next.js 15 + Node 22 (Docker base images). Last-verified: 2026-07-07.
9
9
 
10
10
  ---
11
11
 
12
12
  Stack: Next.js 15 + Neon PostgreSQL + .NET Backend
13
13
 
14
+ ## What is Coolify and why we use it
15
+
16
+ [Coolify](https://coolify.io) is a self-hosted, open-source PaaS -- an alternative to Heroku/Vercel/Railway that runs on your own VPS. It manages Docker-based deployments end-to-end: builds from a Dockerfile or docker-compose, reverse-proxies traffic (Traefik under the hood), issues and renews Let's Encrypt SSL certificates, and exposes a REST API for automation.
17
+
18
+ Coolify is Polymorphism Tech's standard self-hosted deployment platform for Docker workloads.
19
+
20
+ There is no MCP server or CLI tool for Coolify. All access is via **SSH into the VPS**, from which the Coolify API is reached at `http://localhost:8000/api/v1/` (it is not exposed publicly). The API token lives server-side only (e.g. `~/.coolify-token`, `chmod 600`) -- never print it, never commit it, never let it leave the SSH session.
21
+
22
+ ```bash
23
+ # Canonical access pattern — token is read and used entirely server-side
24
+ ssh <vps-ssh-alias> 'T=$(cat ~/.coolify-token); curl -s -H "Authorization: Bearer $T" http://localhost:8000/api/v1/projects'
25
+ ```
26
+
27
+ Useful endpoints: `/version`, `/projects`, `/servers`, `/applications`, `/deploy?uuid={uuid}`. Changing a domain: `PATCH /applications/{uuid}` with `{"domains":"https://x,https://www.x"}`, then `GET /deploy?uuid={uuid}` to redeploy.
28
+
14
29
  ## Core Rules
15
30
 
16
31
  - ALWAYS use multi-stage Docker builds for minimal image size
17
32
  - ALWAYS configure health checks for zero-downtime deploys
18
- - NEVER hardcode secrets in Dockerfiles -- use EasyPanel environment variables
33
+ - NEVER hardcode secrets in Dockerfiles -- use Coolify environment variables
19
34
  - ALWAYS use `.dockerignore` to exclude node_modules, .git, .env files
20
35
  - SSL is automatic via Let's Encrypt -- no manual certificate management
36
+ - NEVER call the Coolify API directly from your local machine or from CI without going through SSH -- the API port is not publicly reachable and the token must stay server-side
21
37
 
22
38
  ## .NET 10 Dockerfile
23
39
 
@@ -85,7 +101,7 @@ test
85
101
  __tests__
86
102
  ```
87
103
 
88
- ## EasyPanel Service Config
104
+ ## Coolify Service Config
89
105
 
90
106
  | Setting | .NET Backend | Next.js Frontend |
91
107
  |---------|-------------|-----------------|
@@ -97,20 +113,22 @@ __tests__
97
113
 
98
114
  ### GitHub Integration
99
115
 
100
- 1. Generate GitHub PAT with `repo` scope
101
- 2. EasyPanel: Settings > GitHub > Add token
102
- 3. Select repository and branch
103
- 4. Enable "Auto Deploy" for webhook-triggered deploys
116
+ Coolify deploys straight from a GitHub repo (via GitHub App install or a deploy key) and redeploys automatically on push when auto-deploy is enabled for the application.
117
+
118
+ 1. In Coolify, add the GitHub source (GitHub App install or deploy key)
119
+ 2. Create the Application, pointing it at the repo/branch and the Dockerfile path
120
+ 3. Enable "Auto Deploy" for webhook-triggered deploys on push to the tracked branch
121
+ 4. Record the application's `uuid` -- every subsequent API call (`/deploy?uuid=`) targets it
104
122
 
105
123
  ### Domain and SSL
106
124
 
107
- DNS setup (CNAME to EasyPanel server):
125
+ DNS setup (A record to the Coolify server):
108
126
  ```
109
- app.example.com CNAME your-server.easypanel.host
110
- api.example.com CNAME your-server.easypanel.host
127
+ app.example.com A <vps-ip>
128
+ api.example.com A <vps-ip>
111
129
  ```
112
130
 
113
- SSL via Let's Encrypt is automatic. Force HTTPS enabled by default.
131
+ SSL via Let's Encrypt is automatic (Coolify runs Traefik as the reverse proxy). Force HTTPS enabled by default.
114
132
 
115
133
  ## Environment Variables
116
134
 
@@ -147,11 +165,11 @@ export async function GET() {
147
165
 
148
166
  ## Zero-Downtime Deploys
149
167
 
150
- EasyPanel uses Docker HEALTHCHECK to determine container readiness:
168
+ Coolify uses the same Docker HEALTHCHECK contract to determine container readiness:
151
169
 
152
170
  1. New container starts alongside old container
153
171
  2. Health check passes after start-period + retries
154
- 3. Traffic shifts to new container
172
+ 3. Traffic shifts to new container (Traefik)
155
173
  4. Old container stopped
156
174
 
157
175
  | HEALTHCHECK Param | Value | Purpose |
@@ -163,8 +181,8 @@ EasyPanel uses Docker HEALTHCHECK to determine container readiness:
163
181
 
164
182
  ## Monitoring
165
183
 
166
- - **Logs**: Real-time in EasyPanel UI
167
- - **Metrics**: CPU, memory, network via dashboard
184
+ - **Logs**: `docker logs <container>` over SSH, or Coolify's live log viewer in the UI
185
+ - **Metrics**: CPU, memory, network via Coolify's dashboard, or `docker stats` over SSH
168
186
  - **Restart**: Auto-restart on crash (default)
169
187
 
170
188
  Structured logging:
@@ -182,6 +200,17 @@ import pino from "pino";
182
200
  const logger = pino({ level: process.env.LOG_LEVEL ?? "info" });
183
201
  ```
184
202
 
203
+ ## Triggering a Deploy via SSH + API
204
+
205
+ Since there is no MCP server or CLI for Coolify, every deploy operation (manual redeploy, CI/CD, or troubleshooting) goes through the same SSH + curl pattern used for all other Coolify access:
206
+
207
+ ```bash
208
+ # Redeploy an existing application after a new image/commit is ready
209
+ ssh <vps-ssh-alias> 'T=$(cat ~/.coolify-token); curl -s -X GET -H "Authorization: Bearer $T" "http://localhost:8000/api/v1/deploy?uuid=<application-uuid>"'
210
+ ```
211
+
212
+ In GitHub Actions this becomes an SSH step using a deploy key stored as a secret (see the `github-workflow-deploy-coolify` template) -- never a direct HTTP call to the Coolify API from the runner, since the API port is not reachable outside the VPS.
213
+
185
214
  ## Deployment Checklist
186
215
 
187
216
  | Step | Action |
@@ -189,8 +218,8 @@ const logger = pino({ level: process.env.LOG_LEVEL ?? "info" });
189
218
  | 1 | Verify `output: "standalone"` in next.config.ts |
190
219
  | 2 | Test Docker build locally |
191
220
  | 3 | Test health endpoint |
192
- | 4 | Configure env vars in EasyPanel |
221
+ | 4 | Configure env vars in Coolify (UI or API) |
193
222
  | 5 | Set up custom domain + DNS |
194
223
  | 6 | Verify SSL certificate |
195
224
  | 7 | Enable auto-deploy from GitHub |
196
- | 8 | Push to main, verify deployment |
225
+ | 8 | Push to main, verify deployment via SSH (`docker ps` / Coolify logs) |
@@ -54,18 +54,18 @@ framework/templates/
54
54
  │ └── postgresql-rls-policy.sql # Row-level security
55
55
  │
56
56
  ├── infrastructure/
57
- │ ├── docker/ # Docker & EasyPanel
57
+ │ ├── docker/ # Docker & Coolify
58
58
  │ │ ├── dockerfile-api.dockerfile # .NET API
59
59
  │ │ ├── dockerfile-web.dockerfile # Next.js web
60
60
  │ │ ├── Dockerfile.template # Generic
61
61
  │ │ ├── docker-compose.template.yml # Compose
62
- │ │ └── easypanel.template.json # EasyPanel config
62
+ │ │ └── coolify.template.json # Coolify config
63
63
  │ │
64
64
  │ └── github/ # GitHub Actions CI/CD
65
65
  │ ├── workflows/ # Reusable workflow templates
66
66
  │ │ ├── dotnet-build.yml.hbs # .NET restore, build, test
67
67
  │ │ ├── docker-build-push.yml.hbs # Docker build & push
68
- │ │ └── deploy-easypanel.yml.hbs # EasyPanel deployment
68
+ │ │ └── deploy-coolify.yml.hbs # Coolify deployment (via SSH)
69
69
  │ │
70
70
  │ ├── actions/ # Composite action templates
71
71
  │ │ ├── docker-build-push/action.yml.hbs
@@ -313,7 +313,7 @@ infrastructure/github/
313
313
  ├── workflows/ # Reusable workflow templates
314
314
  │ ├── dotnet-build.yml.hbs # .NET restore, build, test
315
315
  │ ├── docker-build-push.yml.hbs # Docker build & push
316
- │ └── deploy-easypanel.yml.hbs # EasyPanel deployment
316
+ │ └── deploy-coolify.yml.hbs # Coolify deployment via SSH
317
317
  │
318
318
  └── actions/ # Composite action templates
319
319
  ├── docker-build-push/action.yml.hbs
@@ -329,8 +329,8 @@ infrastructure/github/
329
329
 
330
330
  ### Deployment Strategy Difference
331
331
 
332
- **NextJS-Neon:** Docker containers to EasyPanel
333
- - `docker build` → `docker push` → EasyPanel webhook
332
+ **NextJS-Neon:** Docker containers to Coolify
333
+ - `docker build` → `docker push` → Coolify deploy triggered via SSH (Coolify's API is not publicly exposed — the runner SSHes into the VPS and calls `localhost:8000/api/v1/deploy` there)
334
334
  - Multi-service deployment (API + Web)
335
335
  - Registry: GitHub Container Registry (ghcr.io)
336
336
 
@@ -368,7 +368,7 @@ infrastructure/github/
368
368
  ```
369
369
 
370
370
  **GitHub Secrets to Configure:**
371
- - NextJS-Neon: `GITHUB_TOKEN` (auto), `EASYPANEL_API_TOKEN`
371
+ - NextJS-Neon: `GITHUB_TOKEN` (auto), `COOLIFY_SSH_HOST`, `COOLIFY_SSH_USER`, `COOLIFY_SSH_KEY`, `COOLIFY_APPLICATION_UUID`
372
372
 
373
373
  ### Stack-Specific Overrides
374
374
 
@@ -127,6 +127,8 @@
127
127
  "APP_INSIGHTS",
128
128
  "AZURE_LOCATION",
129
129
  "CONTAINER_ENV",
130
+ "COOLIFY_APP_URL",
131
+ "COOLIFY_SERVER",
130
132
  "DEVOPS_AREA_PATH",
131
133
  "DEVOPS_BUILD_PIPELINE",
132
134
  "DEVOPS_ORG",
@@ -134,8 +136,6 @@
134
136
  "DEVOPS_RELEASE_PIPELINE",
135
137
  "DEVOPS_WIKI_NAME",
136
138
  "DOTNET_VERSION",
137
- "EASYPANEL_API_URL",
138
- "EASYPANEL_WEB_URL",
139
139
  "EF_VERSION",
140
140
  "INFERRED_STANDARDS",
141
141
  "MORPH_VERSION",
@@ -193,7 +193,6 @@
193
193
  "COMPLEXITY",
194
194
  "CONTRACTS_PATH",
195
195
  "CURRENT_TASK",
196
- "CURRENT_TASK_ID",
197
196
  "DECISIONS_PATH",
198
197
  "DESCRIPTION",
199
198
  "FEATURE_ID",
@@ -213,8 +212,7 @@
213
212
  "TASKS_TOTAL",
214
213
  "TEAM_LEAD",
215
214
  "TIMESTAMP",
216
- "VALIDATION_TIMESTAMP",
217
- "VALIDATOR"
215
+ "VALIDATION_TIMESTAMP"
218
216
  ],
219
217
  "stackSpecific": false,
220
218
  "engine": "handlebars",
@@ -521,7 +519,7 @@
521
519
  "category": "infrastructure",
522
520
  "phase": "implement",
523
521
  "required": false,
524
- "description": ".NET API Dockerfile for EasyPanel/Docker",
522
+ "description": ".NET API Dockerfile for Coolify/Docker",
525
523
  "outputName": "Dockerfile.api",
526
524
  "placeholders": [],
527
525
  "stackSpecific": false,
@@ -542,7 +540,7 @@
542
540
  "category": "infrastructure",
543
541
  "phase": "implement",
544
542
  "required": false,
545
- "description": "Next.js web Dockerfile for EasyPanel/Docker",
543
+ "description": "Next.js web Dockerfile for Coolify/Docker",
546
544
  "outputName": "Dockerfile.web",
547
545
  "placeholders": [],
548
546
  "stackSpecific": false,
@@ -597,16 +595,16 @@
597
595
  "validatePlaceholders": true
598
596
  },
599
597
  {
600
- "id": "easypanel-config",
598
+ "id": "coolify-config",
601
599
  "kind": "template",
602
- "name": "EasyPanel Configuration",
603
- "path": "infrastructure/docker/easypanel.template.json",
600
+ "name": "Coolify Configuration",
601
+ "path": "infrastructure/docker/coolify.template.json",
604
602
  "location": "framework",
605
603
  "category": "infrastructure",
606
604
  "phase": "implement",
607
605
  "required": false,
608
- "description": "EasyPanel deployment configuration",
609
- "outputName": "easypanel.json",
606
+ "description": "Coolify deployment configuration — accessed via SSH + API, no MCP/CLI",
607
+ "outputName": "coolify.json",
610
608
  "placeholders": [
611
609
  "GITHUB_OWNER",
612
610
  "GITHUB_REPO"
@@ -837,17 +835,17 @@
837
835
  "validatePlaceholders": true
838
836
  },
839
837
  {
840
- "id": "github-workflow-deploy-easypanel",
838
+ "id": "github-workflow-deploy-coolify",
841
839
  "kind": "template",
842
- "name": "GitHub Actions - Deploy to EasyPanel",
843
- "path": "infrastructure/github/workflows/deploy-easypanel.yml.hbs",
840
+ "name": "GitHub Actions - Deploy to Coolify",
841
+ "path": "infrastructure/github/workflows/deploy-coolify.yml.hbs",
844
842
  "location": "framework",
845
843
  "category": "infrastructure",
846
844
  "technology": "github-actions",
847
845
  "phase": "deploy",
848
846
  "required": false,
849
- "description": "Reusable workflow for deploying to EasyPanel via webhook",
850
- "outputName": "deploy-easypanel.yml",
847
+ "description": "Reusable workflow for deploying to Coolify via SSH (API is not publicly exposed)",
848
+ "outputName": "deploy-coolify.yml",
851
849
  "placeholders": [],
852
850
  "stackSpecific": false,
853
851
  "applicableStacks": [
@@ -229,21 +229,17 @@ No validation runs yet. Validators run automatically via checkpoints.
229
229
  ## Quick Actions
230
230
 
231
231
  ### Continue Implementation
232
- ```bash
233
- # Start a task (dispatch gate + state tracking)
234
- morph-spec task start {{FEATURE_NAME}} <task-id>
235
-
236
- # Complete current task (runs validators)
237
- morph-spec task done {{FEATURE_NAME}} {{CURRENT_TASK_ID}}
238
-
239
- # Generate recap after task completion
240
- morph-spec generate recap {{FEATURE_NAME}}
241
- ```
232
+ During the implement phase, track your work with the native `TaskCreate`/`TaskUpdate`
233
+ tools. Persist progress by writing `tasks.json` (`2-plan/tasks.json`), touching ONLY
234
+ the mutable fields `status`, `outputs`, and `notes` — via the `Write` tool or an `Edit`
235
+ that touches only those fields. The plan contract (`title`, `description`,
236
+ `dependencies`, `effort`, `doneCriteria`, `group`) is frozen after Gate 2. The recap is
237
+ written by the implement skill; state syncs automatically via the `state-sync` hook.
242
238
 
243
239
  ### Advance Phase
244
240
  ```bash
245
- # Check prerequisites and advance
246
- morph-spec phase advance {{FEATURE_NAME}}
241
+ # Approve the current gate and scaffold the next phase folder in one step
242
+ morph-spec advance {{FEATURE_NAME}}
247
243
 
248
244
  # Validate feature outputs
249
245
  morph-spec validate-feature {{FEATURE_NAME}}
@@ -251,11 +247,8 @@ morph-spec validate-feature {{FEATURE_NAME}}
251
247
 
252
248
  ### Validation
253
249
  ```bash
254
- # Run all validators for active agents
255
- morph-spec validate {{FEATURE_NAME}}
256
-
257
- # Run specific validator
258
- morph-spec validate-{{VALIDATOR}} {{FEATURE_NAME}}
250
+ # Validate this feature's outputs against active standards
251
+ morph-spec validate-feature {{FEATURE_NAME}}
259
252
  ```
260
253
 
261
254
  ---