@polymorphism-tech/morph-spec 8.37.1 → 8.40.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.
- package/CLAUDE.md +37 -13
- package/README.md +2 -2
- package/bin/morph-spec.js +75 -49
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +6 -5
- package/framework/MORPH.md +25 -22
- package/framework/agents.json +96 -36
- package/framework/docs/CLI.md +54 -17
- package/framework/evals/rubrics/code-quality.md +5 -0
- package/framework/evals/rubrics/condensed.md +6 -2
- package/framework/evals/rubrics/contracts.md +20 -0
- package/framework/evals/rubrics/test-coverage.md +17 -6
- package/framework/hooks/README.md +9 -3
- package/framework/hooks/claude-code/core/graph-refresh-kick.js +52 -0
- package/framework/hooks/claude-code/core/telemetry-log.js +172 -87
- package/framework/hooks/claude-code/core/validate-completion.js +16 -90
- package/framework/hooks/claude-code/core/worktree-context.js +10 -0
- package/framework/hooks/shared/command-tokens.js +96 -0
- package/framework/hooks/shared/git-exclude.js +44 -0
- package/framework/hooks/shared/git-paths.js +52 -0
- package/framework/hooks/shared/graph-freshness.js +380 -0
- package/framework/hooks/shared/graph-refresh.js +416 -0
- package/framework/hooks/shared/morph-cli.js +17 -5
- package/framework/hooks/shared/redact-secrets.js +55 -0
- package/framework/hooks/shared/telemetry-logger.js +25 -2
- package/framework/hooks/shared/transcript-usage.js +80 -0
- package/framework/mcp/registry.json +33 -2
- package/framework/rubrics/backend.json +2 -2
- package/framework/rubrics/default.json +2 -2
- package/framework/rubrics/frontend.json +2 -2
- package/framework/rules/csharp-standards.md +1 -0
- package/framework/rules/infrastructure-standards.md +0 -1
- package/framework/rules/morph-workflow.md +10 -4
- package/framework/rules/nextjs-standards.md +1 -0
- package/framework/schemas/config.schema.json +41 -1
- package/framework/schemas/feature.schema.json +5 -1
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +40 -11
- package/framework/skills/core/morph-brainstorming/SKILL.md +16 -7
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
- package/framework/skills/core/morph-implement/SKILL.md +44 -10
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +73 -15
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +51 -13
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +39 -13
- package/framework/standards/STANDARDS.json +189 -14
- package/framework/standards/ai-agents/context-providers.md +16 -26
- package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
- package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
- package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
- package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
- package/framework/standards/ai-agents/modalities-vision.md +1 -18
- package/framework/standards/ai-agents/prompt-sources.md +0 -4
- package/framework/standards/ai-agents/testing-ai.md +2 -1
- package/framework/standards/architecture/code-comments.md +100 -0
- package/framework/standards/backend/dotnet/testing.md +22 -0
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
- package/framework/standards/frontend/admin-app/data-table.md +562 -0
- package/framework/standards/frontend/admin-app/feedback.md +236 -0
- package/framework/standards/frontend/admin-app/forms.md +232 -0
- package/framework/standards/frontend/admin-app/page-structure.md +203 -0
- package/framework/standards/frontend/design-system/ai-image-generation.md +5 -5
- package/framework/standards/frontend/nextjs/components.md +37 -58
- package/framework/standards/frontend/nextjs/data-fetching.md +1 -0
- package/framework/standards/frontend/nextjs/forms.md +31 -30
- package/framework/standards/frontend/nextjs/state-management.md +2 -1
- package/framework/standards/frontend/nextjs/testing.md +18 -0
- package/framework/standards/integration/mcp/mcp-tools.md +48 -117
- package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
- package/framework/templates/code/dotnet/database/migration.cs +49 -83
- package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
- package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
- package/framework/templates/code/dotnet/jobs/job.cs +2 -97
- package/framework/templates/code/dotnet/test.cs +2 -87
- package/framework/templates/code/typescript/contracts.ts +140 -167
- package/framework/templates/context/design-system.md +3 -3
- package/framework/templates/docs/proposal.md +11 -0
- package/framework/templates/docs/spec.md +15 -0
- package/framework/templates/docs/ui-mockups.md +115 -98
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
- package/framework/templates/feature/decisions.md +124 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
- package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
- package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
- package/framework/templates/integrations/asaas-client.cs +332 -387
- package/framework/templates/integrations/asaas-webhook.cs +290 -351
- package/framework/templates/integrations/neon-auth-config.cs +9 -105
- package/framework/templates/project/validate.js +97 -120
- package/package.json +2 -2
- package/src/commands/dashboard/dashboard.js +80 -53
- package/src/commands/graph/affected.js +4 -3
- package/src/commands/graph/build.js +109 -18
- package/src/commands/graph/explain.js +8 -5
- package/src/commands/graph/status.js +14 -8
- package/src/commands/mcp/mcp-setup.js +37 -9
- package/src/commands/observability/cost.js +148 -18
- package/src/commands/project/doctor.js +85 -15
- package/src/commands/project/init.js +6 -3
- package/src/commands/project/install-plugin-cmd.js +1 -1
- package/src/commands/project/update.js +30 -0
- package/src/commands/project/worktree.js +73 -90
- package/src/commands/state/advance.js +18 -0
- package/src/commands/state/approve.js +15 -0
- package/src/commands/state/archive.js +62 -9
- package/src/commands/state/finish.js +62 -14
- package/src/commands/state/gate-check.js +8 -1
- package/src/commands/state/gate-decision.js +8 -4
- package/src/commands/state/report-check.js +90 -9
- package/src/commands/state/usecase.js +66 -0
- package/src/commands/tasks/dag.js +17 -2
- package/src/commands/validation/validate-feature.js +6 -1
- package/src/commands/validation/verify.js +20 -1
- package/src/dashboard/app/App.jsx +80 -16
- package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
- package/src/dashboard/app/components/CommandPalette.jsx +155 -0
- package/src/dashboard/app/components/DetailPanel.jsx +47 -11
- package/src/dashboard/app/components/EntityLink.jsx +55 -0
- package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
- package/src/dashboard/app/components/FlowGraph.jsx +19 -17
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
- package/src/dashboard/app/components/Markdown.jsx +47 -0
- package/src/dashboard/app/components/PhaseRail.jsx +111 -0
- package/src/dashboard/app/components/SearchFilter.jsx +40 -22
- package/src/dashboard/app/components/Sidebar.jsx +146 -37
- package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
- package/src/dashboard/app/hooks/usePref.js +38 -0
- package/src/dashboard/app/lib/format.js +69 -0
- package/src/dashboard/app/lib/phases.js +56 -0
- package/src/dashboard/app/lib/project.js +50 -0
- package/src/dashboard/app/pages/Activity.jsx +24 -0
- package/src/dashboard/app/pages/AgentMap.jsx +371 -370
- package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
- package/src/dashboard/app/pages/Features.jsx +400 -0
- package/src/dashboard/app/pages/Guide.jsx +146 -0
- package/src/dashboard/app/pages/HookInspector.jsx +357 -322
- package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
- package/src/dashboard/app/pages/Portfolio.jsx +156 -0
- package/src/dashboard/app/pages/Rubrics.jsx +101 -0
- package/src/dashboard/app/pages/RulesMap.jsx +300 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
- package/src/dashboard/app/pages/Standards.jsx +407 -332
- package/src/dashboard/app/styles/index.css +187 -47
- package/src/dashboard/index.html +14 -12
- package/src/dashboard/package.json +32 -24
- package/src/dashboard/scanner/activity-scanner.js +351 -0
- package/src/dashboard/scanner/agents-scanner.js +63 -1
- package/src/dashboard/scanner/docs-scanner.js +59 -0
- package/src/dashboard/scanner/feature-status.js +10 -0
- package/src/dashboard/scanner/features-scanner.js +360 -0
- package/src/dashboard/scanner/hooks-scanner.js +8 -1
- package/src/dashboard/scanner/index.js +14 -7
- package/src/dashboard/scanner/phases-scanner.js +14 -15
- package/src/dashboard/scanner/portfolio.js +153 -0
- package/src/dashboard/scanner/project-api.js +195 -0
- package/src/dashboard/scanner/rules-scanner.js +42 -37
- package/src/dashboard/scanner/skills-scanner.js +105 -43
- package/src/dashboard/scanner/standards-scanner.js +4 -1
- package/src/dashboard/vite-plugin-morph-data.js +134 -17
- package/src/lib/ai/comment-stripper.js +101 -4
- package/src/lib/detectors/claude-config-detector.js +2 -7
- package/src/lib/detectors/index.js +5 -1
- package/src/lib/evaluator-report.js +47 -0
- package/src/lib/generators/handoff-generator.js +4 -18
- package/src/lib/generators/settings-generator.js +208 -209
- package/src/lib/git/default-branch.js +52 -0
- package/src/lib/git/tree-fingerprint.js +58 -0
- package/src/lib/git/tree-state.js +167 -0
- package/src/lib/graph/god-nodes.js +12 -3
- package/src/lib/graph/graph-health.js +48 -2
- package/src/lib/graph/graph-loader.js +99 -25
- package/src/lib/graph/graphifyignore.js +145 -28
- package/src/lib/graph/sanitize.js +117 -11
- package/src/lib/installers/mcp-installer.js +724 -719
- package/src/lib/installers/memory-installer.js +1 -2
- package/src/lib/projects/registry.js +154 -0
- package/src/lib/risk-detector.js +90 -0
- package/src/lib/specs/acervo-format.js +70 -0
- package/src/lib/specs/acervo-lifecycle.js +264 -0
- package/src/lib/specs/adr-index.js +169 -0
- package/src/lib/specs/revocations.js +156 -0
- package/src/lib/specs/screen-checklist.js +357 -0
- package/src/lib/specs/usecase-check.js +20 -16
- package/src/lib/specs/usecase-promoter.js +103 -38
- package/src/lib/specs/usecase-registry.js +7 -7
- package/src/lib/tasks/tasks-json-parser.js +2 -3
- package/src/lib/telemetry/metrics.js +386 -0
- package/src/lib/telemetry/telemetry-reader.js +161 -51
- package/src/lib/telemetry/verify-event.js +79 -0
- package/src/lib/validators/code-budget/code-budget-validator.js +200 -0
- package/src/lib/validators/code-budget/comment-scanner.js +75 -0
- package/src/lib/validators/code-budget/index.js +9 -0
- package/src/lib/validators/reuse/reuse-validator.js +4 -2
- package/src/lib/validators/reuse/symbol-scanner.js +27 -22
- package/src/lib/validators/validation-runner.js +21 -5
- package/src/lib/validators/verify-runner.js +11 -0
- package/src/lib/worktree/finish-backup.js +739 -0
- package/src/lib/worktree/ignored-triage.js +15 -8
- package/src/lib/worktree/worktree-audit.js +5 -0
- package/src/scripts/install-plugin.js +1 -1
- package/src/scripts/setup-infra.js +31 -22
- package/src/utils/agents-installer.js +338 -24
- package/src/utils/banner.js +1 -1
- package/src/utils/hooks-installer.js +75 -15
- package/src/commands/index.js +0 -13
- package/src/commands/project/checkpoint.js +0 -209
- package/src/core/state/phase-state-machine.js +0 -197
- package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
- package/src/dashboard/app/pages/LiveState.jsx +0 -206
- package/src/dashboard/scanner/squads-scanner.js +0 -13
- package/src/dashboard/scanner/state-scanner.js +0 -85
- package/src/lib/generators/index.js +0 -10
- package/src/lib/hooks/hook-executor.js +0 -167
- package/src/lib/validators/checkpoint-persistence.js +0 -39
- package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
- package/src/lib/validators/shared/index.js +0 -12
- package/src/lib/validators/shared/issue-counter.js +0 -14
- package/src/lib/validators/shared/result-formatter.js +0 -124
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// TEST TEMPLATE (VSA Pattern — Handler + Validator)
|
|
3
|
-
// Generated by MORPH Framework
|
|
4
|
-
// ============================================================
|
|
5
|
-
|
|
6
1
|
using FluentAssertions;
|
|
7
2
|
using FluentValidation;
|
|
8
3
|
using FluentValidation.Results;
|
|
@@ -14,15 +9,6 @@ using Xunit;
|
|
|
14
9
|
|
|
15
10
|
namespace {{pascalCase PROJECT_NAME}}.Tests.Unit.Features.{{pascalCase FEATURE_NAME}};
|
|
16
11
|
|
|
17
|
-
// ============================================================
|
|
18
|
-
// Handler Tests
|
|
19
|
-
// ============================================================
|
|
20
|
-
|
|
21
|
-
/// <summary>
|
|
22
|
-
/// Unit tests for {{pascalCase FEATURE_NAME}} handlers.
|
|
23
|
-
/// Tests handlers directly against a real ApplicationDbContext backed by
|
|
24
|
-
/// in-memory SQLite (no mocks — DbSet is the repository, DbContext is the unit of work).
|
|
25
|
-
/// </summary>
|
|
26
12
|
public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
27
13
|
{
|
|
28
14
|
private readonly SqliteConnection _connection;
|
|
@@ -30,6 +16,7 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
30
16
|
|
|
31
17
|
public {{pascalCase FEATURE_NAME}}HandlerTests()
|
|
32
18
|
{
|
|
19
|
+
// o banco :memory: some quando a conexão fecha, então ela vive o teste inteiro
|
|
33
20
|
_connection = new SqliteConnection("DataSource=:memory:");
|
|
34
21
|
_connection.Open();
|
|
35
22
|
|
|
@@ -47,19 +34,14 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
47
34
|
_connection.Dispose();
|
|
48
35
|
}
|
|
49
36
|
|
|
50
|
-
#region Create Handler Tests
|
|
51
|
-
|
|
52
37
|
[Fact]
|
|
53
38
|
public async Task Create_HandleAsync_WithValidCommand_ReturnsSuccessResult()
|
|
54
39
|
{
|
|
55
|
-
// Arrange
|
|
56
40
|
var command = new Create{{pascalCase FEATURE_NAME}}Request("Test {{pascalCase FEATURE_NAME}}");
|
|
57
41
|
var handler = new Create{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
58
42
|
|
|
59
|
-
// Act
|
|
60
43
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
61
44
|
|
|
62
|
-
// Assert
|
|
63
45
|
result.IsSuccess.Should().BeTrue();
|
|
64
46
|
result.Value.Should().NotBeNull();
|
|
65
47
|
|
|
@@ -67,14 +49,9 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
67
49
|
persisted.Name.Should().Be("Test {{pascalCase FEATURE_NAME}}");
|
|
68
50
|
}
|
|
69
51
|
|
|
70
|
-
#endregion
|
|
71
|
-
|
|
72
|
-
#region GetById Handler Tests
|
|
73
|
-
|
|
74
52
|
[Fact]
|
|
75
53
|
public async Task GetById_HandleAsync_WithValidId_ReturnsSuccessResult()
|
|
76
54
|
{
|
|
77
|
-
// Arrange
|
|
78
55
|
var entity = CreateTestEntity("Test {{pascalCase FEATURE_NAME}}");
|
|
79
56
|
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
80
57
|
await _db.SaveChangesAsync();
|
|
@@ -82,10 +59,8 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
82
59
|
var query = new Get{{pascalCase FEATURE_NAME}}ByIdRequest(entity.Id);
|
|
83
60
|
var handler = new Get{{pascalCase FEATURE_NAME}}ByIdHandler(_db);
|
|
84
61
|
|
|
85
|
-
// Act
|
|
86
62
|
var result = await handler.HandleAsync(query, CancellationToken.None);
|
|
87
63
|
|
|
88
|
-
// Assert
|
|
89
64
|
result.IsSuccess.Should().BeTrue();
|
|
90
65
|
result.Value.Should().NotBeNull();
|
|
91
66
|
result.Value!.Name.Should().Be("Test {{pascalCase FEATURE_NAME}}");
|
|
@@ -94,25 +69,17 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
94
69
|
[Fact]
|
|
95
70
|
public async Task GetById_HandleAsync_WithInvalidId_ReturnsFailureResult()
|
|
96
71
|
{
|
|
97
|
-
// Arrange
|
|
98
72
|
var query = new Get{{pascalCase FEATURE_NAME}}ByIdRequest(Guid.CreateVersion7());
|
|
99
73
|
var handler = new Get{{pascalCase FEATURE_NAME}}ByIdHandler(_db);
|
|
100
74
|
|
|
101
|
-
// Act
|
|
102
75
|
var result = await handler.HandleAsync(query, CancellationToken.None);
|
|
103
76
|
|
|
104
|
-
// Assert
|
|
105
77
|
result.IsSuccess.Should().BeFalse();
|
|
106
78
|
}
|
|
107
79
|
|
|
108
|
-
#endregion
|
|
109
|
-
|
|
110
|
-
#region Update Handler Tests
|
|
111
|
-
|
|
112
80
|
[Fact]
|
|
113
81
|
public async Task Update_HandleAsync_WithValidCommand_ReturnsSuccessResult()
|
|
114
82
|
{
|
|
115
|
-
// Arrange
|
|
116
83
|
var entity = CreateTestEntity("Original Name");
|
|
117
84
|
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
118
85
|
await _db.SaveChangesAsync();
|
|
@@ -120,10 +87,8 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
120
87
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(entity.Id, "Updated Name");
|
|
121
88
|
var handler = new Update{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
122
89
|
|
|
123
|
-
// Act
|
|
124
90
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
125
91
|
|
|
126
|
-
// Assert
|
|
127
92
|
result.IsSuccess.Should().BeTrue();
|
|
128
93
|
|
|
129
94
|
var persisted = await _db.Set<{{pascalCase FEATURE_NAME}}>().SingleAsync(x => x.Id == entity.Id);
|
|
@@ -133,25 +98,17 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
133
98
|
[Fact]
|
|
134
99
|
public async Task Update_HandleAsync_WithNonExistentId_ReturnsFailureResult()
|
|
135
100
|
{
|
|
136
|
-
// Arrange
|
|
137
101
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(Guid.CreateVersion7(), "Updated");
|
|
138
102
|
var handler = new Update{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
139
103
|
|
|
140
|
-
// Act
|
|
141
104
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
142
105
|
|
|
143
|
-
// Assert
|
|
144
106
|
result.IsSuccess.Should().BeFalse();
|
|
145
107
|
}
|
|
146
108
|
|
|
147
|
-
#endregion
|
|
148
|
-
|
|
149
|
-
#region Delete Handler Tests
|
|
150
|
-
|
|
151
109
|
[Fact]
|
|
152
110
|
public async Task Delete_HandleAsync_WithValidId_ReturnsSuccessResult()
|
|
153
111
|
{
|
|
154
|
-
// Arrange
|
|
155
112
|
var entity = CreateTestEntity("To Delete");
|
|
156
113
|
_db.Set<{{pascalCase FEATURE_NAME}}>().Add(entity);
|
|
157
114
|
await _db.SaveChangesAsync();
|
|
@@ -159,10 +116,8 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
159
116
|
var command = new Delete{{pascalCase FEATURE_NAME}}Request(entity.Id);
|
|
160
117
|
var handler = new Delete{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
161
118
|
|
|
162
|
-
// Act
|
|
163
119
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
164
120
|
|
|
165
|
-
// Assert
|
|
166
121
|
result.IsSuccess.Should().BeTrue();
|
|
167
122
|
|
|
168
123
|
(await _db.Set<{{pascalCase FEATURE_NAME}}>().AnyAsync(x => x.Id == entity.Id)).Should().BeFalse();
|
|
@@ -171,57 +126,35 @@ public class {{pascalCase FEATURE_NAME}}HandlerTests : IDisposable
|
|
|
171
126
|
[Fact]
|
|
172
127
|
public async Task Delete_HandleAsync_WithNonExistentId_ReturnsFailureResult()
|
|
173
128
|
{
|
|
174
|
-
// Arrange
|
|
175
129
|
var command = new Delete{{pascalCase FEATURE_NAME}}Request(Guid.CreateVersion7());
|
|
176
130
|
var handler = new Delete{{pascalCase FEATURE_NAME}}Handler(_db);
|
|
177
131
|
|
|
178
|
-
// Act
|
|
179
132
|
var result = await handler.HandleAsync(command, CancellationToken.None);
|
|
180
133
|
|
|
181
|
-
// Assert
|
|
182
134
|
result.IsSuccess.Should().BeFalse();
|
|
183
135
|
}
|
|
184
136
|
|
|
185
|
-
#endregion
|
|
186
|
-
|
|
187
|
-
#region Helper Methods
|
|
188
|
-
|
|
189
137
|
private static {{pascalCase FEATURE_NAME}} CreateTestEntity(string name)
|
|
190
138
|
{
|
|
191
139
|
return new {{pascalCase FEATURE_NAME}}
|
|
192
140
|
{
|
|
193
141
|
Id = Guid.CreateVersion7(),
|
|
194
142
|
Name = name,
|
|
195
|
-
// TODO:
|
|
143
|
+
// TODO: demais campos obrigatórios da entidade
|
|
196
144
|
};
|
|
197
145
|
}
|
|
198
|
-
|
|
199
|
-
#endregion
|
|
200
146
|
}
|
|
201
147
|
|
|
202
|
-
// ============================================================
|
|
203
|
-
// Validator Tests
|
|
204
|
-
// ============================================================
|
|
205
|
-
|
|
206
|
-
/// <summary>
|
|
207
|
-
/// Unit tests for {{pascalCase FEATURE_NAME}} validators.
|
|
208
|
-
/// Tests FluentValidation rules using ValidateAsync.
|
|
209
|
-
/// </summary>
|
|
210
148
|
public class {{pascalCase FEATURE_NAME}}ValidatorTests
|
|
211
149
|
{
|
|
212
|
-
#region Create Validator Tests
|
|
213
|
-
|
|
214
150
|
[Fact]
|
|
215
151
|
public async Task CreateValidator_WithValidCommand_PassesValidation()
|
|
216
152
|
{
|
|
217
|
-
// Arrange
|
|
218
153
|
var validator = new Create{{pascalCase FEATURE_NAME}}Validator();
|
|
219
154
|
var command = new Create{{pascalCase FEATURE_NAME}}Request("Valid Name");
|
|
220
155
|
|
|
221
|
-
// Act
|
|
222
156
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
223
157
|
|
|
224
|
-
// Assert
|
|
225
158
|
result.IsValid.Should().BeTrue();
|
|
226
159
|
result.Errors.Should().BeEmpty();
|
|
227
160
|
}
|
|
@@ -232,14 +165,11 @@ public class {{pascalCase FEATURE_NAME}}ValidatorTests
|
|
|
232
165
|
[InlineData(null)]
|
|
233
166
|
public async Task CreateValidator_WithInvalidName_FailsValidation(string? name)
|
|
234
167
|
{
|
|
235
|
-
// Arrange
|
|
236
168
|
var validator = new Create{{pascalCase FEATURE_NAME}}Validator();
|
|
237
169
|
var command = new Create{{pascalCase FEATURE_NAME}}Request(name!);
|
|
238
170
|
|
|
239
|
-
// Act
|
|
240
171
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
241
172
|
|
|
242
|
-
// Assert
|
|
243
173
|
result.IsValid.Should().BeFalse();
|
|
244
174
|
result.Errors.Should().Contain(e => e.PropertyName == nameof(Create{{pascalCase FEATURE_NAME}}Request.Name));
|
|
245
175
|
}
|
|
@@ -247,50 +177,35 @@ public class {{pascalCase FEATURE_NAME}}ValidatorTests
|
|
|
247
177
|
[Fact]
|
|
248
178
|
public async Task CreateValidator_WithNameExceedingMaxLength_FailsValidation()
|
|
249
179
|
{
|
|
250
|
-
// Arrange
|
|
251
180
|
var validator = new Create{{pascalCase FEATURE_NAME}}Validator();
|
|
252
181
|
var command = new Create{{pascalCase FEATURE_NAME}}Request(new string('A', 201));
|
|
253
182
|
|
|
254
|
-
// Act
|
|
255
183
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
256
184
|
|
|
257
|
-
// Assert
|
|
258
185
|
result.IsValid.Should().BeFalse();
|
|
259
186
|
result.Errors.Should().Contain(e => e.PropertyName == nameof(Create{{pascalCase FEATURE_NAME}}Request.Name));
|
|
260
187
|
}
|
|
261
188
|
|
|
262
|
-
#endregion
|
|
263
|
-
|
|
264
|
-
#region Update Validator Tests
|
|
265
|
-
|
|
266
189
|
[Fact]
|
|
267
190
|
public async Task UpdateValidator_WithValidCommand_PassesValidation()
|
|
268
191
|
{
|
|
269
|
-
// Arrange
|
|
270
192
|
var validator = new Update{{pascalCase FEATURE_NAME}}Validator();
|
|
271
193
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(Guid.CreateVersion7(), "Updated Name");
|
|
272
194
|
|
|
273
|
-
// Act
|
|
274
195
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
275
196
|
|
|
276
|
-
// Assert
|
|
277
197
|
result.IsValid.Should().BeTrue();
|
|
278
198
|
}
|
|
279
199
|
|
|
280
200
|
[Fact]
|
|
281
201
|
public async Task UpdateValidator_WithInvalidId_FailsValidation()
|
|
282
202
|
{
|
|
283
|
-
// Arrange
|
|
284
203
|
var validator = new Update{{pascalCase FEATURE_NAME}}Validator();
|
|
285
204
|
var command = new Update{{pascalCase FEATURE_NAME}}Request(Guid.Empty, "Updated Name");
|
|
286
205
|
|
|
287
|
-
// Act
|
|
288
206
|
ValidationResult result = await validator.ValidateAsync(command);
|
|
289
207
|
|
|
290
|
-
// Assert
|
|
291
208
|
result.IsValid.Should().BeFalse();
|
|
292
209
|
result.Errors.Should().Contain(e => e.PropertyName == nameof(Update{{pascalCase FEATURE_NAME}}Request.Id));
|
|
293
210
|
}
|
|
294
|
-
|
|
295
|
-
#endregion
|
|
296
211
|
}
|
|
@@ -1,167 +1,140 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
export
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
export interface
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
name: string;
|
|
142
|
-
bucket: string;
|
|
143
|
-
path: string;
|
|
144
|
-
publicUrl: string;
|
|
145
|
-
size: number;
|
|
146
|
-
contentType: string;
|
|
147
|
-
createdAt: string;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ----- Auth Types -----
|
|
151
|
-
|
|
152
|
-
export interface AuthUser {
|
|
153
|
-
id: string;
|
|
154
|
-
email: string;
|
|
155
|
-
displayName: string | null;
|
|
156
|
-
avatarUrl: string | null;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export interface AuthSession {
|
|
160
|
-
user: AuthUser;
|
|
161
|
-
accessToken: string;
|
|
162
|
-
expiresAt: number;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// ----- Form Schemas (use with zod) -----
|
|
166
|
-
// Define zod schemas in component files, not here.
|
|
167
|
-
// This file is for type definitions only.
|
|
1
|
+
// {{titleCase FEATURE_NAME}} contracts, generated {{DATE}}
|
|
2
|
+
|
|
3
|
+
export interface NeonConfig {
|
|
4
|
+
connectionString: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ApiClientConfig {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
getAccessToken: () => Promise<string | null>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ApiError {
|
|
13
|
+
message: string;
|
|
14
|
+
code: string;
|
|
15
|
+
statusCode: number;
|
|
16
|
+
details?: Record<string, string[]>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ApiResult<T> =
|
|
20
|
+
| { success: true; data: T }
|
|
21
|
+
| { success: false; error: ApiError };
|
|
22
|
+
|
|
23
|
+
export interface PaginationQuery {
|
|
24
|
+
page?: number;
|
|
25
|
+
pageSize?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface PagedResult<T> {
|
|
29
|
+
items: T[];
|
|
30
|
+
totalCount: number;
|
|
31
|
+
page: number;
|
|
32
|
+
pageSize: number;
|
|
33
|
+
totalPages: number;
|
|
34
|
+
hasNext: boolean;
|
|
35
|
+
hasPrevious: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type Tables<T extends keyof Database["public"]["Tables"]> =
|
|
39
|
+
Database["public"]["Tables"][T]["Row"];
|
|
40
|
+
|
|
41
|
+
export type Insertable<T extends keyof Database["public"]["Tables"]> =
|
|
42
|
+
Database["public"]["Tables"][T]["Insert"];
|
|
43
|
+
|
|
44
|
+
export type Updatable<T extends keyof Database["public"]["Tables"]> =
|
|
45
|
+
Database["public"]["Tables"][T]["Update"];
|
|
46
|
+
|
|
47
|
+
// Placeholder: replace with the types your ORM (Drizzle or Prisma) generates from the Neon schema.
|
|
48
|
+
export interface Database {
|
|
49
|
+
public: {
|
|
50
|
+
Tables: {
|
|
51
|
+
{{FEATURE_NAME}}: {
|
|
52
|
+
Row: {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string;
|
|
55
|
+
user_id: string;
|
|
56
|
+
status: {{pascalCase FEATURE_NAME}}Status;
|
|
57
|
+
created_at: string;
|
|
58
|
+
updated_at: string | null;
|
|
59
|
+
};
|
|
60
|
+
Insert: {
|
|
61
|
+
id?: string;
|
|
62
|
+
name: string;
|
|
63
|
+
user_id?: string;
|
|
64
|
+
status?: {{pascalCase FEATURE_NAME}}Status;
|
|
65
|
+
created_at?: string;
|
|
66
|
+
updated_at?: string | null;
|
|
67
|
+
};
|
|
68
|
+
Update: {
|
|
69
|
+
id?: string;
|
|
70
|
+
name?: string;
|
|
71
|
+
user_id?: string;
|
|
72
|
+
status?: {{pascalCase FEATURE_NAME}}Status;
|
|
73
|
+
created_at?: string;
|
|
74
|
+
updated_at?: string | null;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
Views: Record<string, never>;
|
|
79
|
+
Functions: Record<string, never>;
|
|
80
|
+
Enums: {
|
|
81
|
+
{{FEATURE_NAME}}_status: {{pascalCase FEATURE_NAME}}Status;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type {{pascalCase FEATURE_NAME}}Status =
|
|
87
|
+
| "draft"
|
|
88
|
+
| "active"
|
|
89
|
+
| "completed"
|
|
90
|
+
| "archived"
|
|
91
|
+
| "failed"
|
|
92
|
+
| "cancelled";
|
|
93
|
+
|
|
94
|
+
export interface {{pascalCase FEATURE_NAME}} {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
userId: string;
|
|
98
|
+
status: {{pascalCase FEATURE_NAME}}Status;
|
|
99
|
+
createdAt: string;
|
|
100
|
+
updatedAt: string | null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface Create{{pascalCase FEATURE_NAME}}Input {
|
|
104
|
+
name: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface Update{{pascalCase FEATURE_NAME}}Input {
|
|
108
|
+
name?: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface StorageUpload {
|
|
112
|
+
bucket: string;
|
|
113
|
+
path: string;
|
|
114
|
+
file: File;
|
|
115
|
+
contentType?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface StorageFile {
|
|
119
|
+
id: string;
|
|
120
|
+
name: string;
|
|
121
|
+
bucket: string;
|
|
122
|
+
path: string;
|
|
123
|
+
publicUrl: string;
|
|
124
|
+
size: number;
|
|
125
|
+
contentType: string;
|
|
126
|
+
createdAt: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface AuthUser {
|
|
130
|
+
id: string;
|
|
131
|
+
email: string;
|
|
132
|
+
displayName: string | null;
|
|
133
|
+
avatarUrl: string | null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface AuthSession {
|
|
137
|
+
user: AuthUser;
|
|
138
|
+
accessToken: string;
|
|
139
|
+
expiresAt: number;
|
|
140
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Template** — copy to `.morph/context/design-system.md` and fill in sections marked `/* CUSTOMIZE */`.
|
|
4
4
|
|
|
5
|
-
Living document. All agents read this before any UI work. All design decisions land here.
|
|
5
|
+
Living document. All agents read this before any UI work. All design decisions land here — **rewritten in place, never stacked**: a decision that changes rewrites the section that described the old one (a value that still holds somewhere says where), so an agent reading only the body gets today's answer.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -332,8 +332,8 @@ Choose patterns based on the project domain:
|
|
|
332
332
|
|
|
333
333
|
## Changelog
|
|
334
334
|
|
|
335
|
-
>
|
|
336
|
-
> Format: `- YYYY-MM-DD [agent-id]
|
|
335
|
+
> When and why the body changed — never the new value itself: that lives in the section it rewrote.
|
|
336
|
+
> Format: `- YYYY-MM-DD [agent-id] reason (section rewritten)`
|
|
337
337
|
|
|
338
338
|
<!-- Entries below this line, newest first -->
|
|
339
339
|
|
|
@@ -136,6 +136,17 @@ How will we know this feature is successful?
|
|
|
136
136
|
|
|
137
137
|
---
|
|
138
138
|
|
|
139
|
+
## Conflitos com o acervo
|
|
140
|
+
|
|
141
|
+
UCs (`.morph/specs/usecases/`), ADRs ativos (`.morph/specs/adrs/`) and `.morph/context/*.md` that
|
|
142
|
+
this request contradicts. `Nenhum conflito encontrado.` when there is none — the section is always present.
|
|
143
|
+
|
|
144
|
+
| Fonte | O que diz hoje | O que o pedido muda | Decisão |
|
|
145
|
+
|-------|----------------|---------------------|---------|
|
|
146
|
+
| {UC-133} | {Public Sans + Lora em toda a interface} | {admin passa a Geist} | {vale o novo no admin; a vitrine mantém o antigo — decisions.md ADR-001} |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
139
150
|
## Dependencies
|
|
140
151
|
|
|
141
152
|
- [ ] {Dependency 1} - {status}
|
|
@@ -204,6 +204,21 @@ public interface I{{pascalCase FEATURE_NAME}}Service
|
|
|
204
204
|
|
|
205
205
|
---
|
|
206
206
|
|
|
207
|
+
## UCs e ADRs que esta feature altera ou revoga
|
|
208
|
+
|
|
209
|
+
> Read by `morph-spec finish`: in the archive commit, each row marks the project acervo — a UC turns
|
|
210
|
+
> `status: superseded` + `superseded_by` (+ `scope` when partial); an ADR leaves `.morph/specs/adrs/`
|
|
211
|
+
> (total) or keeps its file with the scope where it still holds (partial). Columns are positional.
|
|
212
|
+
> `morph-spec usecase check {feature}` reports a bad row while this file can still change (it freezes at Gate 2).
|
|
213
|
+
> Nothing revoked → replace the table with `Nenhum.`
|
|
214
|
+
|
|
215
|
+
| Id | Mudança | Substituto | Escopo em que o antigo ainda vale |
|
|
216
|
+
|----|---------|------------|-----------------------------------|
|
|
217
|
+
| UC-{nn} | parcial | UC-{nn} | {where the old one still holds} |
|
|
218
|
+
| {feature}/ADR-{nnn} | total | — | — |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
207
222
|
## Security
|
|
208
223
|
|
|
209
224
|
| Action | Required Policy |
|