@polymorphism-tech/morph-spec 8.34.2 → 8.35.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 +20 -3
- package/README.md +2 -2
- package/bin/morph-spec.js +18 -4
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +5 -4
- package/docs/QUICKSTART.md +1 -1
- package/framework/MORPH.md +16 -17
- package/framework/agents.json +197 -44
- package/framework/ai-pin.json +22 -0
- package/framework/commands/morph-media.md +45 -0
- package/framework/docs/CLI.md +234 -9
- package/framework/evals/proof-rubrics/README.md +76 -0
- package/framework/evals/proof-rubrics/eval-de-modelo.md +64 -0
- package/framework/evals/proof-rubrics/fiacao.md +54 -0
- package/framework/evals/proof-rubrics/guard-cego.md +52 -0
- package/framework/evals/proof-rubrics/media-claims.md +109 -0
- package/framework/evals/proof-rubrics/mutation-proof.md +77 -0
- package/framework/evals/proof-rubrics/observabilidade-genai.md +119 -0
- package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +48 -0
- package/framework/evals/rubrics/architecture.md +30 -0
- package/framework/evals/rubrics/code-quality.md +26 -0
- package/framework/evals/rubrics/test-coverage.md +20 -0
- package/framework/hooks/claude-code/core/protect-spec-files.js +41 -4
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/e2e-check.js +135 -22
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/rules/ai-agents-standards.md +14 -2
- package/framework/schemas/ai-pin.schema.json +97 -0
- package/framework/schemas/config.schema.json +107 -0
- package/framework/schemas/feature.schema.json +23 -4
- 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 +26 -5
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
- package/framework/skills/core/morph-implement/SKILL.md +18 -2
- package/framework/skills/core/morph-media/SKILL.md +215 -0
- package/framework/skills/core/morph-plan/SKILL.md +33 -2
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +166 -9
- 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 +1 -1
- package/framework/standards/PROVENANCE.json +81 -3
- package/framework/standards/STANDARDS.json +1483 -839
- package/framework/standards/ai-agents/agent-archetypes.md +160 -0
- package/framework/standards/ai-agents/agent-session.md +164 -68
- package/framework/standards/ai-agents/agent-spec.md +196 -0
- package/framework/standards/ai-agents/batching.md +61 -37
- package/framework/standards/ai-agents/context-providers.md +97 -24
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +239 -0
- package/framework/standards/ai-agents/cost-and-budget.md +256 -0
- package/framework/standards/ai-agents/durable-workflows-hitl.md +98 -5
- package/framework/standards/ai-agents/evals-with-cache.md +289 -0
- package/framework/standards/ai-agents/guardrails.md +222 -0
- package/framework/standards/ai-agents/llm-runtime-defaults.md +226 -0
- package/framework/standards/ai-agents/mcp-server.md +119 -18
- package/framework/standards/ai-agents/mcp-tools.md +85 -32
- package/framework/standards/ai-agents/media-pipeline.md +352 -0
- package/framework/standards/ai-agents/media-video.md +267 -0
- package/framework/standards/ai-agents/middleware-patterns.md +39 -5
- package/framework/standards/ai-agents/modalities-image-gen.md +354 -105
- package/framework/standards/ai-agents/modalities-speech-to-text.md +8 -2
- package/framework/standards/ai-agents/modalities-text-to-speech.md +10 -2
- package/framework/standards/ai-agents/modalities-vision.md +6 -2
- package/framework/standards/ai-agents/multi-agent-patterns.md +61 -5
- package/framework/standards/ai-agents/observability-patterns.md +227 -17
- package/framework/standards/ai-agents/production.md +38 -9
- package/framework/standards/ai-agents/prompt-sources.md +389 -0
- package/framework/standards/ai-agents/providers/model-registry.md +174 -39
- package/framework/standards/ai-agents/rag-custom-pgvector.md +69 -4
- package/framework/standards/ai-agents/service-tier-flex.md +27 -19
- package/framework/standards/ai-agents/setup.md +166 -50
- package/framework/standards/ai-agents/structured-output.md +34 -3
- package/framework/standards/ai-agents/sweet-spot.md +23 -3
- package/framework/standards/ai-agents/testing-ai.md +236 -0
- package/framework/standards/ai-agents/vector-data-extensions.md +50 -20
- package/framework/standards/ai-agents/workflows.md +27 -7
- package/framework/standards/frontend/design-system/ai-image-generation.md +12 -0
- package/framework/standards/frontend/design-system/ai-video-generation.md +13 -0
- package/framework/standards/infrastructure/docker/local-compose-isolation.md +3 -1
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/REGISTRY.json +13 -0
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +1 -1
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +1 -1
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/dotnet/ai-kit/Directory.Build.props +25 -0
- package/framework/templates/dotnet/ai-kit/Directory.Packages.props +26 -0
- package/framework/templates/dotnet/ai-kit/Morph.AiKit.sln +56 -0
- package/framework/templates/dotnet/ai-kit/NuGet.config +12 -0
- package/framework/templates/dotnet/ai-kit/README.md +128 -0
- package/framework/templates/dotnet/ai-kit/global.json +9 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +65 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +289 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +91 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +91 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +181 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +14 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +174 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +54 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +75 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +71 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +246 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +57 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +78 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +225 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +463 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +32 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +49 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +214 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +168 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +142 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +349 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +42 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +77 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +28 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +107 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +253 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +103 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +259 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +21 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +47 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +102 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +44 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +192 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +94 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +99 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +97 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +133 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +93 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +112 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +288 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +158 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +29 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +208 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +95 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Morph.AiKit.csproj +38 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +119 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +82 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +33 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +267 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +474 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/model-registry.v2.json +87 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +169 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +49 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +495 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +260 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +405 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +379 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +197 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +139 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +157 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +178 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +153 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +194 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +86 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +213 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +95 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +225 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +215 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +33 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +89 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +55 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +60 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +131 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +133 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +127 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +216 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +264 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +148 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +184 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +89 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +98 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +451 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +76 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +33 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +261 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +374 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/.morph-eval-cache.json +12 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/orcamento/acme/a-resposta-estruturada.json +24 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/a-saudacao.json +23 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/b-escalonamento.json +24 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/globex/a-saudacao.json +23 -0
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +3 -3
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/e2e/e2e.js +15 -2
- package/src/commands/index.js +13 -13
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/doctor.js +140 -5
- package/src/commands/project/update.js +469 -153
- package/src/commands/project/worktree.js +8 -1
- package/src/commands/state/advance.js +24 -2
- package/src/commands/state/approve.js +33 -1
- package/src/commands/state/create.js +72 -11
- package/src/commands/state/finish.js +333 -21
- package/src/commands/state/gate-check.js +190 -6
- package/src/commands/state/score.js +36 -1
- package/src/commands/validation/verify.js +134 -25
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/state/state-manager.js +9 -1
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/ai/ai-checks.js +182 -0
- package/src/lib/ai/ai-project-scan.js +347 -0
- package/src/lib/ai/code-audit.js +181 -0
- package/src/lib/ai/comment-stripper.js +184 -0
- package/src/lib/ai/pin-drift.js +138 -0
- package/src/lib/ai/registry-audit.js +285 -0
- package/src/lib/detectors/design-system-detector.js +188 -188
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/e2e/compose-env.js +50 -4
- package/src/lib/evaluator-report.js +269 -15
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/git/default-branch.js +92 -4
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/effects.js +193 -0
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/installers/templates-reconcile.js +3 -3
- package/src/lib/risk-detector.js +284 -0
- package/src/lib/standards/verified-against.js +276 -0
- package/src/lib/tasks/eval-node.js +485 -0
- package/src/lib/tasks/linux-runner.js +297 -0
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/test-nodes.js +486 -0
- package/src/lib/tasks/test-runner.js +410 -33
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/verify-runner.js +583 -28
- package/src/lib/worktree/docker-audit.js +287 -0
- package/src/lib/worktree/env-allocator.js +24 -0
- package/src/lib/worktree/worktree-audit.js +30 -1
- package/src/scripts/setup-infra.js +24 -11
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/agents-installer.js +18 -8
- package/src/utils/claude-md-injector.js +10 -5
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/file-copier.js +11 -4
- package/src/utils/hooks-installer.js +29 -26
- package/src/utils/skills-installer.js +36 -29
- package/src/utils/version-checker.js +68 -3
- package/framework/standards/ai-agents/prompts-in-db.md +0 -214
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Testing AI — como se testa um agente sem rede, sem chave e sem variância
|
|
2
|
+
|
|
3
|
+
> **Scope:** stacks=["dotnet"]
|
|
4
|
+
> **Layer:** 1 (on-keyword)
|
|
5
|
+
> **Keywords:** testar agente, fake IChatClient, ScriptedChatClient, harness de turno, eval de agente, teste sem rede, golden de prompt, compatibilidade binaria
|
|
6
|
+
> **Read by Claude in:** implement (ao escrever o teste de qualquer código que fala com um modelo)
|
|
7
|
+
|
|
8
|
+
**Verified against:** Microsoft.Extensions.AI 10.9.0 + Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs` e `.../src/Morph.AiKit/Providers/IProviderClientFactory.cs` — o fake roteirizado e a costura que dispensa rede são o que o kit compila e exercita. Harness de turno completo e evals com cache de resposta são **verificação documental** — o ai-kit não os traz. Last-verified: 2026-09-08.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Fronteira com o testing genérico
|
|
13
|
+
|
|
14
|
+
`backend-dotnet-testing` continua dono do que é de teste em .NET: xUnit, `FakeTimeProvider`,
|
|
15
|
+
isolamento entre casos, nomes de teste, organização de fixtures. **Nada disso se repete aqui.**
|
|
16
|
+
|
|
17
|
+
Este standard cobre **só o que é de agente** — e o que é de agente cabe em uma frase: o único ponto
|
|
18
|
+
em que o seu código toca um provider é um `IChatClient`. Todo o resto deste arquivo é consequência
|
|
19
|
+
disso.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Fake de IChatClient
|
|
24
|
+
|
|
25
|
+
**Roteirizado e burro.** Uma fila de respostas escritas à mão, servidas na ordem:
|
|
26
|
+
|
|
27
|
+
- resposta de texto;
|
|
28
|
+
- resposta com chamada de função (`FunctionCallContent`);
|
|
29
|
+
- resposta de texto com uso preenchido (para exercitar a conta de custo).
|
|
30
|
+
|
|
31
|
+
A fila guarda **respostas**, não exceções: no exemplar do kit, os três métodos de enfileiramento
|
|
32
|
+
recebem `ChatResponse` (direto, por texto, ou por texto + uso), e o único `throw` do fake é o de
|
|
33
|
+
**fila esgotada**. Para exercitar o caminho de falha do provider, injete um cliente que lança em vez
|
|
34
|
+
de enfileirar uma exceção — são costuras diferentes, e confundi-las faz o teste de falha passar pelo
|
|
35
|
+
motivo errado.
|
|
36
|
+
|
|
37
|
+
E do outro lado, **captura**: as mensagens recebidas, as opções recebidas e a contagem de chamadas —
|
|
38
|
+
uma entrada por chamada, na ordem. É o que permite assertar *o que foi ao provedor*, e não apenas
|
|
39
|
+
*o que voltou*.
|
|
40
|
+
|
|
41
|
+
**A regra que define o padrão: o fake não pode ser inteligente.** Ele não escolhe resposta por
|
|
42
|
+
conteúdo, não simula um modelo, não "responde razoavelmente". E, esgotada a fila, **ele lança**, com
|
|
43
|
+
a contagem exata de chamadas. Devolver uma resposta vazia em silêncio faria um teste passar por
|
|
44
|
+
engano — que é a única coisa pior do que um teste falhando.
|
|
45
|
+
|
|
46
|
+
O argumento mais forte a favor desta forma não é teórico: **duas implementações independentes, em
|
|
47
|
+
dois produtos que não se conhecem, chegaram à mesma coisa** (um `FakeChatClient` e um
|
|
48
|
+
`ScriptedChatClient`, com a mesma fila e a mesma captura). O ai-kit compila a terceira.
|
|
49
|
+
|
|
50
|
+
### A costura, e por que `sealed` não é desculpa para abri-la
|
|
51
|
+
|
|
52
|
+
O fake só serve se houver **um** ponto de injeção. No kit, esse ponto é uma interface de uma
|
|
53
|
+
operação — dado um alias resolvido, devolva o `IChatClient`. O registry permanece `sealed` e continua
|
|
54
|
+
sem saber construir cliente de provider nenhum.
|
|
55
|
+
|
|
56
|
+
> **O que o kit traz, e o que ele não traz.** A única implementação dessa interface no kit é a de
|
|
57
|
+
> **teste** (`FakeProviderClientFactory`) — medido. O adaptador de produção, aquele que faz o
|
|
58
|
+
> `switch` por provider e constrói o cliente de verdade, é **seu**: o kit prova que a costura
|
|
59
|
+
> funciona, não que o outro lado dela existe. É a mesma distinção de níveis do resto deste standard.
|
|
60
|
+
|
|
61
|
+
Precedente de campo com a **variante**: quando o registry é `sealed` e não se quer uma interface
|
|
62
|
+
pública, a costura foi um **construtor `internal`** recebendo uma função `alias -> IChatClient`,
|
|
63
|
+
exposta ao projeto de teste. As duas formas resolvem o mesmo problema; ambas preservam `sealed`, que
|
|
64
|
+
é a política da casa. **Costura de teste não é justificativa para tornar uma classe herdável.**
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Harness de turno
|
|
69
|
+
|
|
70
|
+
**Rode o loop real por cima do fake.** O valor não está em testar o fake; está em fazer o cliente de
|
|
71
|
+
invocação de funções **real** chamar as tools **reais**, com os clientes externos mockados.
|
|
72
|
+
|
|
73
|
+
É assim que se prova, sem rede e sem chave de API:
|
|
74
|
+
|
|
75
|
+
- que a tool escolhida foi a certa para aquele estado;
|
|
76
|
+
- que os argumentos montados batem;
|
|
77
|
+
- que o guard barrou o que devia barrar;
|
|
78
|
+
- que o teto de tool calls encerrou o turno onde devia;
|
|
79
|
+
- que o custo somou o que devia somar.
|
|
80
|
+
|
|
81
|
+
Nenhuma dessas cinco coisas é observável testando o compositor isolado — todas dependem do loop.
|
|
82
|
+
|
|
83
|
+
**Nota de ownership de recurso:** quem cria o cliente e quem o descarta precisa ser decidido uma vez.
|
|
84
|
+
Se a fábrica guardasse e reaproveitasse clientes por fora, existiriam duas caches da mesma coisa — e
|
|
85
|
+
duas caches da mesma coisa é como um cliente vazado sobrevive a um teste e polui o seguinte.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Eval e unit
|
|
90
|
+
|
|
91
|
+
**"Eval" aqui não significa "modelo real".**
|
|
92
|
+
|
|
93
|
+
O padrão medido, e é o que dá mais retorno por hora escrita, é o **eval determinístico**: exercitar o
|
|
94
|
+
caminho **completo e real** — processador de turno, compositor, runner com middleware, tools,
|
|
95
|
+
persistência — com o comportamento do modelo **roteirizado**. Ganha-se cobertura de decisão sem
|
|
96
|
+
variância, e o teste falha por um motivo legível em vez de "o modelo respondeu diferente hoje".
|
|
97
|
+
|
|
98
|
+
Para o que **precisa** do modelo de verdade, o passo seguinte é uma biblioteca de avaliação com
|
|
99
|
+
**cache de resposta**, em **categoria própria** de teste — nunca misturada à suíte determinística. E
|
|
100
|
+
a regra que fecha: **gate duro só vale sobre propriedade determinística.** Reprovar um build porque
|
|
101
|
+
uma nota subjetiva caiu de 8,1 para 7,9 é transformar ruído em bloqueio.
|
|
102
|
+
|
|
103
|
+
**Zero chamada real ao provider dentro do `dotnet test`.** É uma propriedade **verificável
|
|
104
|
+
mecanicamente**, e o jeito de verificá-la é uma varredura sobre `tests/` procurando chave de
|
|
105
|
+
provider, leitura de variável de ambiente e cliente HTTP: ela precisa voltar **vazia**.
|
|
106
|
+
|
|
107
|
+
> **Quem faz essa varredura hoje: ninguém, automaticamente.** Medido em 2026-09-08 sobre o ai-kit
|
|
108
|
+
> (`grep -rniE "OPENAI_API_KEY|GetEnvironmentVariable|HttpClient|EnumerateFiles|Directory.Get"` em
|
|
109
|
+
> `templates/dotnet/ai-kit/**`): **zero ocorrências** — o que prova que o kit **não chama** o
|
|
110
|
+
> provider, e simultaneamente que **não existe teste que cobre essa ausência**. O kit descreve a
|
|
111
|
+
> propriedade em prosa (`FakeChatClient.cs`), não a guarda. Adotar esta regra significa **escrever a
|
|
112
|
+
> varredura no seu projeto**; herdá-la do kit é herdar uma intenção.
|
|
113
|
+
|
|
114
|
+
A medição de campo que sustenta a regra é do **acervo**, não do kit: `grep -c OPENAI_API_KEY` em
|
|
115
|
+
`tests/` = 0, sem nenhum teste marcado como pulado nem categoria de exclusão — ou seja, não há
|
|
116
|
+
"teste real desligado", há ausência de teste real.
|
|
117
|
+
|
|
118
|
+
**E o standard registra o preço disso**, porque ele é real: o harness com modelo de verdade daquele
|
|
119
|
+
projeto (onze cenários) **nunca foi rodado por completo ao vivo**. O que fica fora do `dotnet test`
|
|
120
|
+
tende a não rodar. Se um caminho precisa do modelo real, ele precisa de um dono e de um gatilho — ou
|
|
121
|
+
vai apodrecer.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Captura do que foi ao provedor
|
|
126
|
+
|
|
127
|
+
O que se quer saber depois de um bug é: **o que exatamente foi enviado?**
|
|
128
|
+
|
|
129
|
+
Os dois artefatos que existem no campo, e nenhum deles se chama "captura da chamada crua":
|
|
130
|
+
|
|
131
|
+
1. **As opções recebidas pelo fake** — em teste, é a prova direta de que a lista de tools ofertadas
|
|
132
|
+
saiu da lista real, de que o modo de tool era o esperado, e de que o esforço de raciocínio foi o
|
|
133
|
+
do alias.
|
|
134
|
+
2. **O hash do texto que foi ao provedor** — em produção.
|
|
135
|
+
|
|
136
|
+
**A regra: prompt cru só em desenvolvimento e no harness, com opt-in explícito e sem dado pessoal;
|
|
137
|
+
em produção, hash.** Um prompt cru persistido em produção é um vazamento esperando indexação.
|
|
138
|
+
|
|
139
|
+
Duas asserções que o campo escreveu e que valem copiar: que a lista de tools ofertadas **saiu da
|
|
140
|
+
lista real** (e não de uma constante paralela), e que **turno cancelado não grava** — porque um
|
|
141
|
+
registro de algo que não aconteceu é pior que ausência de registro.
|
|
142
|
+
|
|
143
|
+
A metade de produção deste assunto — como o hash vira span, e a invariante que o torna confiável —
|
|
144
|
+
é de `ai-agents-observability-patterns`.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Golden com parcimônia
|
|
149
|
+
|
|
150
|
+
Golden test congela uma saída em arquivo e compara. É excelente onde o **contrato é a forma**, e é
|
|
151
|
+
peso morto onde o conteúdo muda por motivo legítimo.
|
|
152
|
+
|
|
153
|
+
**Onde compensa:** o render de uma persona a partir de blocos, o contrato de saída estruturada, o
|
|
154
|
+
formato de um artefato publicado.
|
|
155
|
+
|
|
156
|
+
**Onde não compensa, com contra-exemplo real:** goldens de dois blobs de prompt foram **removidos de
|
|
157
|
+
propósito** de um projeto, com a justificativa medida — *"13,6 KB congelados para provar duas linhas
|
|
158
|
+
de concatenação"*. Cada edição de prompt exigia regravar 13,6 KB, o diff era ilegível, e a revisão
|
|
159
|
+
virava um "aceitar tudo". Um golden que ninguém lê no diff não é teste: é atrito.
|
|
160
|
+
|
|
161
|
+
O critério: **golden prova forma, não conteúdo.** Se a asserção real é "estas duas linhas
|
|
162
|
+
concatenam", escreva as duas linhas.
|
|
163
|
+
|
|
164
|
+
### Teste de compatibilidade binária
|
|
165
|
+
|
|
166
|
+
Técnica, não filosofia: comparar em runtime a versão do assembly do SDK carregado com a que a ponte
|
|
167
|
+
referencia, e conferir a **assinatura** do membro que já quebrou uma vez. É barato, roda sem rede, e
|
|
168
|
+
pega a classe de defeito que custou uma chamada paga sem resposta. Ponte com
|
|
169
|
+
`ai-agents-llm-runtime-defaults`, seção de pin de SDK.
|
|
170
|
+
|
|
171
|
+
### Prompt versionado é texto testável
|
|
172
|
+
|
|
173
|
+
Quando o prompt vive fora do código, ele continua sendo texto — e texto se testa. Ler a fonte
|
|
174
|
+
versionada e assertar:
|
|
175
|
+
|
|
176
|
+
- **presença** de uma regra que precisa estar lá;
|
|
177
|
+
- **vocabulário** das chaves que o consumidor espera;
|
|
178
|
+
- **ausência** de uma instrução revogada — que é a asserção que ninguém escreve e a que mais pega
|
|
179
|
+
regressão.
|
|
180
|
+
|
|
181
|
+
Precedente de campo: treze arquivos e cerca de 2.500 linhas fazendo exatamente isso. Ponte com
|
|
182
|
+
`ai-agents-prompt-sources`, seção de reconciliação.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Anti-patterns
|
|
187
|
+
|
|
188
|
+
| Anti-pattern | Por quê é problema | Solução |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| Fake "inteligente" que escolhe resposta por conteúdo | Você passa a testar o fake | Fila roteirizada, servida na ordem |
|
|
191
|
+
| Fake que devolve vazio quando a fila acaba | O teste passa por engano | Lance, com a contagem de chamadas |
|
|
192
|
+
| Testar só o compositor, sem o loop real | Tool escolhida, guard e teto ficam sem cobertura | Harness com o cliente de invocação real |
|
|
193
|
+
| Chamada real ao provider dentro do `dotnet test` | Custo, flake e dependência de rede na suíte | Zero; e verifique com varredura |
|
|
194
|
+
| Harness com modelo real sem dono nem gatilho | Onze cenários que nunca rodaram por completo | Dono, gatilho e categoria própria |
|
|
195
|
+
| Gate duro sobre nota subjetiva de eval | Ruído virando bloqueio de build | Gate só sobre propriedade determinística |
|
|
196
|
+
| Prompt cru persistido em produção | Vazamento esperando indexação | Hash em produção; cru só em dev/harness com opt-in |
|
|
197
|
+
| Gravar telemetria de turno cancelado | Registro de algo que não aconteceu | Não grave |
|
|
198
|
+
| Golden de blob de prompt | 13,6 KB congelados para provar duas linhas | Asserte as duas linhas |
|
|
199
|
+
| Abrir a classe (`sealed` removido) para poder testar | Costura de teste virando decisão de arquitetura | Interface de uma operação, ou construtor `internal` |
|
|
200
|
+
| Fábrica que guarda e reaproveita clientes por fora | Duas caches da mesma coisa; cliente vazado entre testes | Ownership decidido num lugar |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Checklist (verifiable by morph-eval)
|
|
205
|
+
|
|
206
|
+
- [ ] Existe um fake de `IChatClient` roteirizado, com captura de mensagens, opções e contagem
|
|
207
|
+
- [ ] O fake **lança** quando a fila acaba
|
|
208
|
+
- [ ] Há ao menos um teste que roda o loop **real** de invocação de funções por cima do fake
|
|
209
|
+
- [ ] Existe **no seu projeto** um teste que varre `tests/` por chave de provider, leitura de ambiente
|
|
210
|
+
e cliente HTTP, e ele volta vazio (o ai-kit **não** traz essa varredura — medido; herdá-la do
|
|
211
|
+
kit é herdar uma intenção)
|
|
212
|
+
- [ ] Nenhum teste real de modelo está apenas "pulado" — ou tem dono e gatilho, ou não existe
|
|
213
|
+
- [ ] Nenhum gate duro sobre nota subjetiva de eval
|
|
214
|
+
- [ ] Existe asserção de que a lista de tools ofertadas saiu da lista real
|
|
215
|
+
- [ ] Turno cancelado não grava telemetria
|
|
216
|
+
- [ ] Nenhum golden de blob de prompt; goldens existentes provam **forma**
|
|
217
|
+
- [ ] Existe teste de compatibilidade binária do par SDK × ponte
|
|
218
|
+
- [ ] O prompt versionado tem teste de texto, incluindo **ausência** de instrução revogada
|
|
219
|
+
- [ ] Nenhuma classe deixou de ser `sealed` por causa de teste
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## References
|
|
224
|
+
|
|
225
|
+
- `backend-dotnet-testing` — dono do testing .NET genérico (xUnit, `FakeTimeProvider`, isolamento).
|
|
226
|
+
Nada dele se repete aqui
|
|
227
|
+
- `ai-agents-llm-runtime-defaults` — o pin de SDK que o teste de compatibilidade binária protege
|
|
228
|
+
- `ai-agents-prompt-sources` — a fonte versionada que o teste de prompt como texto lê
|
|
229
|
+
- `ai-agents-observability-patterns` — a metade de produção da captura (hash, span, invariante)
|
|
230
|
+
- `ai-agents-conversational-agent-with-phases` — compositor, allow-list e teto: o que o harness exercita
|
|
231
|
+
- `ai-agents-cost-and-budget` — a conta que o harness confere com uso roteirizado
|
|
232
|
+
- `ai-agents-guardrails` — os guards que só o loop real prova
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
*MORPH-SPEC by Polymorphism Tech — ai-agents/testing-ai.md v1.0 (2026-09-08)*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> **Keywords:** microsoft extensions vectordata, vectorstorecollection, vector store abstraction, data ingestion, ingestion pipeline, semantic kernel connectors exception, pgvector connector, vectorstorewriter
|
|
6
6
|
> **Read by Claude in:** plan (when choosing a RAG storage backend) + implement (when deciding whether to adopt VectorData over custom pgvector)
|
|
7
7
|
|
|
8
|
-
**Verified against:** Microsoft.Extensions.VectorData.Abstractions
|
|
8
|
+
**Verified against:** Microsoft.Extensions.VectorData.Abstractions **10.9.0** + CommunityToolkit.VectorData.PgVector **1.0.1** + Microsoft.Extensions.DataIngestion **10.9.0-preview.1.26411.16** — nenhum deles está no `framework/ai-pin.json` (que cobre os 5 pacotes de agente), portanto **todas as versões acima foram apuradas na API do nuget.org em 2026-09-08** e são citadas com essa data, não como pin. **Verificação documental**, sem cláusula `provado por`: o ai-kit **não referencia nem exercita** VectorData — o pacote não está no `Morph.AiKit.csproj`, cujos cinco `PackageReference` são exatamente os do pin (medido 2026-09-08). Aqui nem a régua fraca do restore existe. Last-verified: 2026-09-08.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -33,7 +33,23 @@ A single `VectorStoreCollection<TKey, TRecord>` shape works identically whether
|
|
|
33
33
|
|
|
34
34
|
## A pegadinha de nomenclatura (crítico — leia antes de tudo)
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
> **Atualização de 2026-09-08 — a pegadinha mudou de forma.** Os conectores concretos **saíram** dos nomes `Microsoft.SemanticKernel.Connectors.*` e passaram a `CommunityToolkit.VectorData.*` (repositório `github.com/CommunityToolkit/AI`). Medido na API do nuget.org em 2026-09-08:
|
|
37
|
+
>
|
|
38
|
+
> | Pacote | Última versão | Publicada | Estável? |
|
|
39
|
+
> |---|---|---|---|
|
|
40
|
+
> | `Microsoft.SemanticKernel.Connectors.PgVector` | `1.74.0-preview` | 2026-03-20 | **Nunca teve versão estável**; parou aí |
|
|
41
|
+
> | `CommunityToolkit.VectorData.PgVector` | **`1.0.1`** | **2026-08-31** | **Sim** |
|
|
42
|
+
> | `CommunityToolkit.VectorData.InMemory` | `1.0.1` | 2026-08-31 | Sim |
|
|
43
|
+
>
|
|
44
|
+
> Os dois carregam o **mesmo título e a mesma descrição** ("Postgres (with pgvector extension) provider for Microsoft.Extensions.VectorData"), trocando apenas o autor — *"by Semantic Kernel"* → *"by the .NET Community Toolkit"*. É a mesma peça, com outro dono e outro nome.
|
|
45
|
+
>
|
|
46
|
+
> **Use `CommunityToolkit.VectorData.PgVector` 1.0.1.** O pacote com nome de Semantic Kernel é caminho morto: última versão em março de 2026, e preview.
|
|
47
|
+
>
|
|
48
|
+
> *Fronteira do que foi medido:* a substituição acima é medida (existência, versões, datas, título e descrição, apurados na API do nuget.org em 2026-09-08). Que a página do NuGet **exiba um aviso de rename** não foi confirmado nem pelo `.nuspec` da 1.74.0-preview nem pelos metadados de deprecação da registration API — a afirmação aqui é a substituição, não o aviso.
|
|
49
|
+
|
|
50
|
+
A pegadinha original — abaixo — continua valendo para **projeto legado** que ainda referencia o nome antigo, e para quem tropeça no nome ao ler código existente.
|
|
51
|
+
|
|
52
|
+
The concrete vector-store **connectors** — the packages that actually implement `VectorStoreCollection` against a real backend — **used to** ship under `Microsoft.SemanticKernel.Connectors.*` package names (`Microsoft.SemanticKernel.Connectors.PgVector`, `.Qdrant`, `.SqlServer`, `.CosmosNoSQL`, `.InMemory`, etc.), even though `Microsoft.Extensions.VectorData.Abstractions` itself has been transferred out of the Semantic Kernel repo into `dotnet/extensions` and is fully independent of SK orchestration.
|
|
37
53
|
|
|
38
54
|
Microsoft's own docs are explicit about this:
|
|
39
55
|
|
|
@@ -45,28 +61,36 @@ Microsoft's own docs are explicit about this:
|
|
|
45
61
|
|
|
46
62
|
## Maturidade atual (verificado 2026-07-06)
|
|
47
63
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
|
51
|
-
|
|
52
|
-
| `Microsoft.
|
|
53
|
-
| `Microsoft.
|
|
54
|
-
| `
|
|
64
|
+
> Tabela **reapurada em 2026-09-08** na API do nuget.org. Cada linha traz a versão exata e a data — nenhum destes pacotes está no `framework/ai-pin.json`, então a data de apuração é o que dá validade ao número.
|
|
65
|
+
|
|
66
|
+
| Package | Versão (apurada 2026-09-08) | Status |
|
|
67
|
+
|---------|------------------------------|--------|
|
|
68
|
+
| `Microsoft.Extensions.VectorData.Abstractions` | **10.9.0** (publicada 2026-08-11) | **GA** — é a camada de abstração |
|
|
69
|
+
| `Microsoft.Extensions.AI` / `Microsoft.Extensions.AI.Abstractions` | **10.9.0** (no ai-pin) | **GA** |
|
|
70
|
+
| `CommunityToolkit.VectorData.PgVector` (Postgres/pgvector connector) | **1.0.1** (publicada 2026-08-31) | **Estável** — é o conector recomendado hoje |
|
|
71
|
+
| `CommunityToolkit.VectorData.InMemory` / demais conectores | **1.0.1** (2026-08-31) | Estável; confira cada um antes de adicionar |
|
|
72
|
+
| `Microsoft.SemanticKernel.Connectors.PgVector` | `1.74.0-preview` (2026-03-20) | **Caminho morto** — nunca teve versão estável e não avança desde março/2026 |
|
|
73
|
+
| `Microsoft.Extensions.DataIngestion` | **`10.9.0-preview.1.26411.16`** | **Preview** — sem versão estável |
|
|
55
74
|
|
|
56
|
-
|
|
75
|
+
> **Cuidado com o número que o conector declara.** `CommunityToolkit.VectorData.PgVector` 1.0.1 depende de `Microsoft.Extensions.VectorData.Abstractions` **10.8.2** — esse é o **piso da dependência**, não a versão corrente da abstração, que é 10.9.0. Citar 10.8.2 como "a versão do VectorData" é ler o `.nuspec` do conector como se fosse o do pacote.
|
|
76
|
+
|
|
77
|
+
Preview packages are subject to breaking API changes before GA (see the rename `PostgresVectorStoreRecordCollection` → `PostgresCollection` as precedent).
|
|
57
78
|
|
|
58
79
|
---
|
|
59
80
|
|
|
60
81
|
## Decision matrix — custom pgvector vs VectorData
|
|
61
82
|
|
|
83
|
+
**O critério, em uma frase:** a abstração se paga quando **a troca de store é plausível**; o SQL cru se paga quando **já funciona e é testado**. Nada aqui manda migrar o que está de pé.
|
|
84
|
+
|
|
62
85
|
| Situation | Use |
|
|
63
86
|
|-----------|-----|
|
|
64
|
-
| Default production RAG on Neon/Postgres (this framework's default stack) | **`ai-agents-rag-custom-pgvector`** —
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
87
|
+
| Default production RAG on Neon/Postgres (this framework's default stack), **already implemented and tested** | **`ai-agents-rag-custom-pgvector`** — framework-owned raw SQL, zero external connector, already the checklisted default. **Não se migra o que funciona** (item D4 da elevação-9) |
|
|
88
|
+
| **Projeto novo** onde a escolha do store ainda não foi cravada, e trocá-lo depois deve custar pouco | `Microsoft.Extensions.VectorData.Abstractions` 10.9.0 + `CommunityToolkit.VectorData.PgVector` 1.0.1 — hoje **ambos estáveis**, o que remove o argumento "é preview" que existia em julho/2026 |
|
|
89
|
+
| Project needs genuine portability across >1 vector backend (a client contract requires swapping Postgres for Qdrant or Azure AI Search later) | `Microsoft.Extensions.VectorData` + o conector correspondente — document the choice in `decisions.md` |
|
|
90
|
+
| Prototyping, tests, or demos where an in-memory store is enough | `CommunityToolkit.VectorData.InMemory` 1.0.1 |
|
|
91
|
+
| Ingestão em pipeline (reader → chunker → writer) hoje | Só com `Microsoft.Extensions.DataIngestion`, que **continua preview**: registre a aceitação e um lembrete de revisitar no GA |
|
|
68
92
|
|
|
69
|
-
Do not migrate the existing `ai-agents-rag-custom-pgvector` implementation to
|
|
93
|
+
Do not migrate the existing `ai-agents-rag-custom-pgvector` implementation to VectorData as a default — that would rewrite a working, tested, framework-owned implementation for no functional gain. **O que mudou desde a verificação anterior:** o argumento *"o conector é preview"* **caiu** (o `CommunityToolkit` é estável desde 2026-08-31); o argumento *"não se reescreve o que funciona"* **permanece**, e é ele que sustenta o default hoje.
|
|
70
94
|
|
|
71
95
|
---
|
|
72
96
|
|
|
@@ -138,9 +162,11 @@ This maps conceptually onto the existing custom pattern: `IngestionDocumentReade
|
|
|
138
162
|
|
|
139
163
|
| Anti-pattern | Why it's wrong | Right way |
|
|
140
164
|
|--------------|----------------|-----------|
|
|
141
|
-
| Refusing to add
|
|
142
|
-
|
|
|
143
|
-
|
|
|
165
|
+
| Refusing to add a VectorData connector because of the "Forbidden: Microsoft.SemanticKernel.*" rule | The rule targets SK orchestration, not VectorData connectors — see the naming-trap section above | Read this standard's exception note before treating any `Microsoft.SemanticKernel.Connectors.*` package as forbidden |
|
|
166
|
+
| **Adding `Microsoft.SemanticKernel.Connectors.PgVector` in a new project** | Caminho morto: `1.74.0-preview` de 2026-03-20, sem versão estável | `CommunityToolkit.VectorData.PgVector` 1.0.1 |
|
|
167
|
+
| **Citar `Microsoft.Extensions.VectorData.Abstractions` 10.8.2 como "a versão atual"** | 10.8.2 é o **piso da dependência** declarado pelo conector; a corrente é 10.9.0 | Ler a versão no pacote da abstração, não no `.nuspec` de quem depende dela |
|
|
168
|
+
| Migrating the working custom pgvector implementation to VectorData "because it's official" | Reescreve uma implementação testada sem ganho funcional. Note que o motivo mudou: já **não** é mais "porque é preview" | Keep `ai-agents-rag-custom-pgvector` as the default; adopt VectorData per the decision matrix |
|
|
169
|
+
| Treating `Microsoft.Extensions.DataIngestion` as production-ready | Continua preview em 2026-09-08 (`10.9.0-preview.1.26411.16`), sem versão estável | Track it for future adoption; do not wire it into a shipped feature today |
|
|
144
170
|
| Importing `Microsoft.SemanticKernel` (the core orchestration package) to "just get the vector store types" | Pulls in the full SK orchestration surface this framework has deliberately moved away from | Import only `Microsoft.Extensions.VectorData.Abstractions` + the specific `*.Connectors.*` package needed |
|
|
145
171
|
|
|
146
172
|
---
|
|
@@ -150,7 +176,9 @@ This maps conceptually onto the existing custom pattern: `IngestionDocumentReade
|
|
|
150
176
|
- [ ] If `Microsoft.SemanticKernel.Connectors.*` appears in a `.csproj`, it is used only for `VectorStoreCollection`/`VectorStore` types — no `Kernel`, `KernelFunction`, or `ChatHistory` usage anywhere in the project.
|
|
151
177
|
- [ ] No plain `Microsoft.SemanticKernel` (core) package reference.
|
|
152
178
|
- [ ] If VectorData was chosen over custom pgvector, the reason is recorded in `decisions.md` per the decision matrix.
|
|
153
|
-
- [ ]
|
|
179
|
+
- [ ] No new `Microsoft.SemanticKernel.Connectors.*` reference — new work uses `CommunityToolkit.VectorData.*`.
|
|
180
|
+
- [ ] If a preview package (`Microsoft.Extensions.DataIngestion`, or any `*-preview` connector) was adopted, `decisions.md` records the preview-acceptance and a revisit-at-GA note.
|
|
181
|
+
- [ ] Every VectorData/ingestion `PackageReference` carries an exact version — these packages are **not** in `framework/ai-pin.json`, so the project's own `decisions.md` (or a comment) states when the version was checked.
|
|
154
182
|
- [ ] Embedding model/dimensions consistent between the `VectorStoreVector(N)` attribute and the chosen embedding model.
|
|
155
183
|
|
|
156
184
|
---
|
|
@@ -164,7 +192,9 @@ This maps conceptually onto the existing custom pattern: `IngestionDocumentReade
|
|
|
164
192
|
- Data ingestion - .NET | Microsoft Learn: https://learn.microsoft.com/en-us/dotnet/ai/conceptual/data-ingestion
|
|
165
193
|
- AI and Vector Data Extensions GA announcement: https://devblogs.microsoft.com/dotnet/ai-vector-data-dotnet-extensions-ga/
|
|
166
194
|
- Introducing Data Ingestion Building Blocks (Preview): https://devblogs.microsoft.com/dotnet/introducing-data-ingestion-building-blocks-preview/
|
|
195
|
+
- Vector stores overview: https://learn.microsoft.com/en-us/dotnet/ai/vector-stores/overview
|
|
196
|
+
- `CommunityToolkit.VectorData.*` — repositório https://github.com/CommunityToolkit/AI (apurado 2026-09-08)
|
|
167
197
|
|
|
168
198
|
---
|
|
169
199
|
|
|
170
|
-
*MORPH-SPEC by Polymorphism Tech — ai-agents/vector-data-extensions.md
|
|
200
|
+
*MORPH-SPEC by Polymorphism Tech — ai-agents/vector-data-extensions.md v2.0 (2026-09-08)*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> **Keywords:** workflow, orchestration, fan-in, fan-out, multi-agent workflow, sequential workflow
|
|
6
6
|
> **Read by Claude in:** plan (only when a genuine fan-in/out or long-running need appears)
|
|
7
7
|
|
|
8
|
-
**Verified against:**
|
|
8
|
+
**Verified against:** Microsoft.Agents.AI 1.20.0 (ai-pin 2026-09-08) + Microsoft.Agents.AI.Workflows 1.20.0, Microsoft.Agents.AI.Workflows.Declarative 1.20.0 e Microsoft.Agents.AI.Declarative `1.20.0-rc1` (**os três fora do pin**; versões apuradas no nuget.org em 2026-09-08). **Verificação documental**, sem cláusula `provado por` — o ai-kit não monta workflows. **A localização dos tipos de workflow foi medida por reflexão em 2026-09-08 e CORRIGE este standard**: eles não estão no pacote base. Last-verified: 2026-09-08.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -43,19 +43,39 @@ Para o critério de HITL/long-running acima, a implementação (`RequestPort`, `
|
|
|
43
43
|
|
|
44
44
|
## Packages
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
> **Correção de 2026-09-08, medida.** A versão anterior deste standard dizia que `AgentWorkflowBuilder`, `WorkflowBuilder` e `InProcessExecution` estavam no pacote base `Microsoft.Agents.AI`. **Não estão.** Varredura dos tipos exportados de `Microsoft.Agents.AI` 1.20.0: **zero** tipos de workflow. Todos os 132 tipos de workflow — `AgentWorkflowBuilder`, `WorkflowBuilder`, `InProcessExecution`, `HandoffWorkflowBuilder`, `GroupChatWorkflowBuilder`, `MagenticWorkflowBuilder`, `CheckpointManager` — vivem em **`Microsoft.Agents.AI.Workflows`**, um pacote **separado**. Seguir o texto antigo dá erro de compilação, não aviso.
|
|
47
47
|
|
|
48
48
|
```xml
|
|
49
|
-
|
|
49
|
+
<!-- Base MAF — no ai-pin.json -->
|
|
50
|
+
<PackageReference Include="Microsoft.Agents.AI" Version="1.20.0" />
|
|
51
|
+
|
|
52
|
+
<!-- Workflows: PACOTE SEPARADO. Estável. Fora do pin; apurado no nuget.org em 2026-09-08. -->
|
|
53
|
+
<PackageReference Include="Microsoft.Agents.AI.Workflows" Version="1.20.0" />
|
|
50
54
|
```
|
|
51
55
|
|
|
52
|
-
Para DI helpers (`AddAIAgent`):
|
|
56
|
+
Para DI helpers (`AddAIAgent`, `AddSequentialWorkflow`):
|
|
53
57
|
|
|
54
58
|
```xml
|
|
55
|
-
|
|
59
|
+
<!-- PRERELEASE: não há versão estável. Fora do pin; apurado em 2026-09-08. -->
|
|
60
|
+
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="1.20.0-preview.260831.1" />
|
|
56
61
|
```
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
### Declarativo: workflow é estável, agente ainda não
|
|
64
|
+
|
|
65
|
+
Os dois costumam ser citados juntos e têm maturidade **diferente**. Apurado no nuget.org em 2026-09-08:
|
|
66
|
+
|
|
67
|
+
| Pacote | Última versão | Estável? |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `Microsoft.Agents.AI.Workflows.Declarative` (workflows em YAML) | **1.20.0** | **Sim** — estáveis desde a 1.9 |
|
|
70
|
+
| `Microsoft.Agents.AI.Declarative` (agentes declarativos) | `1.20.0-rc1` | **Não** — ainda exige `--prerelease` |
|
|
71
|
+
|
|
72
|
+
Ou seja: descrever o **grafo** em YAML é caminho estável; descrever o **agente** em YAML ainda não.
|
|
73
|
+
|
|
74
|
+
### Mudança de comportamento na 1.17
|
|
75
|
+
|
|
76
|
+
A partir da **1.17**, um workflow **falha quando um agente participante retorna erro** — antes o erro podia ser absorvido e o grafo seguia com um resultado parcial. Consequência: um workflow que "sempre funcionou" pode passar a falhar depois do upgrade, e isso é o comportamento **correto**. Trate erro de agente explicitamente (branch de erro no grafo, ou tratamento dentro do executor) em vez de contar com a absorção antiga.
|
|
77
|
+
|
|
78
|
+
> Sem `Microsoft.Extensions.AI 9.x`. Nenhuma faixa flutuante — SDK de cadência semanal com `1.0.*` é o defeito que `ai-agents-setup` §1 proíbe.
|
|
59
79
|
|
|
60
80
|
---
|
|
61
81
|
|
|
@@ -187,4 +207,4 @@ Sempre use `await using` no `StreamingRun` / `Run` — é `IAsyncDisposable`.
|
|
|
187
207
|
|
|
188
208
|
---
|
|
189
209
|
|
|
190
|
-
*MORPH-SPEC by Polymorphism Tech — ai-agents/workflows.md v2.0 (2026-
|
|
210
|
+
*MORPH-SPEC by Polymorphism Tech — ai-agents/workflows.md v2.0 (2026-09-08)*
|
|
@@ -288,4 +288,16 @@ If none are good, regenerate at the same step with the prompt adjusted by the fe
|
|
|
288
288
|
- [ ] Images headed for video framed without faces
|
|
289
289
|
- [ ] Favicon and 1200x630 OG image produced
|
|
290
290
|
|
|
291
|
+
## Boundary: Runtime Generation Is Another Standard
|
|
292
|
+
|
|
293
|
+
This standard is **authoring time**: a designer, an MCP tool, and assets that end up committed in the
|
|
294
|
+
repository. When the **product itself** generates images at runtime — a .NET backend calling a paid
|
|
295
|
+
API per request, with cost, review and provenance — the standard is
|
|
296
|
+
`ai-agents/modalities-image-gen.md`, and the surrounding job/review/labelling pipeline is
|
|
297
|
+
`ai-agents/media-pipeline.md`.
|
|
298
|
+
|
|
299
|
+
The two do not overlap: nothing here talks about paid calls per user, and nothing there repeats the
|
|
300
|
+
brand prompt craft above. The rule that never crosses the boundary is the hard one from
|
|
301
|
+
`ai-agents/media-pipeline.md`: **never generate media inside a conversation turn**.
|
|
302
|
+
|
|
291
303
|
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -110,4 +110,17 @@ TECHNICAL: img2vid with image (start) + endImage (end). No audio. No watermark.
|
|
|
110
110
|
- [ ] Draft at 480p/4s approved before any 1080p render
|
|
111
111
|
- [ ] Frames re-extracted with a bumped cache-bust after the final render
|
|
112
112
|
|
|
113
|
+
## Boundary: Runtime Generation Is Another Standard
|
|
114
|
+
|
|
115
|
+
This standard is **authoring time**: a human driving the seedance MCP in a session, footage that ends
|
|
116
|
+
up committed as a page asset. When the **product itself** generates video at runtime — a .NET worker
|
|
117
|
+
creating a paid task, polling an operation, downloading bytes into its own blob store — the standard
|
|
118
|
+
is `ai-agents/media-video.md` (Veo via `Google.GenAI`, the HTTP-only providers, cost per second, the
|
|
119
|
+
2-day retention), and the surrounding job/review/labelling pipeline is
|
|
120
|
+
`ai-agents/media-pipeline.md`.
|
|
121
|
+
|
|
122
|
+
The face-moderation workaround in Section 3 above is the piece `ai-agents/media-video.md` cites
|
|
123
|
+
rather than repeats. The rule that never crosses the boundary is the hard one from
|
|
124
|
+
`ai-agents/media-pipeline.md`: **never generate media inside a conversation turn**.
|
|
125
|
+
|
|
113
126
|
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> **Keywords:** docker compose, worktree, ports, container_name, POSTGRES_PORT, COMPOSE_PROJECT_NAME, local dev, e2e stack
|
|
6
6
|
> **Load When:** a compose file, a dev-server port, or a worktree stack is being written or debugged
|
|
7
7
|
|
|
8
|
-
**Verified against:** Docker Compose v2 + morph-spec 8.34 (dedicated stack per worktree). Last-verified: 2026-09-
|
|
8
|
+
**Verified against:** Docker Compose v2 + morph-spec 8.34 (dedicated stack per worktree). Last-verified: 2026-09-08.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -36,12 +36,14 @@ Also exported: `COMPOSE_PROJECT_NAME=morph-{feature}` (isolates container, netwo
|
|
|
36
36
|
- ALWAYS give `DATABASE_URL` an in-network default so the stack comes up with no `.env`: `postgresql://postgres:postgres@postgres:5432/${POSTGRES_DB:-app}`
|
|
37
37
|
- ALWAYS read the base URL from the environment in `playwright.config.ts`: `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``
|
|
38
38
|
- NEVER put a cloud connection string (Neon branch etc.) in `.morph/worktree.env` — it is regenerated; credentials go in the gitignored file named by `config.json → e2e.auth.envFile`
|
|
39
|
+
- NEVER put a variable from the port layout table above (nor `PLAYWRIGHT_BASE_URL`) in that credentials file — the harness **ignores** it and says which key it ignored on stderr. Ports come from the allocated block; the file carries credentials. A `.env.e2e` copied from a sibling worktree carries THAT worktree's block, and before the filter existed it silently repointed this stack at the neighbour's postgres
|
|
39
40
|
|
|
40
41
|
## What the harness enforces
|
|
41
42
|
|
|
42
43
|
- Inside a secondary worktree, a compose with a fixed host port or a `container_name` **fails the `verify` e2e node** (`compose-not-isolable`) — Gate 3 cannot pass on a stack that cannot run beside its siblings. At the primary root the same finding is a warning.
|
|
43
44
|
- `morph-spec finish` tears the stack down **with volumes** (`--keep-volumes` opts out) and deletes the freshness stamp; `morph-spec worktree remove` tears it down without volumes (the feature is still open).
|
|
44
45
|
- Two worktrees never share `POSTGRES_PORT`: the block is allocated first-free-index per feature and released only when the worktree is removed.
|
|
46
|
+
- The credentials env file is read **after** the block but cannot outrank it. All four surfaces (`e2e up`, the `verify` e2e node, the teardown, `morph-spec env`) build their environment through the same `buildComposeEnv`, which drops the layout keys coming from that file and names them on **stderr** — stdout stays eval-safe for `eval "$(morph-spec env)"`. With no block allocated (outside a worktree) nothing is filtered: there the file is the only port source.
|
|
45
47
|
|
|
46
48
|
## Minimal compose skeleton
|
|
47
49
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<templateSet group="MORPH Templates">
|
|
2
|
+
<template name="morph-pascal" value="{{pascalCase $FEATURE_NAME$}}" description="Convert to PascalCase (UserAuth)" toReformat="false" toShortenFQNames="true">
|
|
3
|
+
<variable name="FEATURE_NAME" expression="" defaultValue=""FEATURE_NAME"" alwaysStopAt="true" />
|
|
4
|
+
<context>
|
|
5
|
+
<option name="OTHER" value="true" />
|
|
6
|
+
</context>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<template name="morph-camel" value="{{camelCase $FEATURE_NAME$}}" description="Convert to camelCase (userAuth)" toReformat="false" toShortenFQNames="true">
|
|
10
|
+
<variable name="FEATURE_NAME" expression="" defaultValue=""FEATURE_NAME"" alwaysStopAt="true" />
|
|
11
|
+
<context>
|
|
12
|
+
<option name="OTHER" value="true" />
|
|
13
|
+
</context>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<template name="morph-snake" value="{{snakeCase $FEATURE_NAME$}}" description="Convert to snake_case (user_auth)" toReformat="false" toShortenFQNames="true">
|
|
17
|
+
<variable name="FEATURE_NAME" expression="" defaultValue=""FEATURE_NAME"" alwaysStopAt="true" />
|
|
18
|
+
<context>
|
|
19
|
+
<option name="OTHER" value="true" />
|
|
20
|
+
</context>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<template name="morph-title" value="{{titleCase $FEATURE_NAME$}}" description="Convert to Title Case (User Auth)" toReformat="false" toShortenFQNames="true">
|
|
24
|
+
<variable name="FEATURE_NAME" expression="" defaultValue=""FEATURE_NAME"" alwaysStopAt="true" />
|
|
25
|
+
<context>
|
|
26
|
+
<option name="OTHER" value="true" />
|
|
27
|
+
</context>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<template name="morph-kebab" value="{{kebabCase $FEATURE_NAME$}}" description="Convert to kebab-case (user-auth)" toReformat="false" toShortenFQNames="true">
|
|
31
|
+
<variable name="FEATURE_NAME" expression="" defaultValue=""FEATURE_NAME"" alwaysStopAt="true" />
|
|
32
|
+
<context>
|
|
33
|
+
<option name="OTHER" value="true" />
|
|
34
|
+
</context>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<template name="morph-if" value="{{#if $CONDITION$}} $END$ {{/if}}" description="Handlebars if block" toReformat="false" toShortenFQNames="true">
|
|
38
|
+
<variable name="CONDITION" expression="" defaultValue=""condition"" alwaysStopAt="true" />
|
|
39
|
+
<context>
|
|
40
|
+
<option name="OTHER" value="true" />
|
|
41
|
+
</context>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<template name="morph-if-else" value="{{#if $CONDITION$}} $TRUE_BRANCH$ {{else}} $FALSE_BRANCH$ {{/if}}" description="Handlebars if-else block" toReformat="false" toShortenFQNames="true">
|
|
45
|
+
<variable name="CONDITION" expression="" defaultValue=""condition"" alwaysStopAt="true" />
|
|
46
|
+
<variable name="TRUE_BRANCH" expression="" defaultValue="""" alwaysStopAt="true" />
|
|
47
|
+
<variable name="FALSE_BRANCH" expression="" defaultValue="""" alwaysStopAt="true" />
|
|
48
|
+
<context>
|
|
49
|
+
<option name="OTHER" value="true" />
|
|
50
|
+
</context>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<template name="morph-each" value="{{#each $ITEMS$}} {{this.$PROPERTY$}} {{/each}}" description="Handlebars each loop" toReformat="false" toShortenFQNames="true">
|
|
54
|
+
<variable name="ITEMS" expression="" defaultValue=""items"" alwaysStopAt="true" />
|
|
55
|
+
<variable name="PROPERTY" expression="" defaultValue=""name"" alwaysStopAt="true" />
|
|
56
|
+
<context>
|
|
57
|
+
<option name="OTHER" value="true" />
|
|
58
|
+
</context>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<template name="morph-service" value="namespace {{NAMESPACE}}.Application.Features.{{pascalCase FEATURE_NAME}}.Services; public class {{pascalCase FEATURE_NAME}}Service( I{{pascalCase FEATURE_NAME}}Repository repository, ILogger<{{pascalCase FEATURE_NAME}}Service> logger) : I{{pascalCase FEATURE_NAME}}Service { public async Task<{{pascalCase FEATURE_NAME}}Dto?> GetByIdAsync(int id, CancellationToken cancellationToken = default) { $END$ } }" description="MORPH .NET Service class template" toReformat="false" toShortenFQNames="true">
|
|
62
|
+
<context>
|
|
63
|
+
<option name="C_SHARP" value="true" />
|
|
64
|
+
</context>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<template name="morph-repository" value="public class {{pascalCase FEATURE_NAME}}Repository(AppDbContext context) : I{{pascalCase FEATURE_NAME}}Repository { private readonly DbSet<{{pascalCase FEATURE_NAME}}> _dbSet = context.Set<{{pascalCase FEATURE_NAME}}>(); public async Task<{{pascalCase FEATURE_NAME}}?> GetByIdAsync(int id, CancellationToken cancellationToken = default) { $END$ } }" description="MORPH .NET Repository class template" toReformat="false" toShortenFQNames="true">
|
|
68
|
+
<context>
|
|
69
|
+
<option name="C_SHARP" value="true" />
|
|
70
|
+
</context>
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<template name="morph-component" value="@page "/{{kebabCase FEATURE_NAME}}" @inject I{{pascalCase FEATURE_NAME}}Service {{pascalCase FEATURE_NAME}}Service @inject ILogger<{{pascalCase FEATURE_NAME}}Page> Logger <PageTitle>{{pascalCase FEATURE_NAME}}</PageTitle> <div class="container-fluid"> $END$ </div> @code { }" description="MORPH Blazor component template" toReformat="false" toShortenFQNames="true">
|
|
74
|
+
<context>
|
|
75
|
+
<option name="HTML" value="true" />
|
|
76
|
+
</context>
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<template name="morph-migration" value="public partial class Add{{pascalCase FEATURE_NAME}} : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "{{pascalCase FEATURE_NAME}}s", columns: table => new { Id = table.Column<int>(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), $END$ }, constraints: table => { table.PrimaryKey("PK_{{pascalCase FEATURE_NAME}}s", x => x.Id); }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable(name: "{{pascalCase FEATURE_NAME}}s"); } }" description="MORPH EF Core migration template" toReformat="false" toShortenFQNames="true">
|
|
80
|
+
<context>
|
|
81
|
+
<option name="C_SHARP" value="true" />
|
|
82
|
+
</context>
|
|
83
|
+
</template>
|
|
84
|
+
|
|
85
|
+
<template name="morph-ts-contract" value="export interface {{pascalCase FEATURE_NAME}} { id: number; $FIELD1$ } export interface Create{{pascalCase FEATURE_NAME}}Request { $FIELD2$ } export interface Update{{pascalCase FEATURE_NAME}}Request { $END$ }" description="MORPH TypeScript contract template" toReformat="false" toShortenFQNames="true">
|
|
86
|
+
<variable name="FIELD1" expression="" defaultValue="""" alwaysStopAt="true" />
|
|
87
|
+
<variable name="FIELD2" expression="" defaultValue="""" alwaysStopAt="true" />
|
|
88
|
+
<context>
|
|
89
|
+
<option name="TypeScript" value="true" />
|
|
90
|
+
</context>
|
|
91
|
+
</template>
|
|
92
|
+
</templateSet>
|