@polymorphism-tech/morph-spec 4.15.0 → 4.17.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 (100) hide show
  1. package/README.md +2 -2
  2. package/bin/morph-spec.js +4 -0
  3. package/bin/task-manager.js +999 -962
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/agents/ai-agents/vector-search-expert.md +247 -233
  8. package/framework/agents/backend/ms-agent-expert.md +2 -1
  9. package/framework/agents/backend/neon-expert.md +397 -0
  10. package/framework/agents/frontend/gsap-animator.md +131 -0
  11. package/framework/agents.json +1175 -1077
  12. package/framework/commands/morph-preflight.md +200 -192
  13. package/framework/hooks/claude-code/session-start/inject-morph-context.js +1 -1
  14. package/framework/rules/gsap-standards.md +13 -0
  15. package/framework/rules/neon-standards.md +25 -0
  16. package/framework/skills/level-0-meta/mcp-registry.json +1 -1
  17. package/framework/skills/level-0-meta/morph-agent-teams/SKILL.md +472 -472
  18. package/framework/skills/level-0-meta/morph-init/SKILL.md +30 -11
  19. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +5 -5
  20. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +5 -5
  21. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +7 -7
  22. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +24 -24
  23. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +12 -12
  24. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +9 -9
  25. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +1 -1
  26. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +1 -1
  27. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +143 -143
  28. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +1 -1
  29. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  30. package/framework/standards/STANDARDS.json +184 -107
  31. package/framework/standards/ai-agents/production.md +1 -0
  32. package/framework/standards/ai-agents/setup.md +3 -2
  33. package/framework/standards/ai-agents/workflows.md +1 -0
  34. package/framework/standards/architecture/vertical-slice/vertical-slice.md +4 -4
  35. package/framework/standards/backend/database/postgresql/database.md +58 -78
  36. package/framework/standards/backend/dotnet/scalar-ui.md +172 -172
  37. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -274
  38. package/framework/standards/backend/integrations/asaas/asaas-api.md +1 -1
  39. package/framework/standards/backend/integrations/clerk/clerk-auth.md +23 -21
  40. package/framework/standards/frontend/design-system/animations.md +9 -0
  41. package/framework/standards/frontend/gsap/gsap-core.md +463 -0
  42. package/framework/standards/frontend/gsap/gsap-plugins.md +294 -0
  43. package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +318 -0
  44. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -0
  45. package/framework/standards/frontend/nextjs/nextjs-patterns.md +47 -37
  46. package/framework/standards/infrastructure/docker/easypanel-deploy.md +4 -8
  47. package/framework/standards/infrastructure/neon/neon-pgrag.md +239 -0
  48. package/framework/standards/infrastructure/neon/neon-pgvector.md +236 -0
  49. package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +310 -0
  50. package/framework/standards/infrastructure/neon/neon-setup.md +186 -0
  51. package/framework/standards/integration/mcp/mcp-tools.md +32 -34
  52. package/framework/templates/README.md +18 -18
  53. package/framework/templates/REGISTRY.json +49 -96
  54. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  55. package/framework/templates/code/dotnet/backend/repository.cs +148 -148
  56. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
  57. package/framework/templates/code/dotnet/database/vector-entity.cs +93 -0
  58. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +1 -1
  59. package/framework/templates/code/sql/{supabase-migration.sql → postgresql-migration.sql} +8 -17
  60. package/framework/templates/code/sql/{supabase-migration.template.sql → postgresql-migration.template.sql} +10 -13
  61. package/framework/templates/code/sql/{rls-policy.sql → postgresql-rls-policy.sql} +8 -8
  62. package/framework/templates/code/typescript/contracts.ts +167 -168
  63. package/framework/templates/context/CONTEXT.md +3 -3
  64. package/framework/templates/docs/proposal.md +6 -6
  65. package/framework/templates/docs/ui-components.md +1 -1
  66. package/framework/templates/feature/decisions.md +121 -121
  67. package/framework/templates/feature/recap.md +145 -145
  68. package/framework/templates/feature/tasks.md +199 -199
  69. package/framework/templates/frontend/nextjs/gsap-scroll-section.tsx.hbs +44 -0
  70. package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -67
  71. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  72. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  73. package/framework/templates/infrastructure/docker/easypanel.template.json +46 -54
  74. package/framework/templates/infrastructure/github/README.md +56 -56
  75. package/framework/templates/integrations/semantic-kernel-neon.cs +125 -0
  76. package/framework/workflows/README.md +1 -1
  77. package/framework/workflows/docs/full-morph.md +69 -69
  78. package/package.json +1 -1
  79. package/src/commands/agents/dispatch-agents.js +19 -15
  80. package/src/commands/project/setup-infra-cmd.js +1 -1
  81. package/src/commands/state/advance-phase.js +5 -0
  82. package/src/commands/tasks/task.js +3 -0
  83. package/src/core/state/state-manager.js +45 -1
  84. package/src/core/templates/template-registry.js +1 -66
  85. package/src/lib/detectors/index.js +2 -2
  86. package/src/lib/generators/architecture-scanner.js +640 -640
  87. package/src/lib/installers/mcp-installer.js +1 -1
  88. package/src/lib/tasks/task-classifier.js +15 -1
  89. package/src/lib/tasks/test-runner.js +5 -1
  90. package/src/lib/validators/content/content-validator.js +9 -10
  91. package/src/lib/validators/validation-runner.js +7 -5
  92. package/src/scripts/setup-infra.js +60 -30
  93. package/framework/agents/backend/supabase-expert.md +0 -256
  94. package/framework/rules/supabase-standards.md +0 -29
  95. package/framework/standards/infrastructure/supabase/mcp-setup.md +0 -142
  96. package/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  97. package/framework/standards/infrastructure/supabase/supabase-custom-jwt.md +0 -206
  98. package/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  99. package/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  100. package/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
@@ -649,7 +649,7 @@ Add stack-specific conditions in config:
649
649
  "blazor-azure": {
650
650
  "minFiles": 5
651
651
  },
652
- "nextjs-supabase": {
652
+ "nextjs-neon": {
653
653
  "minFiles": 3
654
654
  }
655
655
  }
@@ -1,69 +1,69 @@
1
- # Workflow: FULL (Alta Complexidade)
2
-
3
- > **Layer:** 1 | **Load:** on-keyword | **Keywords:** sistema, integração, arquitetura, migração, infraestrutura, plataforma
4
-
5
- ## Critérios
6
-
7
- - > 10 arquivos, > 500 linhas, múltiplos componentes novos
8
- - Infraestrutura, decisões arquiteturais estratégicas, multi-domínio
9
-
10
- ## Fases (TODAS obrigatórias)
11
-
12
- ### FASE 0: PROPOSAL
13
- 1. Analisar solicitação, identificar stack, estimar complexidade
14
- 2. Gerar proposal.md, registrar agentes no state.json
15
- 3. Avaliar complexidade → recomendar workflow full
16
- - **⛔ PAUSA:** Aprovar proposta?
17
-
18
- ### FASE 1: UI/UX (condicional — se keywords UI detectadas)
19
- 1. **Perguntar ao usuário:** layout, referências visuais, fluxo, imagens
20
- 2. Analisar referências fornecidas
21
- 3. Gerar deliverables (design-system, mockups, components, flows)
22
- 4. Validar acessibilidade (WCAG 2.1) e responsividade
23
- - **⛔ PAUSA:** Aprovar UI/UX?
24
-
25
- ### FASE 2: DESIGN (com clarificação integrada)
26
- 1. Scan real do schema (Supabase MCP, EF Core, TypeScript)
27
- 2. Validar schema com usuário (CHECKPOINT 1)
28
- 3. Gerar blueprint arquitetural (CHECKPOINT 2)
29
- 4. Gerar spec.md, contracts.cs/.ts, schema-analysis.md, decisions.md
30
- 5. **Quality + Satisfaction scoring** (0-100):
31
- - Quality: schema fidelity, functional coverage, blueprint, integrations, infra
32
- - Satisfaction: functional completeness, failure coverage, edge cases, clarity, contracts
33
- 6. Loop de refinamento: perguntas → atualizar spec.md direto → re-score
34
- 7. Sai quando score ≥ 85 E usuário aprova
35
- - **⛔ PAUSA:** Aprovar design?
36
-
37
- ### FASE 3: PLAN
38
- 1. Ler spec + contracts + decisions
39
- 2. Analisar codebase existente (Glob + Grep)
40
- 3. Determinar estratégia de execução (single/subagents/agent-teams)
41
- 4. Gerar plan.md com tasks cross-referenciando FRs
42
- - **⛔ PAUSA:** Aprovar plano?
43
-
44
- ### FASE 4: TASKS
45
- 1. Quebrar spec em tasks T001-TXXX com [FR refs]
46
- 2. Definir ordem, checkpoints, dependências
47
- - **⛔ PAUSA:** Aprovar tasks?
48
-
49
- ### FASE 5: IMPLEMENT
50
- 1. Para cada task: ler spec FRs → ler contracts → implementar → verificar
51
- 2. `morph-spec task done {feature} {task-id}` após cada task
52
- 3. Checkpoints automáticos a cada 3 tasks
53
- 4. Gerar recap.md ao final
54
-
55
- ### FASE 6: SYNC
56
- 1. Revisar decisions.md, categorizar
57
- 2. Promover para `.morph/context/{category}.md`
58
- 3. Gerar commit dedicado de sync
59
- - **⛔ PAUSA:** Aprovar promoção de decisões?
60
-
61
- ## Outputs Completos
62
- proposal.md, design-system.md, mockups.md, components.md, flows.md, spec.md, contracts.cs/.ts, schema-analysis.md, decisions.md, plan.md, tasks.md, recap.md
63
-
64
- ## Exemplos
65
- - "Sistema de relatórios com jobs agendados Hangfire"
66
- - "Autenticação completa com Clerk (login, signup, OAuth)"
67
- - "Dashboard com gráficos, tabelas e filtros complexos"
68
- - "RAG pipeline com AI Search e embeddings"
69
- - "Infraestrutura completa com Docker/Easypanel"
1
+ # Workflow: FULL (Alta Complexidade)
2
+
3
+ > **Layer:** 1 | **Load:** on-keyword | **Keywords:** sistema, integração, arquitetura, migração, infraestrutura, plataforma
4
+
5
+ ## Critérios
6
+
7
+ - > 10 arquivos, > 500 linhas, múltiplos componentes novos
8
+ - Infraestrutura, decisões arquiteturais estratégicas, multi-domínio
9
+
10
+ ## Fases (TODAS obrigatórias)
11
+
12
+ ### FASE 0: PROPOSAL
13
+ 1. Analisar solicitação, identificar stack, estimar complexidade
14
+ 2. Gerar proposal.md, registrar agentes no state.json
15
+ 3. Avaliar complexidade → recomendar workflow full
16
+ - **⛔ PAUSA:** Aprovar proposta?
17
+
18
+ ### FASE 1: UI/UX (condicional — se keywords UI detectadas)
19
+ 1. **Perguntar ao usuário:** layout, referências visuais, fluxo, imagens
20
+ 2. Analisar referências fornecidas
21
+ 3. Gerar deliverables (design-system, mockups, components, flows)
22
+ 4. Validar acessibilidade (WCAG 2.1) e responsividade
23
+ - **⛔ PAUSA:** Aprovar UI/UX?
24
+
25
+ ### FASE 2: DESIGN (com clarificação integrada)
26
+ 1. Scan real do schema (Neon/psql, EF Core, TypeScript)
27
+ 2. Validar schema com usuário (CHECKPOINT 1)
28
+ 3. Gerar blueprint arquitetural (CHECKPOINT 2)
29
+ 4. Gerar spec.md, contracts.cs/.ts, schema-analysis.md, decisions.md
30
+ 5. **Quality + Satisfaction scoring** (0-100):
31
+ - Quality: schema fidelity, functional coverage, blueprint, integrations, infra
32
+ - Satisfaction: functional completeness, failure coverage, edge cases, clarity, contracts
33
+ 6. Loop de refinamento: perguntas → atualizar spec.md direto → re-score
34
+ 7. Sai quando score ≥ 85 E usuário aprova
35
+ - **⛔ PAUSA:** Aprovar design?
36
+
37
+ ### FASE 3: PLAN
38
+ 1. Ler spec + contracts + decisions
39
+ 2. Analisar codebase existente (Glob + Grep)
40
+ 3. Determinar estratégia de execução (single/subagents/agent-teams)
41
+ 4. Gerar plan.md com tasks cross-referenciando FRs
42
+ - **⛔ PAUSA:** Aprovar plano?
43
+
44
+ ### FASE 4: TASKS
45
+ 1. Quebrar spec em tasks T001-TXXX com [FR refs]
46
+ 2. Definir ordem, checkpoints, dependências
47
+ - **⛔ PAUSA:** Aprovar tasks?
48
+
49
+ ### FASE 5: IMPLEMENT
50
+ 1. Para cada task: ler spec FRs → ler contracts → implementar → verificar
51
+ 2. `morph-spec task done {feature} {task-id}` após cada task
52
+ 3. Checkpoints automáticos a cada 3 tasks
53
+ 4. Gerar recap.md ao final
54
+
55
+ ### FASE 6: SYNC
56
+ 1. Revisar decisions.md, categorizar
57
+ 2. Promover para `.morph/context/{category}.md`
58
+ 3. Gerar commit dedicado de sync
59
+ - **⛔ PAUSA:** Aprovar promoção de decisões?
60
+
61
+ ## Outputs Completos
62
+ proposal.md, design-system.md, mockups.md, components.md, flows.md, spec.md, contracts.cs/.ts, schema-analysis.md, decisions.md, plan.md, tasks.md, recap.md
63
+
64
+ ## Exemplos
65
+ - "Sistema de relatórios com jobs agendados Hangfire"
66
+ - "Autenticação completa com Clerk (login, signup, OAuth)"
67
+ - "Dashboard com gráficos, tabelas e filtros complexos"
68
+ - "RAG pipeline com AI Search e embeddings"
69
+ - "Infraestrutura completa com Docker/Easypanel"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "4.15.0",
3
+ "version": "4.17.0",
4
4
  "description": "MORPH-SPEC: AI-First development framework with validation pipeline and multi-stack support",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -40,7 +40,7 @@ const AGENTS_JSON_PATH = join(__dirname, '../../../framework/agents.json');
40
40
  const PHASES_JSON_PATH = join(__dirname, '../../../framework/phases.json');
41
41
 
42
42
  /** Phases where agent dispatch is meaningful */
43
- const DISPATCHABLE_PHASES = ['design', 'tasks', 'implement'];
43
+ const DISPATCHABLE_PHASES = ['design', 'plan', 'tasks', 'implement'];
44
44
 
45
45
  // ─────────────────────────────────────────────────────────────────────────────
46
46
  // Required Skills Injection
@@ -238,7 +238,7 @@ export async function buildDispatchConfig(projectPath, featureName, phase, opts
238
238
  // Collect dispatchable agents
239
239
  const isValidateMode = opts.mode === 'validate';
240
240
  const processed = new Set();
241
- const dispatchableAgents = [];
241
+ let dispatchableAgents = [];
242
242
 
243
243
  const candidateIds = [
244
244
  ...activeAgentIds,
@@ -304,6 +304,23 @@ export async function buildDispatchConfig(projectPath, featureName, phase, opts
304
304
  return a.id.localeCompare(b.id);
305
305
  });
306
306
 
307
+ // Pre-flight: check agent files exist, skip missing (BUG-001)
308
+ const warnings = [];
309
+ const verifiedAgents = [];
310
+ for (const agent of dispatchableAgents) {
311
+ const agentFile = join(projectPath, '.claude', 'agents', `${agent.subagentType}.md`);
312
+ if (!existsSync(agentFile)) {
313
+ warnings.push({
314
+ agentId: agent.id,
315
+ subagentType: agent.subagentType,
316
+ message: `File .claude/agents/${agent.subagentType}.md not found — agent skipped from dispatch`,
317
+ });
318
+ } else {
319
+ verifiedAgents.push(agent);
320
+ }
321
+ }
322
+ dispatchableAgents = verifiedAgents;
323
+
307
324
  const shouldDispatch = dispatchableAgents.length >= 2;
308
325
 
309
326
  // ── Recommended agents by group ───────────────────────────────────────────
@@ -320,19 +337,6 @@ export async function buildDispatchConfig(projectPath, featureName, phase, opts
320
337
  tasks = parseAndGroupTasks(tasksPath);
321
338
  }
322
339
 
323
- // ── Pre-flight: check agent files exist ──────────────────────────────────
324
- const warnings = [];
325
- for (const agent of dispatchableAgents) {
326
- const agentFile = join(projectPath, '.claude', 'agents', `${agent.subagentType}.md`);
327
- if (!existsSync(agentFile)) {
328
- warnings.push({
329
- agentId: agent.id,
330
- subagentType: agent.subagentType,
331
- message: `File .claude/agents/${agent.subagentType}.md not found`,
332
- });
333
- }
334
- }
335
-
336
340
  return {
337
341
  feature: featureName,
338
342
  phase,
@@ -4,7 +4,7 @@ import { logger } from '../../utils/logger.js';
4
4
  export async function setupInfraCommand(options) {
5
5
  const targetPath = options.path || process.cwd();
6
6
  try {
7
- await setupInfra(targetPath);
7
+ await setupInfra(targetPath, { reinstall: options.reinstall ?? false });
8
8
  } catch (err) {
9
9
  logger.error(`setup-infra failed: ${err.message}`);
10
10
  process.exit(1);
@@ -128,6 +128,11 @@ function getNextPhase(currentPhase, feature, skipOptional, featureName) {
128
128
 
129
129
  // Skip uiux if no UI design agents are active
130
130
  if (candidate === 'uiux') {
131
+ if (feature.workflow === 'migration' || feature.workflow === 'refactor') {
132
+ console.log(chalk.gray(` ⏩ Skipping ${candidate}: ${feature.workflow} workflow — no visual changes`));
133
+ skippedPhases.push(candidate);
134
+ continue;
135
+ }
131
136
  const hasUiDesignAgent = feature.activeAgents?.some(a => uiDesignAgents.includes(a));
132
137
  if (!hasUiDesignAgent && skipOptional !== false) {
133
138
  console.log(chalk.gray(` ⏩ Skipping ${candidate}: no UI design agents active`));
@@ -42,6 +42,7 @@ export async function taskDoneCommand(featureName, taskIds, options) {
42
42
  try {
43
43
  const args = ['done', featureName, ...taskIds];
44
44
  if (options.skipValidation) args.push('--skip-validation');
45
+ if (options.skipBuild) args.push('--skip-build');
45
46
  if (options.reason) args.push('--reason', options.reason);
46
47
  if (options.note) args.push('--note', options.note);
47
48
  if (options.dryRun) args.push('--dry-run');
@@ -76,6 +77,7 @@ export async function taskBulkDoneCommand(featureName, range, options) {
76
77
  if (options.from) args.push('--from', options.from);
77
78
  if (options.to) args.push('--to', options.to);
78
79
  if (options.skipValidation) args.push('--skip-validation');
80
+ if (options.skipBuild) args.push('--skip-build');
79
81
  if (options.reason) args.push('--reason', options.reason);
80
82
  if (options.note) args.push('--note', options.note);
81
83
  if (options.dryRun) args.push('--dry-run');
@@ -93,6 +95,7 @@ export async function taskAnnotateCommand(featureName, taskId, text, options) {
93
95
  try {
94
96
  const args = ['annotate', featureName, taskId, text];
95
97
  if (options.type) args.push('--type', options.type);
98
+ if (options.markDone) args.push('--mark-done');
96
99
  await executeTaskManager(args);
97
100
  } catch (error) {
98
101
  console.error(chalk.red(`Error: ${error.message}`));
@@ -5,7 +5,7 @@
5
5
  * Used both by CLI commands and internal automation.
6
6
  */
7
7
 
8
- import { readFileSync, writeFileSync, renameSync, unlinkSync, existsSync, mkdirSync } from 'fs';
8
+ import { readFileSync, writeFileSync, renameSync, unlinkSync, existsSync, mkdirSync, rmdirSync, statSync } from 'fs';
9
9
  import { join, dirname } from 'path';
10
10
  import { detectWorkflow } from '../workflows/workflow-detector.js';
11
11
  import { getAllOutputPaths, getOutputPath } from '../paths/output-schema.js';
@@ -163,6 +163,50 @@ export function saveState(state) {
163
163
  }
164
164
  }
165
165
 
166
+ // ============================================================================
167
+ // File Locking (BUG-002)
168
+ // ============================================================================
169
+
170
+ const LOCK_DIR_NAME = '.morph/state.json.lock';
171
+ const LOCK_MAX_RETRIES = 5;
172
+ const LOCK_BASE_MS = 100;
173
+ const LOCK_STALE_MS = 30_000;
174
+
175
+ /**
176
+ * Wrap a read-modify-write cycle on state.json with a mkdir-based mutex.
177
+ * @param {Function} fn - Async function to execute while holding the lock
178
+ * @returns {Promise<*>} Return value of fn
179
+ */
180
+ export async function withStateLock(fn) {
181
+ const lockPath = join(process.cwd(), LOCK_DIR_NAME);
182
+
183
+ for (let attempt = 0; attempt <= LOCK_MAX_RETRIES; attempt++) {
184
+ try {
185
+ mkdirSync(lockPath);
186
+ break;
187
+ } catch (err) {
188
+ if (err.code !== 'EEXIST') throw err;
189
+ try {
190
+ const lockStat = statSync(lockPath);
191
+ if (Date.now() - lockStat.mtimeMs > LOCK_STALE_MS) {
192
+ try { rmdirSync(lockPath); } catch { }
193
+ continue;
194
+ }
195
+ } catch { }
196
+ if (attempt === LOCK_MAX_RETRIES) {
197
+ throw new Error('Could not acquire state lock after retries');
198
+ }
199
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, LOCK_BASE_MS * (2 ** attempt));
200
+ }
201
+ }
202
+
203
+ try {
204
+ return await fn();
205
+ } finally {
206
+ try { rmdirSync(lockPath); } catch { }
207
+ }
208
+ }
209
+
166
210
  /**
167
211
  * Initialize new state file
168
212
  * @param {Object} options - Options
@@ -108,7 +108,7 @@ export function getTemplatesByPhase(phase, projectPath = null) {
108
108
  /**
109
109
  * Get templates by stack.
110
110
  *
111
- * @param {string} stackId - Stack identifier ('blazor-azure', 'nextjs-supabase')
111
+ * @param {string} stackId - Stack identifier ('blazor-azure', 'nextjs-neon')
112
112
  * @param {string} [projectPath] - Optional project path
113
113
  * @returns {Array} Filtered template array (includes universal + stack-specific)
114
114
  */
@@ -226,28 +226,6 @@ export function searchTemplates(keyword, projectPath = null) {
226
226
  });
227
227
  }
228
228
 
229
- /**
230
- * Get registry statistics.
231
- *
232
- * @param {string} [projectPath] - Optional project path
233
- * @returns {Object} Statistics object
234
- */
235
- export function getRegistryStats(projectPath = null) {
236
- const registry = loadTemplateRegistry(projectPath);
237
- return registry.stats || {};
238
- }
239
-
240
- /**
241
- * Validate that a template exists in the registry.
242
- *
243
- * @param {string} templateId - Template identifier
244
- * @param {string} [projectPath] - Optional project path
245
- * @returns {boolean} True if template exists
246
- */
247
- export function templateExists(templateId, projectPath = null) {
248
- return getTemplateById(templateId, projectPath) !== null;
249
- }
250
-
251
229
  /**
252
230
  * Get template absolute path with fallback logic.
253
231
  *
@@ -276,46 +254,3 @@ export function resolveTemplatePathById(templateId, projectPath) {
276
254
  return existsSync(frameworkPath) ? frameworkPath : null;
277
255
  }
278
256
 
279
- /**
280
- * List all template IDs.
281
- *
282
- * @param {string} [projectPath] - Optional project path
283
- * @returns {string[]} Array of template IDs
284
- */
285
- export function listTemplateIds(projectPath = null) {
286
- const templates = getAllTemplates(projectPath);
287
- return templates.map(t => t.id);
288
- }
289
-
290
- /**
291
- * Get templates that use Handlebars engine.
292
- *
293
- * @param {string} [projectPath] - Optional project path
294
- * @returns {Array} Templates using Handlebars
295
- */
296
- export function getHandlebarsTemplates(projectPath = null) {
297
- const templates = getAllTemplates(projectPath);
298
- return templates.filter(t => t.engine === 'handlebars');
299
- }
300
-
301
- /**
302
- * Get templates that use custom engine (need migration).
303
- *
304
- * @param {string} [projectPath] - Optional project path
305
- * @returns {Array} Templates using custom engine
306
- */
307
- export function getCustomEngineTemplates(projectPath = null) {
308
- const templates = getAllTemplates(projectPath);
309
- return templates.filter(t => t.engine === 'custom');
310
- }
311
-
312
- /**
313
- * Get deprecated templates.
314
- *
315
- * @param {string} [projectPath] - Optional project path
316
- * @returns {Array} Deprecated templates
317
- */
318
- export function getDeprecatedTemplates(projectPath = null) {
319
- const templates = getAllTemplates(projectPath);
320
- return templates.filter(t => t.deprecated === true);
321
- }
@@ -71,8 +71,8 @@ export function detectProject(targetPath, opts = {}) {
71
71
  }
72
72
 
73
73
  // Integrations
74
- if (depNames.includes('@supabase/supabase-js') || depNames.includes('@supabase/ssr')) {
75
- structure.integrations.push('supabase');
74
+ if (depNames.includes('@neondatabase/serverless') || depNames.includes('postgres') || depNames.includes('pg')) {
75
+ structure.integrations.push('neon');
76
76
  }
77
77
  if (depNames.includes('@clerk/nextjs') || depNames.includes('@clerk/clerk-sdk-node')) {
78
78
  structure.integrations.push('clerk');