@polymorphism-tech/morph-spec 7.3.0 → 7.5.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 (61) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +22 -2
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +10 -5
  8. package/framework/MORPH.md +31 -14
  9. package/framework/agents.json +132 -132
  10. package/framework/commands/create-umbraco-lp.md +35 -0
  11. package/framework/commands/migrate-lp-to-umbraco.md +33 -0
  12. package/framework/commands/morph-archive.md +17 -27
  13. package/framework/evals/rubrics/README.md +9 -8
  14. package/framework/hooks/README.md +2 -0
  15. package/framework/hooks/claude-code/core/enforce-phase-writes.js +115 -90
  16. package/framework/hooks/claude-code/core/gate-guard.js +160 -0
  17. package/framework/hooks/claude-code/core/protect-spec-files.js +32 -30
  18. package/framework/hooks/claude-code/core/state-sync.js +16 -36
  19. package/framework/hooks/claude-code/core/validate-completion.js +105 -0
  20. package/framework/hooks/shared/state-reader.js +302 -221
  21. package/framework/hooks/shared/state-writer.js +124 -0
  22. package/framework/rules/morph-task-tracking.md +69 -49
  23. package/framework/rules/morph-workflow.md +192 -191
  24. package/framework/skills/README.md +1 -1
  25. package/framework/skills/core/create-umbraco-lp/SKILL.md +252 -0
  26. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +452 -0
  27. package/framework/skills/core/morph-apply/SKILL.md +69 -27
  28. package/framework/skills/core/morph-brainstorming/SKILL.md +6 -2
  29. package/framework/skills/core/morph-eval/SKILL.md +4 -5
  30. package/framework/skills/core/morph-implement/SKILL.md +51 -22
  31. package/framework/skills/core/morph-plan/SKILL.md +10 -4
  32. package/framework/skills/core/morph-proposal/SKILL.md +8 -7
  33. package/framework/skills/core/morph-review/SKILL.md +15 -8
  34. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  35. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  36. package/framework/standards/ai-agents/setup.md +258 -244
  37. package/framework/templates/REGISTRY.json +1 -3
  38. package/framework/templates/context/CONTEXT-FEATURE.md +10 -17
  39. package/framework/templates/context/CONTEXT.md +181 -180
  40. package/framework/templates/docs/onboarding.md +122 -118
  41. package/framework/templates/docs/proposal.md +10 -0
  42. package/framework/templates/docs/spec.md +228 -228
  43. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -80
  44. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -89
  45. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +2 -1
  46. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +44 -43
  47. package/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -107
  48. package/package.json +1 -1
  49. package/src/commands/project/init.js +517 -515
  50. package/src/commands/project/update.js +415 -368
  51. package/src/commands/project/worktree.js +212 -210
  52. package/src/commands/state/advance.js +82 -0
  53. package/src/commands/state/approve.js +251 -213
  54. package/src/commands/state/archive.js +111 -0
  55. package/src/commands/validation/validate-feature.js +244 -79
  56. package/src/core/state/state-manager.js +256 -74
  57. package/src/dashboard/scanner/state-scanner.js +35 -8
  58. package/src/lib/generators/context-generator.js +12 -8
  59. package/src/lib/risk-detector.js +2 -2
  60. package/src/utils/file-copier.js +7 -0
  61. package/src/utils/hooks-installer.js +527 -516
@@ -0,0 +1,252 @@
1
+ ---
2
+ name: create-umbraco-lp
3
+ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do template MORPH_Umbraco_LP_Template (Umbraco 17 + Next.js): coleta decisões, scaffolda, sobe e valida, customiza branding e módulos, e entrega checklist final.
4
+ version: core
5
+ when-to-invoke: ao iniciar um novo projeto de LP com o template Umbraco genérico
6
+ user-invokable: true
7
+ cliVersion: "7.5.0"
8
+ ---
9
+
10
+ # create-umbraco-lp
11
+
12
+ ## Objetivo
13
+
14
+ Conduzir um agente (ou dev) na criação de uma nova landing page usando o template canônico `MORPH_Umbraco_LP_Template` (repo privado, branch `master`). Cobre do clone ao smoke-test, passando por branding, módulos de conteúdo e configuração de integração de lead.
15
+
16
+ ## Quando invocar
17
+
18
+ Ao iniciar um projeto de LP do zero — quando o usuário disser "criar uma LP", "novo projeto Umbraco", "bootstrapar LP", "nova landing page", ou mencionar `/create-umbraco-lp`. Não invocar se o projeto já existe (repositório com `.env` presente); nesse caso, ir direto ao passo de customização ou ao troubleshoot.
19
+
20
+ ## O que fazer
21
+
22
+ ### Passo 1 — Coletar decisões (uma pergunta por vez via AskUserQuestion)
23
+
24
+ Faça cada pergunta separadamente e aguarde a resposta antes de seguir. Não liste todas de uma vez.
25
+
26
+ **Pergunta 1:** Nome do projeto (ex.: "Reserva das Flores").
27
+
28
+ **Pergunta 2:** Integração de lead. Use `AskUserQuestion` com as opções:
29
+ - `none` — sem integração (form recebe lead mas não envia a lugar nenhum; útil para fase de dev).
30
+ - `ghl` — GoHighLevel (requer API token GHL; configurado depois no backoffice).
31
+ - `prospectpro` — ProspectPRO (requer URL de API + token; configurado depois no backoffice).
32
+ - `webhook` — Webhook genérico (requer URL do webhook; configurado depois no backoffice).
33
+
34
+ **Pergunta 3:** Origins permitidas pelo CORS do backend — o domínio real do frontend em produção, separado por vírgula. Em dev local, `http://localhost:3000` já é o padrão gravado pelo script; pergunte apenas se houver domínio de produção a configurar agora.
35
+
36
+ **Pergunta 4 (opcional):** Seed de demo? Se sim, o boot semeará um Hero e um módulo de Contato de exemplo, facilitando a visualização imediata. Recomendado para projetos novos. Use `AskUserQuestion` com opções Sim / Não.
37
+
38
+ Persista as respostas em variáveis para uso nos passos seguintes.
39
+
40
+ ---
41
+
42
+ ### Passo 2 — Scaffold: clonar template e rodar `new-lp`
43
+
44
+ **2.1 — Clonar o template para o diretório do novo projeto:**
45
+
46
+ O repo do template é **privado** — prefira `gh repo clone` (usa o token já autenticado). Comando idêntico em bash e PowerShell:
47
+
48
+ ```bash
49
+ # Clonar o template canônico (privado) para o diretório do novo projeto.
50
+ # Branch padrão master (já generalizado) — sem checkout de branch.
51
+ gh repo clone polymorphism-tech/MORPH_Umbraco_LP_Template <NomeDoProjeto>
52
+ cd <NomeDoProjeto>
53
+ # (opcional) desacoplar do histórico do template para o projeto ter o seu:
54
+ # rm -rf .git && git init (PowerShell: Remove-Item .git -Recurse -Force; git init)
55
+ ```
56
+
57
+ - **Fallback** se `gh` não estiver disponível: `git clone https://github.com/polymorphism-tech/MORPH_Umbraco_LP_Template.git <NomeDoProjeto>` (ou SSH `git@github.com:polymorphism-tech/MORPH_Umbraco_LP_Template.git`) — exige credencial HTTPS ou chave SSH com acesso à org.
58
+ - Se o clone for por cópia local (sibling repo), substitua por `cp -r` ou `xcopy` preservando o conteúdo de `backend/uSync/` e `scripts/`.
59
+
60
+ **2.2 — Executar o script de bootstrap:**
61
+
62
+ No Windows (PowerShell):
63
+ ```powershell
64
+ .\scripts\new-lp.ps1 -ProjectName "<NomeDoProjeto>" -LeadIntegration "<none|ghl|prospectpro|webhook>" -ResetDb -EnableDemoSeed
65
+ ```
66
+
67
+ `-ResetDb` deve ser passado sempre no primeiro boot de um projeto novo; `-EnableDemoSeed` apenas se demo seed foi escolhido no passo 1.
68
+
69
+ No Linux / macOS (bash):
70
+ ```bash
71
+ ./scripts/new-lp.sh "<NomeDoProjeto>" \
72
+ --lead-integration <none|ghl|prospectpro|webhook> \
73
+ --reset-db \
74
+ --demo-seed # se demo seed foi escolhido
75
+ ```
76
+
77
+ O script escreve `.env` na raiz do repo com os campos:
78
+ ```
79
+ PROJECT_NAME=<NomeDoProjeto>
80
+ UMBRACO_ADMIN_EMAIL=admin@<slug>.com
81
+ UMBRACO_ADMIN_PASSWORD=<gerada>
82
+ UMBRACO_GLOBAL_ID=<uuid-gerado>
83
+ ALLOWED_ORIGINS=http://localhost:3000
84
+ REVALIDATE_SECRET=<gerado>
85
+ LEADS_INTEGRATION=<integração-escolhida>
86
+ ```
87
+
88
+ E gera `backend/appsettings.Development.json` com o bloco Unattended install do Umbraco (usando o email/senha computados pelo script). Isso significa que um projeto recém-scaffoldado **auto-instala no `dotnet run`** — sem necessidade de rodar o instalador UI manualmente.
89
+
90
+ E escreve `frontend/.env.local` com:
91
+ ```
92
+ NEXT_PUBLIC_UMBRACO_URL=https://localhost:44324
93
+ REVALIDATE_SECRET=<mesmo-secret>
94
+ ```
95
+
96
+ > **Nota de overwrite:** se `.env` já existe, `new-lp.ps1` prompta (Read-Host) para sobrescrever — portanto, uma execução não-interativa em um diretório que já tem `.env` vai bloquear na prompt. Execute em um scaffold fresco, ou responda à prompt interativamente.
97
+
98
+ > **Nota importante:** `ALLOWED_ORIGINS` é gravado com `http://localhost:3000` pelo script independentemente do que foi informado no passo 1. Se o usuário especificou um domínio de produção, a forma de aplicá-lo depende do modo de execução:
99
+ > - **Docker Compose:** edite `.env` na raiz: `ALLOWED_ORIGINS=https://meuprojeto.com,http://localhost:3000`. O `docker-compose.yml` injeta essa variável e ela é lida pelo `builder.Configuration` em `Program.cs`.
100
+ > - **`dotnet run` local:** o `.env` **não** é lido automaticamente pelo `dotnet run`. Edite `backend/appsettings.json`, campo `AllowedOrigins` (array de strings), ou exporte a variável no shell antes de rodar (`$env:AllowedOrigins="https://meuprojeto.com,http://localhost:3000"` no PowerShell). O `Program.cs` lê `builder.Configuration.GetSection("AllowedOrigins")`, que é populado via `appsettings.json` ou env var do processo.
101
+
102
+ > `LEADS_INTEGRATION` NÃO está no `.env.example` — é uma variável extra gravada pelo script na seção `LEADS_INTEGRATION=`. O seed a lê via `Environment.GetEnvironmentVariable("LEADS_INTEGRATION")` para criar o node `Configurações de Lead` com o valor correto.
103
+
104
+ Guarde as credenciais exibidas na saída do script (`Admin:`, `Senha:`, `GUID:`).
105
+
106
+ ---
107
+
108
+ ### Passo 3 — Boot + verificar
109
+
110
+ **3.1 — Subir o backend (Umbraco 17 / .NET 10):**
111
+
112
+ ```bash
113
+ cd backend
114
+ dotnet run
115
+ # ou, com IIS Express: perfil "Umbraco.Web.UI"
116
+ ```
117
+
118
+ Portas padrão (dev local):
119
+ - HTTP: `http://localhost:19223`
120
+ - HTTPS: `https://localhost:44324` (IIS Express)
121
+
122
+ O banco de dados é SQLite em `backend/umbraco/Data/Umbraco.sqlite.db`. O flag `-ResetDb` / `--reset-db` apaga `Umbraco.sqlite.db*` e `TEMP/ExamineIndexes` antes do boot — use sempre no primeiro boot de um projeto novo para garantir um estado limpo.
123
+
124
+ > **⚠️ Primeiro `dotnet run` leva vários minutos:** cold compile com NuGet restore + build. Não é um hang — seja paciente.
125
+
126
+ **3.2 — Aguardar o uSync e o seed (após compilar):**
127
+
128
+ Na primeira subida, o Umbraco executa a instalação unattended (via `backend/appsettings.Development.json` configurado pelo script), depois o uSync importa todos os Content Types de `backend/uSync/v17/` (`ImportAtStartup: "All"`), e então o `SeedContentHandler` cria:
129
+ - O node raiz `lpHome` (home da LP, com `PROJECT_NAME` como título).
130
+ - O node `Configurações de Lead` (`leadsConfig`, com `LEADS_INTEGRATION` semeado como `["<integração>"]`).
131
+
132
+ Aguarde as seguintes linhas de log (strings exatas do `SeedContentHandler.cs`) antes de prosseguir:
133
+ - Home: `SeedContent: node created and published successfully.`
134
+ - Leads: `SeedContent: leads config node created and published.`
135
+
136
+ (Se os nodes já existiam de um boot anterior: `SeedContent: home already exists (...), skipping.` e `SeedContent: leads config node already exists, skipping.` — também é OK.)
137
+
138
+ **3.3 — Verificar a Delivery API:**
139
+
140
+ ```bash
141
+ curl "http://localhost:19223/umbraco/delivery/api/v2/content?contentType=lpHome&take=1"
142
+ # Deve retornar { total: 1, items: [...] }
143
+ ```
144
+
145
+ **3.4 — Verificar o endpoint Ping de leads:**
146
+
147
+ ```bash
148
+ curl http://localhost:19223/api/leads
149
+ # Deve retornar { "ok": true, "service": "leads" } (prod)
150
+ # Em Development: inclui "integration", "configFound", "ready"
151
+ ```
152
+
153
+ Se `configFound: false`, o node `leadsConfig` não foi criado pelo seed — verifique os logs e o passo 2.2.
154
+
155
+ **3.5 — Subir o frontend (Next.js):**
156
+
157
+ ```bash
158
+ cd frontend
159
+ npm install
160
+ npm run dev # com TLS
161
+ # ou:
162
+ npm run dev:no-tls # sem TLS (mais simples em dev inicial)
163
+ ```
164
+
165
+ Acesse `http://localhost:3000`. A home deve renderizar com o conteúdo semeado.
166
+
167
+ ---
168
+
169
+ ### Passo 4 — Customizar
170
+
171
+ **4.1 — Branding e cores (frontend):**
172
+
173
+ Edite `frontend/src/app/globals.css`. As variáveis CSS de base do tema são definidas no bloco `:root` e expostas via `@theme inline` para o Tailwind v4:
174
+
175
+ ```css
176
+ /* frontend/src/app/globals.css */
177
+ :root {
178
+ --background: #ffffff; /* troque pela cor de fundo da LP */
179
+ --foreground: #171717; /* troque pela cor de texto principal */
180
+ /* adicione variáveis de cores de marca, tipografia, etc. */
181
+ }
182
+ ```
183
+
184
+ Para tipografias customizadas, importe via `next/font` em `frontend/src/app/layout.tsx` e exponha como variável CSS.
185
+
186
+ **4.2 — Módulos disponíveis (Content Types *Section):**
187
+
188
+ O template já inclui os seguintes módulos versionados em `backend/uSync/v17/ContentTypes/`:
189
+
190
+ | Alias (Content Type) | Propósito |
191
+ |---|---|
192
+ | `heroSection` | Hero principal com título, subtítulo, CTA e imagem |
193
+ | `contatoSection` | Formulário de contato / captação de lead |
194
+ | `diferencialSection` | Lista de diferenciais (cada item: `diferencialItem`) |
195
+ | `galeriaSection` | Galeria de imagens |
196
+ | `videoSection` | Embed de vídeo |
197
+ | `testimonialSection` | Seção de depoimentos (cada item: `testimonialItem`) |
198
+ | `equipeSection` | Seção de equipe (cada membro: `equipeMembro`) |
199
+ | `tipologiasSection` | Tipologias/plantas (cada tipo: `tipologiaTipo`) |
200
+ | `certificacoesSection` | Certificações (cada item: `certificacaoItem`) |
201
+ | `localizacaoSection` | Seção de localização |
202
+ | `customHtmlSection` | HTML livre (escape hatch) |
203
+
204
+ Para adicionar ou reordenar módulos: acesse o backoffice em `https://localhost:44324/umbraco`, faça login com as credenciais geradas, abra o node `lpHome` e adicione os módulos desejados.
205
+
206
+ **4.3 — Configurar integração de lead no backoffice:**
207
+
208
+ Acesse o backoffice → Content → `Configurações de Lead`. Preencha os campos conforme a integração escolhida:
209
+
210
+ - **GHL:** preencha obrigatoriamente `ghlApiToken` (Private Integration Token da sub-conta) **e** `ghlLocationId` (ID da sub-conta/location). Sem `ghlLocationId`, os leads são enviados ao GHL mas vão para a conta errada ou falham silenciosamente. Campos opcionais de mapeamento: `ghlFieldFonte`, `ghlFieldCanal`, `ghlFieldSegmento`, `ghlFieldConsent`, `ghlFieldObs`, `ghlTags`.
211
+ - **ProspectPRO:** `ppApiUrl` + `ppApiToken`.
212
+ - **Webhook genérico:** `whUrl` (URL do webhook; o payload é o lead completo em JSON).
213
+
214
+ > Esses tokens **nunca são semeados pelo script** (por design: "Template genérico — NÃO semear tokens/ids"). O node é criado com campos em branco para o editor preencher. Tokens não aparecem na Delivery API pública (`leadsConfig` está em `DisallowedContentTypeAliases`).
215
+
216
+ > **Dropdown Flexível — gotcha:** o campo `leadIntegration` é um `Umbraco.DropDown.Flexible`. Mesmo com `Multiple: false`, o valor é persistido internamente como JSON array (ex.: `["ghl"]`). O seed já escreve no formato correto via `JsonSerializer.Serialize(new[]{ value })`. Ao ler no controller, `node.Value<string>("leadIntegration")` desembrulha para a string simples.
217
+
218
+ ---
219
+
220
+ ### Passo 5 — Checklist de entrega
221
+
222
+ Antes de fazer deploy ou entregar o projeto ao cliente:
223
+
224
+ - [ ] `dotnet build` sem warnings no backend.
225
+ - [ ] `npm run lint` no frontend sem erros (ESLint via `eslint.config.mjs`).
226
+ - [ ] `npm run build` no frontend (requer backend acessível em `NEXT_PUBLIC_UMBRACO_URL` — ou `E2E_FAKE_DATA=true` para CI sem backend).
227
+ - [ ] `GET /api/leads` retorna `{ ok: true, service: "leads" }`.
228
+ - [ ] Formulário de lead submete e a resposta é `{ ok: true }` (ou `{ ok: true, skipped: true }` se tokens ainda não configurados — comportamento esperado em dev).
229
+ - [ ] Delivery API responde com o node `lpHome` populado: `/umbraco/delivery/api/v2/content?contentType=lpHome&take=1`.
230
+ - [ ] `.env` contém `ALLOWED_ORIGINS` com o domínio de produção correto (separado por vírgula se múltiplos).
231
+ - [ ] `UMBRACO_GLOBAL_ID` é único para este projeto (gerado pelo script — não reutilizar de outro projeto).
232
+ - [ ] SEO: preencher título, descrição e OG image no backoffice (campos do node `lpHome`).
233
+ - [ ] Variáveis sensíveis (`UMBRACO_ADMIN_PASSWORD`, `REVALIDATE_SECRET`, tokens de integração) não estão commitadas no repositório (`.env` deve estar no `.gitignore`).
234
+ - [ ] Em produção com Docker Compose: `docker-compose up --build` e confirmar que backend e frontend sobem com as variáveis do `.env`.
235
+
236
+ > **Nota Docker — `LEADS_INTEGRATION` e `SEED_DEMO_CONTENT`:** o `docker-compose.yml` **não** injeta essas duas variáveis no container do backend. Mesmo que estejam no `.env`, o seed sempre inicializa `leadIntegration` como `"none"` no boot Docker. Isso é esperado: o editor deve configurar a integração manualmente no backoffice após o primeiro boot. Se precisar seeding automático da integração via Docker, adicione a variável na seção `environment` do serviço `backend` em `docker-compose.yml` manualmente.
237
+
238
+ ## Output esperado
239
+
240
+ - Repositório do projeto com `.env` e `frontend/.env.local` configurados.
241
+ - Backend Umbraco subindo com node `lpHome` e node `Configurações de Lead` semeados.
242
+ - Frontend Next.js renderizando a home com conteúdo da Delivery API.
243
+ - `GET /api/leads` respondendo `{ ok: true, service: "leads" }`.
244
+ - Backoffice acessível para o editor adicionar módulos e configurar tokens de integração.
245
+
246
+ ## Referências
247
+
248
+ - `polymorphism-tech/MORPH_Umbraco_LP_Template` (privado, branch `master`) — template canônico: `scripts/new-lp.ps1`, `scripts/new-lp.sh`, `backend/Infrastructure/SeedContentHandler.cs`, `backend/Controllers/LeadController.cs`, `backend/uSync/v17/`.
249
+ - `docs/umbraco-lp-patterns.md` (em `main` neste repo) — padrões e gotchas detalhados: controller público (seção 1), DI multi-sink (seção 2), leitura server-side de config oculta (seção 3), segurança Delivery API (seção 4), uSync config-as-code (seção 5), dropdown gotcha (seção 6), seed idempotente (seção 7), endpoint Ping (seção 10), skip silencioso em dev (seção 11), build Next.js exige backend (seção 12).
250
+ - `backend/appsettings.json` — `Umbraco:CMS:DeliveryApi:DisallowedContentTypeAliases` e `uSync:Settings:ImportAtStartup`.
251
+ - `backend/Properties/launchSettings.json` — portas de dev: HTTP `:19223`, HTTPS `:44324`.
252
+ - `docker-compose.yml` — orquestração de produção (backend porta `5001`, frontend `3000`).