@polymorphism-tech/morph-spec 4.7.0 → 4.7.2

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 (232) hide show
  1. package/.morph/.morphversion +5 -0
  2. package/.morph/analytics/threads-log.jsonl +5 -0
  3. package/.morph/config/config.json +8 -0
  4. package/.morph/framework/agents.json +1815 -0
  5. package/.morph/framework/hooks/README.md +205 -0
  6. package/.morph/framework/hooks/claude-code/notification/approval-reminder.js +54 -0
  7. package/.morph/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
  8. package/.morph/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
  9. package/.morph/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
  10. package/.morph/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
  11. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
  12. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
  13. package/.morph/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
  14. package/.morph/framework/hooks/claude-code/statusline.py +538 -0
  15. package/.morph/framework/hooks/claude-code/statusline.sh +7 -0
  16. package/.morph/framework/hooks/claude-code/stop/validate-completion.js +88 -0
  17. package/.morph/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
  18. package/.morph/framework/hooks/git/commit-msg/conventional-commits.sh +33 -0
  19. package/.morph/framework/hooks/git/pre-commit/agents.sh +25 -0
  20. package/.morph/framework/hooks/git/pre-commit/orchestrator.sh +64 -0
  21. package/.morph/framework/hooks/git/pre-commit/specs.sh +50 -0
  22. package/.morph/framework/hooks/git/pre-push/run-tests.sh +44 -0
  23. package/.morph/framework/hooks/shared/hook-response.js +45 -0
  24. package/.morph/framework/hooks/shared/phase-utils.js +129 -0
  25. package/.morph/framework/hooks/shared/state-reader.js +138 -0
  26. package/.morph/framework/hooks/shared/stdin-reader.js +26 -0
  27. package/.morph/framework/standards/STANDARDS.json +933 -0
  28. package/.morph/framework/standards/ai-agents/blazor-ui.md +364 -0
  29. package/.morph/framework/standards/ai-agents/production.md +415 -0
  30. package/.morph/framework/standards/ai-agents/setup.md +418 -0
  31. package/.morph/framework/standards/ai-agents/team-orchestration.md +479 -0
  32. package/.morph/framework/standards/ai-agents/workflows.md +354 -0
  33. package/.morph/framework/standards/architecture/ddd/aggregates.md +120 -0
  34. package/.morph/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
  35. package/.morph/framework/standards/architecture/ddd/complexity-levels.md +108 -0
  36. package/.morph/framework/standards/architecture/ddd/entities.md +99 -0
  37. package/.morph/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
  38. package/.morph/framework/standards/architecture/ddd/value-objects.md +124 -0
  39. package/.morph/framework/standards/backend/api/minimal-api.md +494 -0
  40. package/.morph/framework/standards/backend/api/rest.md +492 -0
  41. package/.morph/framework/standards/backend/api/validation.md +88 -0
  42. package/.morph/framework/standards/backend/authentication/passkeys.md +428 -0
  43. package/.morph/framework/standards/backend/database/ef-core.md +199 -0
  44. package/.morph/framework/standards/backend/database/migrations.md +393 -0
  45. package/.morph/framework/standards/backend/database/postgresql/database.md +352 -0
  46. package/.morph/framework/standards/backend/database/repository-patterns.md +528 -0
  47. package/.morph/framework/standards/backend/database/vector-search-rag.md +541 -0
  48. package/.morph/framework/standards/backend/dotnet/async.md +366 -0
  49. package/.morph/framework/standards/backend/dotnet/core.md +117 -0
  50. package/.morph/framework/standards/backend/dotnet/di.md +439 -0
  51. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +92 -0
  52. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +216 -0
  53. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +290 -0
  54. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +350 -0
  55. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +385 -0
  56. package/.morph/framework/standards/context/analytics.md +96 -0
  57. package/.morph/framework/standards/context/bundles.md +110 -0
  58. package/.morph/framework/standards/context/priming.md +78 -0
  59. package/.morph/framework/standards/core/architecture.md +185 -0
  60. package/.morph/framework/standards/core/coding.md +214 -0
  61. package/.morph/framework/standards/core/git-branching-strategy.md +403 -0
  62. package/.morph/framework/standards/core/git.md +185 -0
  63. package/.morph/framework/standards/core/testing.md +295 -0
  64. package/.morph/framework/standards/data/nosql/blob-storage.md +102 -0
  65. package/.morph/framework/standards/data/nosql/cache/redis.md +97 -0
  66. package/.morph/framework/standards/data/nosql/cosmos-db.md +118 -0
  67. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +121 -0
  68. package/.morph/framework/standards/data/vector-search/rag-chunking.md +104 -0
  69. package/.morph/framework/standards/frontend/blazor/design-checklist.md +222 -0
  70. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +595 -0
  71. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +137 -0
  72. package/.morph/framework/standards/frontend/blazor/html-conversion.md +184 -0
  73. package/.morph/framework/standards/frontend/blazor/lifecycle.md +195 -0
  74. package/.morph/framework/standards/frontend/blazor/pitfalls.md +198 -0
  75. package/.morph/framework/standards/frontend/blazor/state.md +191 -0
  76. package/.morph/framework/standards/frontend/design-system/animations.md +151 -0
  77. package/.morph/framework/standards/frontend/design-system/naming.md +64 -0
  78. package/.morph/framework/standards/frontend/nextjs/app-router.md +123 -0
  79. package/.morph/framework/standards/frontend/nextjs/components.md +132 -0
  80. package/.morph/framework/standards/frontend/nextjs/data-fetching.md +126 -0
  81. package/.morph/framework/standards/frontend/nextjs/forms.md +128 -0
  82. package/.morph/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
  83. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +215 -0
  84. package/.morph/framework/standards/frontend/nextjs/project-structure.md +102 -0
  85. package/.morph/framework/standards/frontend/nextjs/state-management.md +72 -0
  86. package/.morph/framework/standards/frontend/nextjs/testing.md +111 -0
  87. package/.morph/framework/standards/infrastructure/azure/azure.md +624 -0
  88. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +422 -0
  89. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +516 -0
  90. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +520 -0
  91. package/.morph/framework/standards/infrastructure/azure/services/functions.md +486 -0
  92. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +459 -0
  93. package/.morph/framework/standards/infrastructure/azure/services/storage.md +407 -0
  94. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -0
  95. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +252 -0
  96. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +176 -0
  97. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +169 -0
  98. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +184 -0
  99. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +153 -0
  100. package/.morph/framework/standards/integration/api/graphql.md +91 -0
  101. package/.morph/framework/standards/integration/api/grpc.md +114 -0
  102. package/.morph/framework/standards/integration/api/rest-design.md +95 -0
  103. package/.morph/framework/standards/integration/event-driven/cqrs.md +101 -0
  104. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +124 -0
  105. package/.morph/framework/standards/integration/event-driven/service-bus.md +95 -0
  106. package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
  107. package/.morph/framework/standards/observability/logging.md +131 -0
  108. package/.morph/framework/standards/observability/metrics.md +121 -0
  109. package/.morph/framework/standards/observability/monitoring.md +114 -0
  110. package/.morph/framework/standards/observability/tracing.md +132 -0
  111. package/.morph/framework/standards/workflows/parallel-execution.md +112 -0
  112. package/.morph/framework/standards/workflows/thread-management.md +113 -0
  113. package/.morph/framework/templates/.idea/morph-templates.xml +92 -0
  114. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  115. package/.morph/framework/templates/IDE-SNIPPETS.md +266 -0
  116. package/.morph/framework/templates/README.md +814 -0
  117. package/.morph/framework/templates/REGISTRY.json +1888 -0
  118. package/.morph/framework/templates/code/dotnet/backend/repository.cs +141 -0
  119. package/.morph/framework/templates/code/dotnet/backend/service.cs +139 -0
  120. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +74 -0
  121. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +25 -0
  122. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +74 -0
  123. package/.morph/framework/templates/code/dotnet/contracts/README.md +74 -0
  124. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -0
  125. package/.morph/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
  126. package/.morph/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
  127. package/.morph/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
  128. package/.morph/framework/templates/code/dotnet/database/migration.cs +83 -0
  129. package/.morph/framework/templates/code/dotnet/frontend/component.razor +239 -0
  130. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +163 -0
  131. package/.morph/framework/templates/code/dotnet/jobs/job.cs +171 -0
  132. package/.morph/framework/templates/code/dotnet/test.cs +239 -0
  133. package/.morph/framework/templates/code/sql/rls-policy.sql +57 -0
  134. package/.morph/framework/templates/code/sql/supabase-migration.sql +100 -0
  135. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +113 -0
  136. package/.morph/framework/templates/code/typescript/contracts.ts +168 -0
  137. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +276 -0
  138. package/.morph/framework/templates/context/CONTEXT.md +181 -0
  139. package/.morph/framework/templates/docs/clarifications.md +253 -0
  140. package/.morph/framework/templates/docs/onboarding.md +123 -0
  141. package/.morph/framework/templates/docs/proposal.md +182 -0
  142. package/.morph/framework/templates/docs/schema-analysis.md +119 -0
  143. package/.morph/framework/templates/docs/spec.md +198 -0
  144. package/.morph/framework/templates/docs/ui-components.md +124 -0
  145. package/.morph/framework/templates/docs/ui-design-system.md +76 -0
  146. package/.morph/framework/templates/docs/ui-flows.md +167 -0
  147. package/.morph/framework/templates/docs/ui-mockups.md +98 -0
  148. package/.morph/framework/templates/docs/user-stories.md +34 -0
  149. package/.morph/framework/templates/examples/design-system-examples.md +357 -0
  150. package/.morph/framework/templates/examples/spec-examples.md +90 -0
  151. package/.morph/framework/templates/feature/decisions.md +187 -0
  152. package/.morph/framework/templates/feature/recap.md +146 -0
  153. package/.morph/framework/templates/feature/tasks.md +199 -0
  154. package/.morph/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
  155. package/.morph/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
  156. package/.morph/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
  157. package/.morph/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
  158. package/.morph/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
  159. package/.morph/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
  160. package/.morph/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
  161. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +82 -0
  162. package/.morph/framework/templates/infrastructure/azure/README.md +286 -0
  163. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +63 -0
  164. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +164 -0
  165. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +49 -0
  166. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +156 -0
  167. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +426 -0
  168. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +229 -0
  169. package/.morph/framework/templates/infrastructure/azure/deploy.sh +208 -0
  170. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +91 -0
  171. package/.morph/framework/templates/infrastructure/azure/main.bicep +189 -0
  172. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +29 -0
  173. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +29 -0
  174. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +29 -0
  175. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +103 -0
  176. package/.morph/framework/templates/infrastructure/azure/storage.bicep +106 -0
  177. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +58 -0
  178. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -0
  179. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -0
  180. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -0
  181. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +54 -0
  182. package/.morph/framework/templates/infrastructure/github/README.md +593 -0
  183. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +22 -0
  184. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -0
  185. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -0
  186. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +61 -0
  187. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +31 -0
  188. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -0
  189. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -0
  190. package/.morph/framework/templates/integrations/asaas-client.cs +387 -0
  191. package/.morph/framework/templates/integrations/asaas-webhook.cs +351 -0
  192. package/.morph/framework/templates/integrations/azure-identity-config.cs +288 -0
  193. package/.morph/framework/templates/integrations/clerk-config.cs +258 -0
  194. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -0
  195. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -0
  196. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +78 -0
  197. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +97 -0
  198. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +36 -0
  199. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +113 -0
  200. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -0
  201. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -0
  202. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +126 -0
  203. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +43 -0
  204. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -0
  205. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -0
  206. package/.morph/framework/templates/project-structure/dotnet-ddd.md +70 -0
  207. package/.morph/framework/templates/saas/subscription.cs +347 -0
  208. package/.morph/framework/templates/saas/tenant.cs +338 -0
  209. package/.morph/framework/templates/state.template.json +17 -0
  210. package/.morph/framework/templates/ui/FluentDesignTheme.cs +149 -0
  211. package/.morph/framework/templates/ui/MudTheme.cs +281 -0
  212. package/.morph/framework/templates/ui/design-system.css +226 -0
  213. package/.morph/logs/tool-failures.log +17 -0
  214. package/.morph/memory/pre-compact-2026-02-24T17-43-30-049Z.json +16 -0
  215. package/.morph/plans/eager-watching-bunny.md +105 -0
  216. package/.morph/plans/temporal-seeking-nebula.md +45 -0
  217. package/.morph/state.json +48 -0
  218. package/CLAUDE.md +1 -1
  219. package/README.md +119 -99
  220. package/bin/morph-spec.js +0 -9
  221. package/framework/CLAUDE.md +1 -1
  222. package/framework/hooks/README.md +10 -6
  223. package/framework/hooks/claude-code/notification/approval-reminder.js +2 -0
  224. package/framework/hooks/claude-code/post-tool-use/dispatch.js +1 -1
  225. package/framework/hooks/claude-code/stop/validate-completion.js +1 -1
  226. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +1 -1
  227. package/package.json +1 -1
  228. package/src/commands/project/init.js +15 -42
  229. package/src/commands/project/update.js +22 -37
  230. package/src/lib/installers/mcp-installer.js +18 -3
  231. package/src/utils/hooks-installer.js +5 -15
  232. package/src/commands/project/detect.js +0 -114
@@ -0,0 +1,281 @@
1
+ using MudBlazor;
2
+
3
+ namespace {Namespace}.Themes;
4
+
5
+ /// <summary>
6
+ /// MudBlazor Theme customizado para {Project Name}.
7
+ /// Gerado automaticamente baseado em ui-design-system.md
8
+ /// </summary>
9
+ /// <remarks>
10
+ /// Template MORPH-SPEC v2.1.1 by Polymorphism Tech
11
+ /// </remarks>
12
+ public static class AppTheme
13
+ {
14
+ /// <summary>
15
+ /// Tema Light Mode
16
+ /// </summary>
17
+ public static MudTheme LightTheme => new()
18
+ {
19
+ Palette = new PaletteLight
20
+ {
21
+ // Cores Principais
22
+ Primary = "#{hex da cor primária}", // Ex: #3b82f6
23
+ Secondary = "#{hex da cor secundária}", // Ex: #6b7280
24
+ Tertiary = "#{hex da cor terciária}", // Opcional
25
+
26
+ // Cores de Estado
27
+ Success = "#{hex}", // Ex: #10b981
28
+ Error = "#{hex}", // Ex: #ef4444
29
+ Warning = "#{hex}", // Ex: #f59e0b
30
+ Info = "#{hex}", // Ex: #06b6d4
31
+
32
+ // Background e Superfícies
33
+ Background = "#ffffff",
34
+ BackgroundGrey = "#{hex do gray-50}", // Ex: #f9fafb
35
+ Surface = "#ffffff",
36
+
37
+ // Text Colors
38
+ TextPrimary = "#{hex do gray-900}", // Texto principal
39
+ TextSecondary = "#{hex do gray-600}", // Texto secundário
40
+ TextDisabled = "#{hex do gray-400}", // Texto desabilitado
41
+
42
+ // Borders
43
+ Divider = "#{hex do gray-200}", // Divisores
44
+ DividerLight = "#{hex do gray-100}", // Divisores mais claros
45
+ Lines = "#{hex do gray-300}", // Linhas de borda
46
+
47
+ // Action colors (usados em botões, links, etc)
48
+ ActionDefault = "#{hex do gray-500}",
49
+ ActionDisabled = "#{hex do gray-300}",
50
+ ActionDisabledBackground = "#{hex do gray-100}",
51
+
52
+ // Outros
53
+ Dark = "#{hex do gray-800}",
54
+ DarkLighten = "#{hex do gray-700}",
55
+ DarkDarken = "#{hex do gray-900}",
56
+
57
+ // Overlay (usado em modais, dropdowns)
58
+ OverlayLight = "rgba(255, 255, 255, 0.95)",
59
+ OverlayDark = "rgba(33, 33, 33, 0.95)",
60
+
61
+ // Hover effects
62
+ HoverOpacity = 0.06, // Opacidade do hover (6%)
63
+ },
64
+
65
+ Typography = new Typography
66
+ {
67
+ // Font Families
68
+ Default = new Default
69
+ {
70
+ FontFamily = new[] { "{Font Name}", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "sans-serif" },
71
+ FontSize = "1rem", // 16px
72
+ FontWeight = 400, // Regular
73
+ LineHeight = 1.5,
74
+ LetterSpacing = "normal",
75
+ },
76
+
77
+ H1 = new H1
78
+ {
79
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
80
+ FontSize = "2.25rem", // 36px
81
+ FontWeight = 700, // Bold
82
+ LineHeight = 1.2,
83
+ },
84
+
85
+ H2 = new H2
86
+ {
87
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
88
+ FontSize = "1.875rem", // 30px
89
+ FontWeight = 700,
90
+ LineHeight = 1.3,
91
+ },
92
+
93
+ H3 = new H3
94
+ {
95
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
96
+ FontSize = "1.5rem", // 24px
97
+ FontWeight = 600,
98
+ LineHeight = 1.4,
99
+ },
100
+
101
+ H4 = new H4
102
+ {
103
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
104
+ FontSize = "1.25rem", // 20px
105
+ FontWeight = 600,
106
+ LineHeight = 1.4,
107
+ },
108
+
109
+ H5 = new H5
110
+ {
111
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
112
+ FontSize = "1.125rem", // 18px
113
+ FontWeight = 600,
114
+ LineHeight = 1.5,
115
+ },
116
+
117
+ H6 = new H6
118
+ {
119
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
120
+ FontSize = "1rem", // 16px
121
+ FontWeight = 600,
122
+ LineHeight = 1.5,
123
+ },
124
+
125
+ Body1 = new Body1
126
+ {
127
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
128
+ FontSize = "1rem", // 16px
129
+ FontWeight = 400,
130
+ LineHeight = 1.5,
131
+ },
132
+
133
+ Body2 = new Body2
134
+ {
135
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
136
+ FontSize = "0.875rem", // 14px
137
+ FontWeight = 400,
138
+ LineHeight = 1.43,
139
+ },
140
+
141
+ Button = new Button
142
+ {
143
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
144
+ FontSize = "0.875rem", // 14px
145
+ FontWeight = 600, // Semibold
146
+ LineHeight = 1.75,
147
+ TextTransform = "none", // Ou "uppercase" se preferir
148
+ },
149
+
150
+ Caption = new Caption
151
+ {
152
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
153
+ FontSize = "0.75rem", // 12px
154
+ FontWeight = 400,
155
+ LineHeight = 1.66,
156
+ },
157
+
158
+ Subtitle1 = new Subtitle1
159
+ {
160
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
161
+ FontSize = "1rem",
162
+ FontWeight = 500, // Medium
163
+ LineHeight = 1.75,
164
+ },
165
+
166
+ Subtitle2 = new Subtitle2
167
+ {
168
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
169
+ FontSize = "0.875rem",
170
+ FontWeight = 500,
171
+ LineHeight = 1.57,
172
+ },
173
+
174
+ Overline = new Overline
175
+ {
176
+ FontFamily = new[] { "{Font Name}", "sans-serif" },
177
+ FontSize = "0.75rem",
178
+ FontWeight = 600,
179
+ LineHeight = 2.66,
180
+ LetterSpacing = "0.08em",
181
+ },
182
+ },
183
+
184
+ Shadows = new Shadow
185
+ {
186
+ Elevation = new[]
187
+ {
188
+ "none", // 0
189
+ "0 1px 2px 0 rgba(0, 0, 0, 0.05)", // 1
190
+ "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", // 2
191
+ "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)", // 3
192
+ "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)", // 4
193
+ "0 25px 50px -12px rgba(0, 0, 0, 0.25)", // 5
194
+ // Adicione mais elevações conforme necessário
195
+ }
196
+ },
197
+
198
+ LayoutProperties = new LayoutProperties
199
+ {
200
+ // Border Radius
201
+ DefaultBorderRadius = "6px", // md
202
+
203
+ // Drawer
204
+ DrawerWidthLeft = "240px",
205
+ DrawerWidthRight = "240px",
206
+
207
+ // AppBar
208
+ AppbarHeight = "64px",
209
+ },
210
+
211
+ ZIndex = new ZIndex
212
+ {
213
+ Drawer = 1200,
214
+ AppBar = 1100,
215
+ Dialog = 1300,
216
+ Popover = 1400,
217
+ Snackbar = 1500,
218
+ Tooltip = 1600,
219
+ },
220
+ };
221
+
222
+ /// <summary>
223
+ /// Tema Dark Mode (opcional - ajustar cores)
224
+ /// </summary>
225
+ public static MudTheme DarkTheme => new()
226
+ {
227
+ Palette = new PaletteDark
228
+ {
229
+ // Cores Principais (ajustar para dark mode)
230
+ Primary = "#{hex}",
231
+ Secondary = "#{hex}",
232
+
233
+ // Cores de Estado
234
+ Success = "#{hex}",
235
+ Error = "#{hex}",
236
+ Warning = "#{hex}",
237
+ Info = "#{hex}",
238
+
239
+ // Background e Superfícies (tons escuros)
240
+ Background = "#{hex do gray-900}",
241
+ BackgroundGrey = "#{hex do gray-800}",
242
+ Surface = "#{hex do gray-800}",
243
+
244
+ // Text Colors (invertidos)
245
+ TextPrimary = "#{hex do gray-50}",
246
+ TextSecondary = "#{hex do gray-400}",
247
+ TextDisabled = "#{hex do gray-600}",
248
+
249
+ // Etc... (ajustar conforme design system dark mode)
250
+ },
251
+
252
+ // Compartilhar Typography e outras configurações do LightTheme
253
+ Typography = LightTheme.Typography,
254
+ Shadows = LightTheme.Shadows,
255
+ LayoutProperties = LightTheme.LayoutProperties,
256
+ ZIndex = LightTheme.ZIndex,
257
+ };
258
+ }
259
+
260
+ /// <summary>
261
+ /// EXEMPLO DE USO:
262
+ ///
263
+ /// // Program.cs
264
+ /// builder.Services.AddMudServices(config =>
265
+ /// {
266
+ /// config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomRight;
267
+ /// });
268
+ ///
269
+ /// // App.razor ou MainLayout.razor
270
+ /// <MudThemeProvider Theme="@AppTheme.LightTheme" />
271
+ /// <MudDialogProvider />
272
+ /// <MudSnackbarProvider />
273
+ ///
274
+ /// // Para suportar dark mode dinâmico:
275
+ /// <MudThemeProvider @bind-IsDarkMode="@_isDarkMode"
276
+ /// Theme="@(_isDarkMode ? AppTheme.DarkTheme : AppTheme.LightTheme)" />
277
+ ///
278
+ /// @code {
279
+ /// private bool _isDarkMode;
280
+ /// }
281
+ /// </summary>
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Design System - {Project Name}
3
+ *
4
+ * CSS Variables generated from ui-design-system.md
5
+ * Use estas variáveis em todo o projeto para manter consistência visual.
6
+ *
7
+ * Template MORPH-SPEC v2.1.1 by Polymorphism Tech
8
+ */
9
+
10
+ :root {
11
+ /* ========================================
12
+ * CORES PRINCIPAIS
13
+ * ======================================== */
14
+
15
+ --color-primary: #{hex da cor primária};
16
+ --color-primary-hover: #{hex da cor primária mais escura};
17
+ --color-primary-active: #{hex da cor primária ainda mais escura};
18
+
19
+ --color-secondary: #{hex da cor secundária};
20
+ --color-secondary-hover: #{hex};
21
+ --color-secondary-active: #{hex};
22
+
23
+ /* ========================================
24
+ * CORES DE ESTADO
25
+ * ======================================== */
26
+
27
+ --color-success: #{hex};
28
+ --color-success-bg: #{hex com transparência ou shade mais claro};
29
+ --color-success-border: #{hex};
30
+
31
+ --color-error: #{hex};
32
+ --color-error-bg: #{hex};
33
+ --color-error-border: #{hex};
34
+
35
+ --color-warning: #{hex};
36
+ --color-warning-bg: #{hex};
37
+ --color-warning-border: #{hex};
38
+
39
+ --color-info: #{hex};
40
+ --color-info-bg: #{hex};
41
+ --color-info-border: #{hex};
42
+
43
+ /* ========================================
44
+ * ESCALA DE NEUTROS (Cinzas)
45
+ * ======================================== */
46
+
47
+ --color-gray-50: #{hex};
48
+ --color-gray-100: #{hex};
49
+ --color-gray-200: #{hex};
50
+ --color-gray-300: #{hex};
51
+ --color-gray-400: #{hex};
52
+ --color-gray-500: #{hex};
53
+ --color-gray-600: #{hex};
54
+ --color-gray-700: #{hex};
55
+ --color-gray-800: #{hex};
56
+ --color-gray-900: #{hex};
57
+
58
+ /* ========================================
59
+ * TIPOGRAFIA - FONTES
60
+ * ======================================== */
61
+
62
+ --font-sans: '{Font Name}', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
63
+ --font-serif: '{Font Name}', Georgia, 'Times New Roman', serif;
64
+ --font-mono: '{Font Name}', 'Fira Code', 'Courier New', Consolas, monospace;
65
+
66
+ /* ========================================
67
+ * TIPOGRAFIA - TAMANHOS
68
+ * ======================================== */
69
+
70
+ --text-xs: 0.75rem; /* 12px */
71
+ --text-sm: 0.875rem; /* 14px */
72
+ --text-base: 1rem; /* 16px */
73
+ --text-lg: 1.125rem; /* 18px */
74
+ --text-xl: 1.25rem; /* 20px */
75
+ --text-2xl: 1.5rem; /* 24px */
76
+ --text-3xl: 1.875rem; /* 30px */
77
+ --text-4xl: 2.25rem; /* 36px */
78
+ --text-5xl: 3rem; /* 48px */
79
+
80
+ /* ========================================
81
+ * TIPOGRAFIA - LINE HEIGHTS
82
+ * ======================================== */
83
+
84
+ --leading-none: 1;
85
+ --leading-tight: 1.25;
86
+ --leading-snug: 1.375;
87
+ --leading-normal: 1.5;
88
+ --leading-relaxed: 1.625;
89
+ --leading-loose: 2;
90
+
91
+ /* ========================================
92
+ * TIPOGRAFIA - FONT WEIGHTS
93
+ * ======================================== */
94
+
95
+ --font-light: 300;
96
+ --font-regular: 400;
97
+ --font-medium: 500;
98
+ --font-semibold: 600;
99
+ --font-bold: 700;
100
+ --font-extrabold: 800;
101
+
102
+ /* ========================================
103
+ * ESPAÇAMENTO
104
+ * Baseado em múltiplos de {base}px (ex: 4px)
105
+ * ======================================== */
106
+
107
+ --space-0: 0;
108
+ --space-1: 0.25rem; /* 4px */
109
+ --space-2: 0.5rem; /* 8px */
110
+ --space-3: 0.75rem; /* 12px */
111
+ --space-4: 1rem; /* 16px */
112
+ --space-5: 1.25rem; /* 20px */
113
+ --space-6: 1.5rem; /* 24px */
114
+ --space-7: 1.75rem; /* 28px */
115
+ --space-8: 2rem; /* 32px */
116
+ --space-10: 2.5rem; /* 40px */
117
+ --space-12: 3rem; /* 48px */
118
+ --space-16: 4rem; /* 64px */
119
+ --space-20: 5rem; /* 80px */
120
+ --space-24: 6rem; /* 96px */
121
+
122
+ /* ========================================
123
+ * BORDER RADIUS
124
+ * ======================================== */
125
+
126
+ --rounded-none: 0;
127
+ --rounded-sm: 0.125rem; /* 2px */
128
+ --rounded-md: 0.375rem; /* 6px */
129
+ --rounded-lg: 0.5rem; /* 8px */
130
+ --rounded-xl: 0.75rem; /* 12px */
131
+ --rounded-2xl: 1rem; /* 16px */
132
+ --rounded-full: 9999px;
133
+
134
+ /* ========================================
135
+ * SOMBRAS (Shadows)
136
+ * ======================================== */
137
+
138
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
139
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
140
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
141
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
142
+ --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
143
+
144
+ /* ========================================
145
+ * Z-INDEX LAYERS
146
+ * ======================================== */
147
+
148
+ --z-0: 0;
149
+ --z-10: 10;
150
+ --z-20: 20;
151
+ --z-30: 30;
152
+ --z-40: 40;
153
+ --z-50: 50; /* Modals, dropdowns */
154
+ --z-100: 100; /* Tooltips */
155
+ --z-max: 9999; /* Toasts, notifications */
156
+
157
+ /* ========================================
158
+ * TRANSITIONS / ANIMATIONS
159
+ * ======================================== */
160
+
161
+ --transition-fast: 150ms ease-in-out;
162
+ --transition-base: 250ms ease-in-out;
163
+ --transition-slow: 350ms ease-in-out;
164
+
165
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
166
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
167
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
168
+
169
+ /* ========================================
170
+ * BREAKPOINTS (informativo - usar em media queries)
171
+ * ======================================== */
172
+
173
+ /* @media (min-width: 640px) - sm */
174
+ /* @media (min-width: 768px) - md */
175
+ /* @media (min-width: 1024px) - lg */
176
+ /* @media (min-width: 1280px) - xl */
177
+ /* @media (min-width: 1536px) - 2xl */
178
+ }
179
+
180
+ /* ========================================
181
+ * MODO ESCURO (Dark Mode)
182
+ * Opcional - ajuste as cores para dark theme
183
+ * ======================================== */
184
+
185
+ @media (prefers-color-scheme: dark) {
186
+ :root {
187
+ /* Inverter cores conforme necessário */
188
+ --color-gray-50: #{hex do gray-900};
189
+ --color-gray-900: #{hex do gray-50};
190
+ /* ... outras inversões */
191
+ }
192
+ }
193
+
194
+ /* ========================================
195
+ * CLASSES UTILITÁRIAS (Exemplo)
196
+ * ======================================== */
197
+
198
+ /* Exemplo de uso das variáveis */
199
+ .btn-primary {
200
+ background-color: var(--color-primary);
201
+ color: white;
202
+ padding: var(--space-2) var(--space-4);
203
+ border-radius: var(--rounded-md);
204
+ font-weight: var(--font-semibold);
205
+ transition: background-color var(--transition-base);
206
+ }
207
+
208
+ .btn-primary:hover {
209
+ background-color: var(--color-primary-hover);
210
+ }
211
+
212
+ .card {
213
+ background-color: white;
214
+ padding: var(--space-6);
215
+ border-radius: var(--rounded-lg);
216
+ box-shadow: var(--shadow-md);
217
+ }
218
+
219
+ .text-muted {
220
+ color: var(--color-gray-600);
221
+ font-size: var(--text-sm);
222
+ }
223
+
224
+ /* ========================================
225
+ * FIM DO DESIGN SYSTEM
226
+ * ======================================== */
@@ -0,0 +1,17 @@
1
+ {"timestamp":"2026-02-24T17:14:33.256Z","tool":"Read","error":"File does not exist. Note: your current working directory is R:\\Polymorphism Tech\\repos\\morph-spec-framework.","input":{"file_path":"R:\\Polymorphism Tech\\repos\\morph-spec-framework\\.morph\\features\\override-feature\\0-proposal\\proposal.md"}}
2
+ {"timestamp":"2026-02-24T17:18:09.280Z","tool":"Bash","error":"Exit code 1\nnode:fs:2425\r\n return binding.writeFileUtf8(\r\n ^\r\n\r\nError: ENOENT: no such file or directory, open 'C:\\tmp\\morph-hook-test\\.morph\\state.json'\r\n at writeFileSync (node:fs:2425:20)\r\n at file:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:22:1\r\n at ModuleJob.run (node:internal/modules/esm/module_job:329:25)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\r\n at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:268:26)\r\n at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:264:20)\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'open',\r\n path: 'C:\\\\tmp\\\\morph-hook-test\\\\.morph\\\\state.json'\r\n}\r\n\r\nNode.js v22.17.0\r\n\nnode:fs:2425\r\n return binding.writeFileUtf8(\r\n ^\r\n\r\nError: ENOENT: no such file or directory, open 'C:\\tmp\\morph-hook-test\\.morph\\state.json'\r\n at writeFileSync (node:fs:2425:20)\r\n at file:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:22:1\r\n at ModuleJob.run (node:internal/modules/esm/module_job:329:25)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\r\n at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:268:26)\r\n at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:264:20)\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'open',\r\n path: 'C:\\\\tmp\\\\morph-hook-test\\\\.morph\\\\state.json'\r\n}\r\n\r\nNode.js v22.17.0","input":{"command":"cd /tmp/morph-hook-test && node --input-type=module << 'NODEEOF'\nimport { spawnSync } from 'child_process';\nimport { writeFileSync } from 'fs';\n\n// Restore standard state\nconst state = {\n \"version\": \"4.0.0\",\n \"features\": {\n \"test-feature\": {\n \"phase\": \"tasks\",\n \"status\": \"in_progress\",\n \"approvalGates\": {\n \"proposal\": { \"approved\": true, \"timestamp\": \"2026-02-24T17:00:00.000Z\" },\n \"design\": { \"approved\": true, \"timestamp\": \"2026-02-24T17:00:00.000Z\" },\n \"tasks\": { \"approved\": false, \"timestamp\": null }\n },\n \"outputs\": {},\n \"tasks\": { \"total\": 5, \"completed\": 2 }\n }\n },\n \"activeFeature\": \"test-feature\"\n};\nwriteFileSync('/tmp/morph-hook-test/.morph/state.json', JSON.stringify(state, null, 2));\n\nconst protect_readonly = 'R:/Polymorphism Tech/repos/morph-spec-framework/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js';\nconst nodePath = process.execPath;\nconst cwd = 'C:/Users/Lucas/AppData/Local/Temp/morph-hook-test';\n\nconst tests = [\n {\n label: 'Readonly 1: Write to state.json (should BLOCK)',\n input: '{\"tool_name\":\"Write\",\"tool_input\":{\"file_path\":\".morph/state.json\",\"content\":\"{}\"}}'\n },\n {\n label: 'Readonly 2: Edit state.json (should BLOCK)',\n input: '{\"tool_name\":\"Edit\",\"tool_input\":{\"file_path\":\".morph/state.json\",\"old_string\":\"x\",\"new_string\":\"y\"}}'\n },\n {\n label: 'Readonly 3: Write to framework file (should BLOCK)',\n input: '{\"tool_name\":\"Write\",\"tool_input\":{\"file_path\":\".morph/framework/agents.json\",\"content\":\"{}\"}}'\n },\n {\n label: 'Readonly 4: Write to regular file (should PASS)',\n input: '{\"tool_name\":\"Write\",\"tool_input\":{\"file_path\":\"src/index.js\",\"content\":\"test\"}}'\n },\n {\n label: 'Readonly 5: Write to .morph/features/ file (should PASS)',\n input: '{\"tool_name\":\"Write\",\"tool_input\":{\"file_path\":\".morph/features/test-feature/1-design/spec.md\",\"content\":\"test\"}}'\n },\n];\n\nconsole.log('=== protect-readonly-files.js (legacy hook still present) ===');\nfor (const t of tests) {\n const r = spawnSync(nodePath, [protect_readonly], { input: t.input, encoding: 'utf8', cwd, timeout: 10000 });\n console.log(`\\nTest ${t.label}`);\n console.log('STDOUT:', r.stdout || '(empty)');\n console.log('STDERR:', r.stderr?.substring(0, 200) || '(empty)');\n console.log('EXIT:', r.status);\n}\nNODEEOF","description":"Test legacy protect-readonly-files hook"}}
3
+ {"timestamp":"2026-02-24T17:20:27.996Z","tool":"Bash","error":"Exit code 1\n\n=== CRITICAL BUG ANALYSIS ===\nsettings.local.json hook command: node \"$CLAUDE_PROJECT_DIR/framework/hooks/claude-code/...\"\n$CLAUDE_PROJECT_DIR = /tmp/morph-hook-test (the project root)\nExpected path: /tmp/morph-hook-test/framework/hooks/... (DOES NOT EXIST)\n\nChecking for framework/hooks in project dir:\n /tmp/morph-hook-test/framework/ exists: false\n /tmp/morph-hook-test/.morph/framework/ exists: true\nfile:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:33\r\nconst morphFrameworkContents = require('fs').readdirSync('.morph/framework/');\r\n ^\r\n\r\nReferenceError: require is not defined in ES module scope, you can use import instead\r\n at file:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:33:32\r\n at ModuleJob.run (node:internal/modules/esm/module_job:329:25)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\r\n at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:268:26)\r\n at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:264:20)\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5)\r\n\r\nNode.js v22.17.0\r\n\n\n=== CRITICAL BUG ANALYSIS ===\nsettings.local.json hook command: node \"$CLAUDE_PROJECT_DIR/framework/hooks/claude-code/...\"\n$CLAUDE_PROJECT_DIR = /tmp/morph-hook-test (the project root)\nExpected path: /tmp/morph-hook-test/framework/hooks/... (DOES NOT EXIST)\n\nChecking for framework/hooks in project dir:\n /tmp/morph-hook-test/framework/ exists: false\n /tmp/morph-hook-test/.morph/framework/ exists: true\nfile:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:33\r\nconst morphFrameworkContents = require('fs').readdirSync('.morph/framework/');\r\n ^\r\n\r\nReferenceError: require is not defined in ES module scope, you can use import instead\r\n at file:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:33:32\r\n at ModuleJob.run (node:internal/modules/esm/module_job:329:25)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\r\n at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:268:26)\r\n at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:264:20)\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5)\r\n\r\nNode.js v22.17.0","input":{"command":"cd \"C:/Users/Lucas/AppData/Local/Temp/morph-hook-test\" && node --input-type=module << 'NODEEOF'\n// Now test the $CLAUDE_PROJECT_DIR environment variable issue in settings.local.json\n// The hooks are configured as:\n// node \"$CLAUDE_PROJECT_DIR/framework/hooks/...\"\n// But $CLAUDE_PROJECT_DIR is set by Claude Code automatically when running hooks\n// When init runs and the project is installed globally (npm link), this would resolve to\n// node_modules/morph-spec/framework/... path which may be wrong\n// \n// But in our test, the .claude/settings.local.json uses $CLAUDE_PROJECT_DIR\n// which means when Claude Code runs the hook, it injects the actual project root\n// The hooks then load the shared modules via relative path from the framework dir\n// \n// Let's check: what happens with the hooks installed in .claude/ - do they exist?\nimport { readFileSync, existsSync } from 'fs';\n\n// The settings.local.json references: $CLAUDE_PROJECT_DIR/framework/hooks/...\n// This means the hooks run FROM the morph-spec framework source, NOT from .morph/framework/\n// This is correct since the project's .morph/framework is READ-ONLY\n// But wait - $CLAUDE_PROJECT_DIR is the PROJECT root, not the framework root\n// So the hook path would be: /tmp/morph-hook-test/framework/hooks/... which doesn't exist!\n\nconsole.log('\\n=== CRITICAL BUG ANALYSIS ===');\nconsole.log('settings.local.json hook command: node \"$CLAUDE_PROJECT_DIR/framework/hooks/claude-code/...\"');\nconsole.log('$CLAUDE_PROJECT_DIR = /tmp/morph-hook-test (the project root)');\nconsole.log('Expected path: /tmp/morph-hook-test/framework/hooks/... (DOES NOT EXIST)');\nconsole.log('');\nconsole.log('Checking for framework/hooks in project dir:');\nconsole.log(' /tmp/morph-hook-test/framework/ exists:', existsSync('framework'));\nconsole.log(' /tmp/morph-hook-test/.morph/framework/ exists:', existsSync('.morph/framework'));\n\n// So the REAL path should reference .morph/framework/hooks/... \n// But the settings says framework/hooks/... (no .morph prefix!)\n// Let's check what's actually in .morph/framework/\nconst morphFrameworkContents = require('fs').readdirSync('.morph/framework/');\nconsole.log('\\n.morph/framework/ contents:', morphFrameworkContents);\nNODEEOF","description":"Investigate critical $CLAUDE_PROJECT_DIR path bug"}}
4
+ {"timestamp":"2026-02-24T17:22:45.328Z","tool":"Bash","error":"Exit code 1\nnode:fs:441\r\n return binding.readFileUtf8(path, stringToFlags(options.flag));\r\n ^\r\n\r\nError: ENOENT: no such file or directory, open 'C:\\Users\\Lucas\\AppData\\Local\\Temp\\morph-hook-test\\node_modules\\morph-spec\\package.json'\r\n at readFileSync (node:fs:441:20)\r\n at file:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:9:28\r\n at ModuleJob.run (node:internal/modules/esm/module_job:329:25)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\r\n at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:268:26)\r\n at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:264:20)\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'open',\r\n path: 'C:\\\\Users\\\\Lucas\\\\AppData\\\\Local\\\\Temp\\\\morph-hook-test\\\\node_modules\\\\morph-spec\\\\package.json'\r\n}\r\n\r\nNode.js v22.17.0\r\n\nnode:fs:441\r\n return binding.readFileUtf8(path, stringToFlags(options.flag));\r\n ^\r\n\r\nError: ENOENT: no such file or directory, open 'C:\\Users\\Lucas\\AppData\\Local\\Temp\\morph-hook-test\\node_modules\\morph-spec\\package.json'\r\n at readFileSync (node:fs:441:20)\r\n at file:///C:/Users/Lucas/AppData/Local/Temp/morph-hook-test/[eval1]:9:28\r\n at ModuleJob.run (node:internal/modules/esm/module_job:329:25)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\r\n at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:268:26)\r\n at async ModuleLoader.executeModuleJob (node:internal/modules/esm/loader:264:20)\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'open',\r\n path: 'C:\\\\Users\\\\Lucas\\\\AppData\\\\Local\\\\Temp\\\\morph-hook-test\\\\node_modules\\\\morph-spec\\\\package.json'\r\n}\r\n\r\nNode.js v22.17.0","input":{"command":"cd \"C:/Users/Lucas/AppData/Local/Temp/morph-hook-test\" && node --input-type=module << 'NODEEOF'\n// Let's check what $CLAUDE_PROJECT_DIR actually means by looking at how init installs things\n// The key question: does morph-spec copy the hooks to .morph/ during init?\n// Or does it expect the hooks to run from the npm package directory?\n\nimport { readFileSync, existsSync } from 'fs';\nimport { execSync } from 'child_process';\n\n// Find where morph-spec is installed\nconst pkgJson = JSON.parse(readFileSync('node_modules/morph-spec/package.json', 'utf8'));\nconsole.log('morph-spec location: node_modules/morph-spec/');\nconsole.log('morph-spec version:', pkgJson.version);\n\n// Check if hooks exist in the node_modules copy\nconst hooksInNodeModules = existsSync('node_modules/morph-spec/framework/hooks/claude-code/');\nconsole.log('hooks in node_modules/morph-spec/framework/hooks/:', hooksInNodeModules);\n\n// So if morph-spec is installed as a local dependency, \n// $CLAUDE_PROJECT_DIR = /my-project\n// and hooks are at /my-project/node_modules/morph-spec/framework/hooks/\n// which is NOT the same as $CLAUDE_PROJECT_DIR/framework/hooks/\n\n// If morph-spec is installed globally (npm install -g morph-spec),\n// then $CLAUDE_PROJECT_DIR = /my-project still\n// and the global binary is at /usr/lib/node_modules/morph-spec/ (Linux) or %APPDATA%\\npm\\node_modules\\morph-spec\\ (Windows)\n// Still not accessible as $CLAUDE_PROJECT_DIR/framework/hooks/\n\n// This is definitely a real bug - the hooks path is wrong for any real installation\nconsole.log('\\n=== CONCLUSION: HOOKS PATH IS BROKEN IN PRODUCTION ===');\nconsole.log('The env var $CLAUDE_PROJECT_DIR points to the USER project root');\nconsole.log('framework/hooks/ does not exist at the user project root');\nconsole.log('Hooks silently fail to load (node: file not found)');\nconsole.log('Since all hooks are fail-open (exit 0), this goes undetected');\nNODEEOF","description":"Confirm the hooks path bug with node_modules path analysis"}}
5
+ {"timestamp":"2026-02-24T17:34:27.677Z","tool":"Read","error":"File does not exist. Note: your current working directory is R:\\Polymorphism Tech\\repos\\morph-spec-framework.","input":{"file_path":"R:\\Polymorphism Tech\\repos\\morph-spec-framework\\.morph\\features\\override-feature\\3-tasks\\tasks.md"}}
6
+ {"timestamp":"2026-02-24T17:34:32.988Z","tool":"Read","error":"File does not exist. Note: your current working directory is R:\\Polymorphism Tech\\repos\\morph-spec-framework.","input":{"file_path":"R:\\Polymorphism Tech\\repos\\morph-spec-framework\\.morph\\features\\override-feature\\0-proposal\\proposal.md"}}
7
+ {"timestamp":"2026-02-24T17:38:31.938Z","tool":"Read","error":"File does not exist. Note: your current working directory is R:\\Polymorphism Tech\\repos\\morph-spec-framework.","input":{"file_path":"R:\\Polymorphism Tech\\repos\\morph-spec-framework\\.morph\\features\\override-feature\\0-proposal\\proposal.md"}}
8
+ {"timestamp":"2026-02-24T17:38:53.229Z","tool":"Bash","error":"Exit code 2\n/usr/bin/bash: eval: line 1: unexpected EOF while looking for matching `\"'\n\n/usr/bin/bash: eval: line 1: unexpected EOF while looking for matching `\"'","input":{"command":"ls -la \"R:\\Polymorphism Tech\\repos\\morph-spec-framework\\.morph\\\" 2>&1","description":"List all items in .morph directory"}}
9
+ {"timestamp":"2026-02-24T17:42:40.173Z","tool":"Bash","error":"Exit code 1\nnode:fs:441\r\n return binding.readFileUtf8(path, stringToFlags(options.flag));\r\n ^\r\n\r\nError: ENOENT: no such file or directory, open 'R:\\dev\\stdin'\r\n at Object.readFileSync (node:fs:441:20)\r\n at [eval]:2:34\r\n at runScriptInThisContext (node:internal/vm:209:10)\r\n at node:internal/process/execution:449:12\r\n at [eval]-wrapper:6:24\r\n at runScriptInContext (node:internal/process/execution:447:60)\r\n at evalFunction (node:internal/process/execution:87:30)\r\n at evalScript (node:internal/process/execution:99:3)\r\n at node:internal/main/eval_string:74:3 {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'open',\r\n path: 'R:\\\\dev\\\\stdin'\r\n}\r\n\r\nNode.js v22.17.0\r\n\nnode:fs:441\r\n return binding.readFileUtf8(path, stringToFlags(options.flag));\r\n ^\r\n\r\nError: ENOENT: no such file or directory, open 'R:\\dev\\stdin'\r\n at Object.readFileSync (node:fs:441:20)\r\n at [eval]:2:34\r\n at runScriptInThisContext (node:internal/vm:209:10)\r\n at node:internal/process/execution:449:12\r\n at [eval]-wrapper:6:24\r\n at runScriptInContext (node:internal/process/execution:447:60)\r\n at evalFunction (node:internal/process/execution:87:30)\r\n at evalScript (node:internal/process/execution:99:3)\r\n at node:internal/main/eval_string:74:3 {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'open',\r\n path: 'R:\\\\dev\\\\stdin'\r\n}\r\n\r\nNode.js v22.17.0","input":{"command":"cd \"R:/Polymorphism Tech/repos/morph-spec-framework\" && cat .morph/state.json | node -e \"\nconst d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8'));\nconst active = Object.entries(d.features||{}).find(([,f]) => f.status==='in_progress');\nconsole.log(active ? 'Feature: '+active[0]+' phase: '+active[1].phase : 'No active feature');\nconsole.log('All features:', Object.entries(d.features||{}).map(([k,v])=>' '+k+': '+v.status+'/'+v.phase).join('\\n'));\n\"","description":"Check active feature and all features in state.json"}}
10
+ {"timestamp":"2026-02-24T17:43:41.461Z","tool":"Bash","error":"Permission denied","input":{"command":"git push"}}
11
+ {"timestamp":"2026-02-24T18:11:35.669Z","tool":"Bash","error":"Exit code 1\n/usr/bin/bash: line 1: cd: too many arguments\nhead: cannot open 'echo' for reading: No such file or directory\nhead: cannot open 'Init exit: ' for reading: No such file or directory\n\n/usr/bin/bash: line 1: cd: too many arguments\nhead: cannot open 'echo' for reading: No such file or directory\nhead: cannot open 'Init exit: ' for reading: No such file or directory","input":{"command":"TMPPROJECT=/tmp/morph-hook-verify-nd9q\ncd \"$TMPPROJECT\"\necho -e \"\\n\\n\\n\\n\" | npx morph-spec init --skip-mcp 2>&1 | head -60\necho \"Init exit: $?\"","timeout":60000,"description":"Run morph-spec init with non-interactive input"}}
12
+ {"timestamp":"2026-02-24T18:11:43.022Z","tool":"Bash","error":"Exit code 1\nhead: cannot open 'echo' for reading: No such file or directory\nhead: cannot open 'Init exit: ' for reading: No such file or directory\n\nhead: cannot open 'echo' for reading: No such file or directory\nhead: cannot open 'Init exit: ' for reading: No such file or directory","input":{"command":"cd \"/tmp/morph-hook-verify-nd9q\" && printf \"\\n\\n\\n\\n\" | npx morph-spec init --skip-mcp 2>&1 | head -60\necho \"Init exit: $?\"","timeout":60000,"description":"Run morph-spec init non-interactively in temp project"}}
13
+ {"timestamp":"2026-02-24T18:11:51.077Z","tool":"Bash","error":"Exit code 1\n\n MORPH-SPEC Framework Installation\n ─────────────────────────────────\n\n Target: R:\\Polymorphism Tech\\repos\\morph-spec-framework\n\n ⚠ MORPH already initialized in this directory.\n Use --force to overwrite existing installation.\n\n\n MORPH-SPEC Framework Installation\n ─────────────────────────────────\n\n Target: R:\\Polymorphism Tech\\repos\\morph-spec-framework\n\n ⚠ MORPH already initialized in this directory.\n Use --force to overwrite existing installation.","input":{"command":"TMPPROJECT=\"/tmp/morph-hook-verify-nd9q\"\nprintf \"\\n\\n\\n\\n\" | npx --prefix \"$TMPPROJECT\" morph-spec init --skip-mcp 2>&1\necho \"Init exit: $?\"","timeout":60000,"description":"Run morph-spec init using prefix flag"}}
14
+ {"timestamp":"2026-02-24T18:12:09.467Z","tool":"Bash","error":"Exit code 127\n/usr/bin/bash: line 1: : command not found\n\n/usr/bin/bash: line 1: : command not found","input":{"command":"TMPPROJECT=\"/tmp/morph-hook-verify-nd9q\"\nMORPHCLI=\"$TMPPROJECT/node_modules/.bin/morph-spec\"\nprintf \"\\n\\n\\n\\n\" | \"$MORPHCLI\" init --skip-mcp --cwd \"$TMPPROJECT\" 2>&1\necho \"Init exit: $?\"","timeout":60000,"description":"Run morph-spec init with --cwd flag pointing to temp project"}}
15
+ {"timestamp":"2026-02-24T18:12:37.776Z","tool":"Bash","error":"Exit code 1\nnode_modules\npackage.json\npackage-lock.json\nnode:internal/bootstrap/switches/does_own_process_state:128\r\n rawMethods.chdir(directory);\r\n ^\r\n\r\nError: ENOENT: no such file or directory, chdir 'R:\\Polymorphism Tech\\repos\\morph-spec-framework' -> '/tmp/morph-hook-verify-nd9q'\r\n at process.wrappedChdir [as chdir] (node:internal/bootstrap/switches/does_own_process_state:128:14)\r\n at [eval]:1:9\r\n at runScriptInThisContext (node:internal/vm:209:10)\r\n at node:internal/process/execution:449:12\r\n at [eval]-wrapper:6:24\r\n at runScriptInContext (node:internal/process/execution:447:60)\r\n at evalFunction (node:internal/process/execution:87:30)\r\n at evalScript (node:internal/process/execution:99:3)\r\n at node:internal/main/eval_string:74:3 {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'chdir',\r\n path: 'R:\\\\Polymorphism Tech\\\\repos\\\\morph-spec-framework',\r\n dest: '/tmp/morph-hook-verify-nd9q'\r\n}\r\n\r\nNode.js v22.17.0\r\n\nnode_modules\npackage.json\npackage-lock.json\nnode:internal/bootstrap/switches/does_own_process_state:128\r\n rawMethods.chdir(directory);\r\n ^\r\n\r\nError: ENOENT: no such file or directory, chdir 'R:\\Polymorphism Tech\\repos\\morph-spec-framework' -> '/tmp/morph-hook-verify-nd9q'\r\n at process.wrappedChdir [as chdir] (node:internal/bootstrap/switches/does_own_process_state:128:14)\r\n at [eval]:1:9\r\n at runScriptInThisContext (node:internal/vm:209:10)\r\n at node:internal/process/execution:449:12\r\n at [eval]-wrapper:6:24\r\n at runScriptInContext (node:internal/process/execution:447:60)\r\n at evalFunction (node:internal/process/execution:87:30)\r\n at evalScript (node:internal/process/execution:99:3)\r\n at node:internal/main/eval_string:74:3 {\r\n errno: -4058,\r\n code: 'ENOENT',\r\n syscall: 'chdir',\r\n path: 'R:\\\\Polymorphism Tech\\\\repos\\\\morph-spec-framework',\r\n dest: '/tmp/morph-hook-verify-nd9q'\r\n}\r\n\r\nNode.js v22.17.0","input":{"command":"ls /tmp/morph-hook-verify-nd9q/ && node -e \"process.chdir('/tmp/morph-hook-verify-nd9q'); console.log(process.cwd())\"","description":"Test if chdir works for Linux tmp path"}}
16
+ {"timestamp":"2026-02-24T18:12:58.773Z","tool":"Bash","error":"Exit code 1\ntail: option used in invalid context -- 8\n\ntail: option used in invalid context -- 8","input":{"command":"WINPROJECT=\"C:/Users/Lucas/AppData/Local/Temp/morph-hook-verify-4384\"\nnpm install --prefix \"$WINPROJECT\" \"R:/Polymorphism Tech/repos/morph-spec-framework\" --save 2>&1 | tail -8\necho \"NPM install exit: $?\"","timeout":120000,"description":"Install morph-spec into Windows temp project"}}
17
+ {"timestamp":"2026-02-24T18:17:04.762Z","tool":"Bash","error":"Exit code 1\nnode:internal/modules/esm/load:209\r\n throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed, schemes);\r\n ^\r\n\r\nError [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'\r\n at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:209:11)\r\n at defaultLoad (node:internal/modules/esm/load:107:3)\r\n at ModuleLoader.load (node:internal/modules/esm/loader:800:12)\r\n at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:580:43)\r\n at #createModuleJob (node:internal/modules/esm/loader:604:36)\r\n at #getJobFromResolveResult (node:internal/modules/esm/loader:338:34)\r\n at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:306:41)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {\r\n code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'\r\n}\r\n\r\nNode.js v22.17.0\r\n\nnode:internal/modules/esm/load:209\r\n throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed, schemes);\r\n ^\r\n\r\nError [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'\r\n at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:209:11)\r\n at defaultLoad (node:internal/modules/esm/load:107:3)\r\n at ModuleLoader.load (node:internal/modules/esm/loader:800:12)\r\n at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:580:43)\r\n at #createModuleJob (node:internal/modules/esm/loader:604:36)\r\n at #getJobFromResolveResult (node:internal/modules/esm/loader:338:34)\r\n at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:306:41)\r\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {\r\n code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'\r\n}\r\n\r\nNode.js v22.17.0","input":{"command":"WINPROJECT=\"C:/Users/Lucas/AppData/Local/Temp/morph-hook-verify-4384\"\nHOOKS=\"$WINPROJECT/.morph/framework/hooks/claude-code\"\n\n# Check what getActiveFeature returns\nnode --input-type=module <<EOF\nimport { stateExists, getActiveFeature, getMissingOutputs } from '$HOOKS/../shared/state-reader.js';\nconsole.log('stateExists:', stateExists());\nconst active = getActiveFeature();\nconsole.log('active:', JSON.stringify(active, null, 2));\nEOF","timeout":15000,"description":"Debug getActiveFeature() return value"}}
@@ -0,0 +1,16 @@
1
+ {
2
+ "timestamp": "2026-02-24T17:43:30.048Z",
3
+ "event": "pre-compact",
4
+ "activeFeature": "override-feature",
5
+ "features": {
6
+ "override-feature": {
7
+ "phase": "implement",
8
+ "status": "in_progress",
9
+ "tasks": {
10
+ "total": 20,
11
+ "completed": 30
12
+ },
13
+ "approvalGates": {}
14
+ }
15
+ }
16
+ }