@polymorphism-tech/morph-spec 8.34.2 → 8.35.1
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 +22 -5
- 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 +236 -11
- 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/core/worktree-env-inject.js +43 -0
- 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/payload-utils.js +15 -2
- 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 +148 -6
- package/src/commands/project/update.js +469 -153
- package/src/commands/project/worktree.js +76 -4
- 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 +379 -24
- 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/git/pr-files.js +56 -0
- 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,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linux Runner — run the declared test nodes inside a Linux container.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS MODULE EXISTS
|
|
5
|
+
*
|
|
6
|
+
* Defect F35: 3.057 tests green on Windows, ten failures on Linux. The ten
|
|
7
|
+
* were `Link=` casing and `Uri.TryCreate` — defects of CASE, invisible on a
|
|
8
|
+
* case-insensitive filesystem. The CI has had an ubuntu leg since 8.24.2 and
|
|
9
|
+
* F35 still reached the field, because the CI answers minutes-to-hours after
|
|
10
|
+
* the loop has moved on. `--linux` is the desk-side complement: the same
|
|
11
|
+
* suites, on Linux, inside the loop.
|
|
12
|
+
*
|
|
13
|
+
* WHY THE TREE IS COPIED AND NOT MOUNTED (D5) — the load-bearing decision
|
|
14
|
+
*
|
|
15
|
+
* Docker Desktop's bind mount on Windows crosses a 9p / gRPC-FUSE translation
|
|
16
|
+
* layer that is **case-insensitive**. Running the suite on top of that mount
|
|
17
|
+
* gives back exactly the green Windows already gave: the flag would exist and
|
|
18
|
+
* prove nothing about the one class of defect it was built for. So the host
|
|
19
|
+
* tree is mounted READ-ONLY at `/src` purely as the source of a copy, the copy
|
|
20
|
+
* lands on the container's own filesystem (the overlayfs) at `/work`, and every
|
|
21
|
+
* node runs from `/work/{cwd}`. Nothing ever executes out of `/src`.
|
|
22
|
+
*
|
|
23
|
+
* The copy is `tar | tar` rather than a literal `cp -r` because `cp` has no
|
|
24
|
+
* portable exclusion: `node_modules`, `bin`, `obj`, `.git` and the worktree
|
|
25
|
+
* container directories must not travel (a worktree is ANOTHER feature's
|
|
26
|
+
* checkout — copying it doubles the clock and reports on code outside the tree
|
|
27
|
+
* under judgement, the same reason `collectDotnetTestProjects` excludes them).
|
|
28
|
+
* The effect is the one the issue asked for: the executed tree lives in the
|
|
29
|
+
* container.
|
|
30
|
+
*
|
|
31
|
+
* WHY `exec` IS INJECTED
|
|
32
|
+
*
|
|
33
|
+
* The CI has no guaranteed Docker daemon and no .NET at all. Every test of
|
|
34
|
+
* this module drives a recorded `exec` and asserts the command line that WOULD
|
|
35
|
+
* have run — a verifier whose own tests need a container is a verifier that
|
|
36
|
+
* stops being tested.
|
|
37
|
+
*
|
|
38
|
+
* @module linux-runner
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import { resolve } from 'path';
|
|
42
|
+
|
|
43
|
+
import { defaultExec, isDockerAvailable } from '../../../framework/hooks/shared/e2e-check.js';
|
|
44
|
+
import { WORKTREES_DIR, LEGACY_WORKTREES_DIR } from '../worktree/dirs.js';
|
|
45
|
+
|
|
46
|
+
/** The SDK image `--linux` runs in by default (spec §5.1); overridable per run and per node. */
|
|
47
|
+
export const LINUX_DEFAULT_IMAGE = 'mcr.microsoft.com/dotnet/sdk:10.0';
|
|
48
|
+
|
|
49
|
+
/** Where the host tree is mounted (read-only) and where the copy is executed from. */
|
|
50
|
+
const SRC_MOUNT = '/src';
|
|
51
|
+
const WORK_DIR = '/work';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Markers that fence one node's output inside the single container's stdout.
|
|
55
|
+
* Deliberately noisy: a delimiter that could occur in real test output would
|
|
56
|
+
* split a run at the wrong line and attribute failures to the wrong suite.
|
|
57
|
+
*/
|
|
58
|
+
export const NODE_START = '@@MORPH-NODE-START@@';
|
|
59
|
+
export const NODE_EXIT = '@@MORPH-NODE-EXIT@@';
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* What never travels into the container.
|
|
63
|
+
*
|
|
64
|
+
* The two worktree container names are IMPORTED from `dirs.js`, never retyped:
|
|
65
|
+
* duplicating that string is the documented way the C1 bug comes back. They are
|
|
66
|
+
* anchored at the root (`./name`) because they are root-level containers; the
|
|
67
|
+
* build artifacts are unanchored because they nest anywhere in a tree.
|
|
68
|
+
*/
|
|
69
|
+
export const COPY_EXCLUDES = [
|
|
70
|
+
'node_modules',
|
|
71
|
+
'bin',
|
|
72
|
+
'obj',
|
|
73
|
+
'.git',
|
|
74
|
+
`./${WORKTREES_DIR}`,
|
|
75
|
+
`./${LEGACY_WORKTREES_DIR}`,
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
/** Single-quote a POSIX shell word — the container's shell is always sh. */
|
|
79
|
+
function shq(value) {
|
|
80
|
+
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Why `--linux` cannot run, or null when it can.
|
|
85
|
+
*
|
|
86
|
+
* A missing daemon is a USAGE ERROR (exit 2), never a skipped node. A skip
|
|
87
|
+
* would mean "we could not check on Linux" reading as green — which is F35
|
|
88
|
+
* itself, restated as a feature.
|
|
89
|
+
*
|
|
90
|
+
* @param {{ projectPath: string, skipTests: boolean, exec?: Function }} params
|
|
91
|
+
* @returns {string|null}
|
|
92
|
+
*/
|
|
93
|
+
export function checkLinuxPreconditions({ projectPath, skipTests, exec = defaultExec }) {
|
|
94
|
+
if (skipTests) {
|
|
95
|
+
return '--linux com --skip-tests se anulam: a flag existe para RODAR a suíte em Linux';
|
|
96
|
+
}
|
|
97
|
+
if (!isDockerAvailable(projectPath, exec)) {
|
|
98
|
+
return '--linux exige Docker e o daemon não respondeu — '
|
|
99
|
+
+ 'rode onde ele exista (nunca reportamos "não deu para checar no Linux" como verde)';
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Which nodes can actually run inside the container, and why the others cannot.
|
|
106
|
+
*
|
|
107
|
+
* An `e2e: true` node needs the application stack up; bringing docker up INSIDE
|
|
108
|
+
* a container is out of scope, so it is refused by name rather than silently
|
|
109
|
+
* dropped — a suite that disappears from the report is the defect this whole
|
|
110
|
+
* feature exists to close.
|
|
111
|
+
*/
|
|
112
|
+
function partitionNodes(nodes) {
|
|
113
|
+
const runnable = [];
|
|
114
|
+
const refused = [];
|
|
115
|
+
for (const node of nodes) {
|
|
116
|
+
if (node.e2e) {
|
|
117
|
+
refused.push({
|
|
118
|
+
id: node.id,
|
|
119
|
+
skipped: true,
|
|
120
|
+
reason: 'nó e2e não roda dentro do container do --linux (docker-em-docker fora de escopo)',
|
|
121
|
+
output: '',
|
|
122
|
+
exitCode: null,
|
|
123
|
+
durationMs: 0,
|
|
124
|
+
});
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
runnable.push(node);
|
|
128
|
+
}
|
|
129
|
+
return { runnable, refused };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The shell script the container executes: copy first, then every node.
|
|
134
|
+
*
|
|
135
|
+
* Order is the contract — the copy precedes the first command, and every
|
|
136
|
+
* command is `cd`-ed into `/work/{cwd}`. `set -e` is deliberately NOT used
|
|
137
|
+
* around the nodes: one red suite must not cancel the ones after it (the same
|
|
138
|
+
* rule the local loop follows for a timeout).
|
|
139
|
+
*
|
|
140
|
+
* @param {{ nodes: Array<import('./test-nodes.js').TestNode> }} params
|
|
141
|
+
* @returns {string}
|
|
142
|
+
*/
|
|
143
|
+
export function buildContainerScript({ nodes }) {
|
|
144
|
+
const excludes = COPY_EXCLUDES.map((e) => `--exclude=${e}`).join(' ');
|
|
145
|
+
const lines = [
|
|
146
|
+
'set -u',
|
|
147
|
+
`mkdir -p ${WORK_DIR}`,
|
|
148
|
+
// The copy that makes this flag mean something: after it, the executed
|
|
149
|
+
// files live on the container's own filesystem, which is case-SENSITIVE.
|
|
150
|
+
`tar -C ${SRC_MOUNT} ${excludes} -cf - . | tar -C ${WORK_DIR} -xf -`,
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
for (const node of nodes) {
|
|
154
|
+
const dir = `${WORK_DIR}/${node.cwd || '.'}`;
|
|
155
|
+
// The clock is read into a variable BEFORE the marker is echoed, and the
|
|
156
|
+
// exit code into another one: a `$(date)` sharing an echo with `$?` is one
|
|
157
|
+
// shell quirk away from reporting the timestamp's exit code as the suite's.
|
|
158
|
+
// An image without `date` degrades to an UNKNOWN duration, never a zero.
|
|
159
|
+
lines.push(`__ms=$(date +%s 2>/dev/null); echo "${NODE_START} ${node.id} $__ms"`);
|
|
160
|
+
lines.push(`cd ${shq(dir)} && ${node.command}`);
|
|
161
|
+
// `$?` of the compound above: a cd that fails is a failure too, and one
|
|
162
|
+
// that reported success would run the suite from the wrong directory.
|
|
163
|
+
lines.push(`__code=$?; __me=$(date +%s 2>/dev/null); echo "${NODE_EXIT} ${node.id} $__code $__me"`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return lines.join('\n');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The exact `docker` argv. Split out from the execution so a test can assert
|
|
171
|
+
* the command line without a daemon — this is the canary that keeps the
|
|
172
|
+
* read-only `/src` and the absence of a writable `/work` mount honest.
|
|
173
|
+
*
|
|
174
|
+
* @param {{ projectPath: string, image: string, script: string }} params
|
|
175
|
+
* @returns {string[]}
|
|
176
|
+
*/
|
|
177
|
+
export function buildLinuxArgv({ projectPath, image, script }) {
|
|
178
|
+
return [
|
|
179
|
+
'run', '--rm',
|
|
180
|
+
// Read-only, and mounted at /src: the SOURCE of the copy, never the tree
|
|
181
|
+
// the tests run from. See the module docs for why that distinction is the
|
|
182
|
+
// entire point of the flag.
|
|
183
|
+
//
|
|
184
|
+
// Forward slashes even on Windows: `C:\a\b` and `C:/a/b` are both accepted
|
|
185
|
+
// by Docker Desktop, but the backslash form is the one that breaks first
|
|
186
|
+
// when a path is re-parsed downstream, and the mount spec is already
|
|
187
|
+
// colon-delimited.
|
|
188
|
+
'-v', `${resolve(projectPath).replace(/\\/g, '/')}:${SRC_MOUNT}:ro`,
|
|
189
|
+
'-w', WORK_DIR,
|
|
190
|
+
image,
|
|
191
|
+
'sh', '-c', script,
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Split the container's stdout back into one result per node.
|
|
197
|
+
*
|
|
198
|
+
* A node whose exit marker never arrived did not pass: the container died
|
|
199
|
+
* mid-run (image pull, OOM, killed clock). Reporting it as anything but a
|
|
200
|
+
* failure would be a green verdict over a suite nobody observed.
|
|
201
|
+
*/
|
|
202
|
+
function splitByMarkers(output, nodes) {
|
|
203
|
+
const text = String(output || '');
|
|
204
|
+
const escape = (v) => String(v).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
205
|
+
return nodes.map((node) => {
|
|
206
|
+
const startRe = new RegExp(`${escape(NODE_START)} ${escape(node.id)}(?: (\\d+))?`);
|
|
207
|
+
const exitRe = new RegExp(`${escape(NODE_EXIT)} ${escape(node.id)} (-?\\d+)(?: (\\d+))?`);
|
|
208
|
+
const startMatch = startRe.exec(text);
|
|
209
|
+
if (!startMatch) {
|
|
210
|
+
return {
|
|
211
|
+
id: node.id,
|
|
212
|
+
exitCode: null,
|
|
213
|
+
durationMs: null,
|
|
214
|
+
output: '',
|
|
215
|
+
reason: 'o container terminou antes deste nó — nenhum veredito foi observado',
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const rest = text.slice(startMatch.index + startMatch[0].length);
|
|
219
|
+
const exitMatch = exitRe.exec(rest);
|
|
220
|
+
const body = (exitMatch ? rest.slice(0, exitMatch.index) : rest).replace(/^\r?\n/, '').trimEnd();
|
|
221
|
+
if (!exitMatch) {
|
|
222
|
+
return {
|
|
223
|
+
id: node.id,
|
|
224
|
+
exitCode: null,
|
|
225
|
+
durationMs: null,
|
|
226
|
+
output: body,
|
|
227
|
+
reason: 'o container terminou sem reportar o código de saída deste nó',
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// **null is UNKNOWN, never 0** — an image without `date` did not run the
|
|
231
|
+
// suite in zero milliseconds.
|
|
232
|
+
const durationMs = startMatch[1] && exitMatch[2]
|
|
233
|
+
? (Number(exitMatch[2]) - Number(startMatch[1])) * 1000
|
|
234
|
+
: null;
|
|
235
|
+
return { id: node.id, exitCode: Number(exitMatch[1]), durationMs, output: body, reason: null };
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Run every runnable node inside ONE container and return the raw per-node
|
|
241
|
+
* results — exit code and output, nothing judged.
|
|
242
|
+
*
|
|
243
|
+
* Judgement (count comparison, baseline drop, feedback lines) stays in
|
|
244
|
+
* verify-runner beside the local path, so a container run and a host run are
|
|
245
|
+
* decided by the SAME code. A second copy of that rule is how two environments
|
|
246
|
+
* start disagreeing about the same suite.
|
|
247
|
+
*
|
|
248
|
+
* @param {Object} params
|
|
249
|
+
* @param {string} params.projectPath - Project root (the copy source)
|
|
250
|
+
* @param {Array<import('./test-nodes.js').TestNode>} params.nodes - Nodes to run
|
|
251
|
+
* @param {string} [params.image] - Image override (`--linux-image`)
|
|
252
|
+
* @param {number} [params.timeout] - Ceiling for the whole container, in ms
|
|
253
|
+
* @param {Function} [params.exec] - Injected executor (defaults to e2e-check's defaultExec)
|
|
254
|
+
* @returns {{ results: Array<{id: string, exitCode: number|null, output: string, reason: string|null, skipped?: boolean}>,
|
|
255
|
+
* environment: {kind: string, image: string}, argv: string[], script: string, containerCode: number|null }}
|
|
256
|
+
*/
|
|
257
|
+
export function runLinuxSuite({ projectPath, nodes, image, timeout, exec = defaultExec }) {
|
|
258
|
+
const { runnable, refused } = partitionNodes(nodes);
|
|
259
|
+
// Precedence: explicit override > a node that declares its own image > the
|
|
260
|
+
// default. A per-node image only decides the single container everyone shares
|
|
261
|
+
// when it is the only one asked for — two images would mean two copies of the
|
|
262
|
+
// tree and two clocks, which is not what this flag is for.
|
|
263
|
+
const declared = runnable.map((n) => n.linuxImage).filter(Boolean);
|
|
264
|
+
const resolvedImage = image || declared[0] || LINUX_DEFAULT_IMAGE;
|
|
265
|
+
const environment = { kind: 'linux-container', image: resolvedImage };
|
|
266
|
+
|
|
267
|
+
if (runnable.length === 0) {
|
|
268
|
+
return { results: refused, environment, argv: [], script: '', containerCode: null };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const script = buildContainerScript({ nodes: runnable });
|
|
272
|
+
const argv = buildLinuxArgv({ projectPath, image: resolvedImage, script });
|
|
273
|
+
const run = exec('docker', argv, { cwd: projectPath, timeout });
|
|
274
|
+
|
|
275
|
+
const results = splitByMarkers(run.output, runnable).map((r) =>
|
|
276
|
+
r.exitCode === null && !r.reason
|
|
277
|
+
? { ...r, reason: 'o container não reportou este nó' }
|
|
278
|
+
: r
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
// A container that never produced a single marker failed as a whole (a pull
|
|
282
|
+
// failure, say). The reason has to name the container, or the reader goes
|
|
283
|
+
// hunting through a test log for a suite that never started.
|
|
284
|
+
const nothingRan = results.every((r) => r.exitCode === null);
|
|
285
|
+
const enriched = results.map((r) =>
|
|
286
|
+
r.exitCode === null && nothingRan
|
|
287
|
+
? { ...r, reason: `${r.reason} (container saiu com ${run.code}): ${tail(run.output)}` }
|
|
288
|
+
: r
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
return { results: [...enriched, ...refused], environment, argv, script, containerCode: run.code };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Last few lines of the container output — enough to name a pull failure. */
|
|
295
|
+
function tail(output, lines = 5) {
|
|
296
|
+
return String(output || '').split('\n').slice(-lines).join('\n').trim();
|
|
297
|
+
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Task classifier — identifies test/validation and infrastructure tasks by title.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const TEST_TASK_PATTERN = /\b(tests?|testing|specs?|coverage|e2e|unit|integration|integra[cç][aã]o|valida[cç][aã]o|cobertura|testes?)\b/i;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Returns true if the task title indicates a testing or validation task.
|
|
9
|
-
*
|
|
10
|
-
* @param {string} taskTitle
|
|
11
|
-
* @returns {boolean}
|
|
12
|
-
*/
|
|
13
|
-
export function isTestTask(taskTitle) {
|
|
14
|
-
if (!taskTitle) return false;
|
|
15
|
-
return TEST_TASK_PATTERN.test(taskTitle);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const INFRA_TASK_PATTERN = /\b(infrastructure|infra|cleanup|migration|migra[cç][aã]o|config|setup|ci\/cd|devops|deploy|docker|packages?|dependencies|tags)\b/i;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Returns true if the task title indicates an infrastructure/cleanup/migration task.
|
|
22
|
-
* Used to skip contract validation and suppress breaking change warnings.
|
|
23
|
-
*
|
|
24
|
-
* @param {string} taskTitle
|
|
25
|
-
* @returns {boolean}
|
|
26
|
-
*/
|
|
27
|
-
export function isInfrastructureTask(taskTitle) {
|
|
28
|
-
if (!taskTitle) return false;
|
|
29
|
-
return INFRA_TASK_PATTERN.test(taskTitle);
|
|
30
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Task classifier — identifies test/validation and infrastructure tasks by title.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const TEST_TASK_PATTERN = /\b(tests?|testing|specs?|coverage|e2e|unit|integration|integra[cç][aã]o|valida[cç][aã]o|cobertura|testes?)\b/i;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns true if the task title indicates a testing or validation task.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} taskTitle
|
|
11
|
+
* @returns {boolean}
|
|
12
|
+
*/
|
|
13
|
+
export function isTestTask(taskTitle) {
|
|
14
|
+
if (!taskTitle) return false;
|
|
15
|
+
return TEST_TASK_PATTERN.test(taskTitle);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const INFRA_TASK_PATTERN = /\b(infrastructure|infra|cleanup|migration|migra[cç][aã]o|config|setup|ci\/cd|devops|deploy|docker|packages?|dependencies|tags)\b/i;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if the task title indicates an infrastructure/cleanup/migration task.
|
|
22
|
+
* Used to skip contract validation and suppress breaking change warnings.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} taskTitle
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
*/
|
|
27
|
+
export function isInfrastructureTask(taskTitle) {
|
|
28
|
+
if (!taskTitle) return false;
|
|
29
|
+
return INFRA_TASK_PATTERN.test(taskTitle);
|
|
30
|
+
}
|