@polymorphism-tech/morph-spec 3.2.0 → 4.3.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/README.md +1 -14
- package/bin/detect-agents.js +1 -1
- package/bin/morph-spec.js +403 -40
- package/bin/validate.js +5 -5
- package/docs/getting-started.md +0 -5
- package/docs/next-generation/AGENTS.md +521 -0
- package/docs/next-generation/ANALYSIS.md +555 -0
- package/docs/next-generation/ARCHITECTURE.md +436 -0
- package/docs/next-generation/CONTEXT-OPTIMIZATION.md +267 -0
- package/docs/next-generation/EXECUTION-FLOW.md +274 -0
- package/docs/next-generation/FEATURES.md +688 -0
- package/docs/next-generation/META-PROMPTS.md +235 -0
- package/docs/next-generation/MIGRATION-GUIDE.md +253 -0
- package/docs/next-generation/README.md +231 -0
- package/docs/next-generation/ROADMAP.md +801 -0
- package/docs/next-generation/THREAD-MANAGEMENT.md +240 -0
- package/docs/validation-checklist.md +0 -1
- package/package.json +5 -5
- package/src/commands/agents/agents-fuse.js +96 -0
- package/src/commands/agents/index.js +4 -0
- package/src/commands/agents/micro-agent.js +112 -0
- package/src/commands/{spawn-team.js → agents/spawn-team.js} +237 -172
- package/src/commands/agents/squad-template.js +146 -0
- package/src/commands/analytics/analytics.js +176 -0
- package/src/commands/context/context-prime.js +63 -0
- package/src/commands/context/core-four.js +54 -0
- package/src/commands/{create-story.js → feature/create-story.js} +357 -354
- package/src/commands/feature/index.js +6 -0
- package/src/commands/{shard-spec.js → feature/shard-spec.js} +2 -2
- package/src/commands/{sprint-status.js → feature/sprint-status.js} +1 -1
- package/src/commands/{generate-context.js → generation/generate-context.js} +40 -40
- package/src/commands/{generate.js → generation/generate.js} +4 -4
- package/src/commands/generation/index.js +5 -0
- package/src/commands/index.js +16 -0
- package/src/commands/{capture-pattern.js → learning/capture-pattern.js} +121 -121
- package/src/commands/learning/index.js +5 -0
- package/src/commands/mcp/mcp.js +102 -0
- package/src/commands/{detect-agents.js → project/detect-agents.js} +178 -178
- package/src/commands/project/detect-workflow.js +174 -0
- package/src/commands/{detect.js → project/detect.js} +104 -104
- package/src/commands/{doctor.js → project/doctor.js} +221 -4
- package/src/commands/project/index.js +10 -0
- package/src/commands/{init.js → project/init.js} +305 -295
- package/src/commands/{sync.js → project/sync.js} +167 -167
- package/src/commands/{update.js → project/update.js} +240 -240
- package/src/commands/{advance-phase.js → state/advance-phase.js} +101 -25
- package/src/commands/{approve.js → state/approve.js} +221 -221
- package/src/commands/state/index.js +8 -0
- package/src/commands/{rollback-phase.js → state/rollback-phase.js} +185 -185
- package/src/commands/{state.js → state/state.js} +334 -334
- package/src/commands/{validate-phase.js → state/validate-phase.js} +221 -221
- package/src/commands/tasks/index.js +4 -0
- package/src/commands/{task.js → tasks/task.js} +78 -78
- package/src/commands/templates/index.js +8 -0
- package/src/commands/templates/template-customize.js +101 -0
- package/src/commands/templates/template-list.js +128 -0
- package/src/commands/templates/template-render.js +174 -0
- package/src/commands/templates/template-show.js +131 -0
- package/src/commands/templates/template-validate.js +91 -0
- package/src/commands/threads/thread-template.js +103 -0
- package/src/commands/threads/threads.js +261 -0
- package/src/commands/trust/trust.js +205 -0
- package/src/commands/utils/index.js +7 -0
- package/src/commands/{session-summary.js → utils/session-summary.js} +291 -291
- package/src/commands/{troubleshoot.js → utils/troubleshoot.js} +222 -222
- package/src/commands/{analyze-blazor-concurrency.js → validation/analyze-blazor-concurrency.js} +193 -193
- package/src/commands/validation/index.js +8 -0
- package/src/commands/{lint-fluent.js → validation/lint-fluent.js} +352 -352
- package/src/commands/{validate-blazor-state.js → validation/validate-blazor-state.js} +210 -210
- package/src/commands/{validate-blazor.js → validation/validate-blazor.js} +156 -156
- package/src/commands/{validate-css.js → validation/validate-css.js} +84 -84
- package/src/core/index.js +10 -0
- package/src/{orchestrator.js → core/orchestrator.js} +8 -8
- package/src/core/registry/command-registry.js +302 -0
- package/src/core/registry/index.js +8 -0
- package/src/core/registry/validator-registry.js +204 -0
- package/src/core/state/index.js +8 -0
- package/src/{lib → core/state}/phase-state-machine.js +214 -214
- package/src/{lib → core/state}/state-manager.js +588 -534
- package/src/core/templates/index.js +9 -0
- package/src/core/templates/template-registry.js +335 -0
- package/src/core/templates/template-renderer.js +477 -0
- package/src/core/templates/template-validator.js +296 -0
- package/src/core/workflows/index.js +7 -0
- package/src/core/workflows/workflow-detector.js +452 -0
- package/src/lib/agents/micro-agent-factory.js +161 -0
- package/src/lib/{complexity-analyzer.js → analysis/complexity-analyzer.js} +441 -441
- package/src/lib/analysis/index.js +7 -0
- package/src/lib/analytics/analytics-engine.js +345 -0
- package/src/lib/{checkpoint-hooks.js → checkpoints/checkpoint-hooks.js} +35 -0
- package/src/lib/checkpoints/index.js +7 -0
- package/src/lib/context/context-bundler.js +240 -0
- package/src/lib/context/context-optimizer.js +212 -0
- package/src/lib/context/context-tracker.js +273 -0
- package/src/lib/context/core-four-tracker.js +201 -0
- package/src/lib/context/mcp-optimizer.js +200 -0
- package/src/lib/detectors/config-detector.js +223 -223
- package/src/lib/detectors/conversation-analyzer.js +163 -163
- package/src/lib/{design-system-detector.js → detectors/design-system-detector.js} +187 -187
- package/src/lib/detectors/index.js +87 -84
- package/src/lib/detectors/standards-generator.js +275 -275
- package/src/lib/detectors/structure-detector.js +245 -245
- package/src/lib/execution/fusion-executor.js +304 -0
- package/src/lib/execution/parallel-executor.js +270 -0
- package/src/lib/{context-generator.js → generators/context-generator.js} +526 -516
- package/src/lib/generators/index.js +10 -0
- package/src/lib/{metadata-extractor.js → generators/metadata-extractor.js} +387 -380
- package/src/lib/{recap-generator.js → generators/recap-generator.js} +205 -205
- package/src/lib/hooks/hook-executor.js +169 -0
- package/src/lib/hooks/stop-hook-executor.js +286 -0
- package/src/lib/hops/hop-composer.js +221 -0
- package/src/lib/learning/index.js +7 -0
- package/src/lib/orchestration/index.js +7 -0
- package/src/lib/{team-orchestrator.js → orchestration/team-orchestrator.js} +323 -323
- package/src/lib/stacks/index.js +7 -0
- package/src/lib/{stack-resolver.js → stacks/stack-resolver.js} +180 -148
- package/src/lib/standards/index.js +7 -0
- package/src/lib/{standards-context-injector.js → standards/standards-context-injector.js} +298 -288
- package/src/lib/threads/thread-coordinator.js +238 -0
- package/src/lib/threads/thread-manager.js +317 -0
- package/src/lib/tracking/artifact-trail.js +202 -0
- package/src/lib/troubleshooting/index.js +8 -0
- package/src/lib/{troubleshoot-grep.js → troubleshooting/troubleshoot-grep.js} +204 -204
- package/src/lib/{troubleshoot-index.js → troubleshooting/troubleshoot-index.js} +144 -144
- package/src/lib/trust/trust-manager.js +269 -0
- package/src/lib/validators/{architecture-validator.js → architecture/architecture-validator.js} +8 -8
- package/src/lib/validators/architecture/index.js +7 -0
- package/src/lib/{blazor-concurrency-analyzer.js → validators/blazor/blazor-concurrency-analyzer.js} +277 -288
- package/src/lib/{blazor-state-validator.js → validators/blazor/blazor-state-validator.js} +279 -291
- package/src/lib/{blazor-validator.js → validators/blazor/blazor-validator.js} +369 -374
- package/src/lib/validators/blazor/index.js +9 -0
- package/src/lib/validators/{content-validator.js → content/content-validator.js} +351 -351
- package/src/lib/validators/content/index.js +7 -0
- package/src/lib/validators/{contract-compliance-validator.js → contracts/contract-compliance-validator.js} +273 -273
- package/src/lib/validators/contracts/index.js +7 -0
- package/src/lib/{css-validator.js → validators/css/css-validator.js} +352 -352
- package/src/lib/validators/css/index.js +7 -0
- package/src/lib/validators/{design-system-validator.js → design-system/design-system-validator.js} +231 -231
- package/src/lib/validators/design-system/index.js +7 -0
- package/src/lib/validators/packages/index.js +7 -0
- package/src/lib/validators/shared/index.js +12 -0
- package/src/lib/validators/shared/issue-counter.js +18 -0
- package/src/lib/validators/shared/result-formatter.js +124 -0
- package/src/lib/{spec-validator.js → validators/spec-validator.js} +258 -258
- package/src/lib/validators/ui/index.js +7 -0
- package/src/lib/{validation-runner.js → validators/validation-runner.js} +286 -284
- package/src/ui/wizard-questions.js +0 -2
- package/src/utils/color-utils.js +70 -0
- package/src/utils/file-copier.js +188 -189
- package/src/utils/process-handler.js +97 -0
- package/stacks/blazor-azure/.morph/config/agents.json +948 -764
- package/stacks/blazor-azure/.morph/hooks/{pre-commit-tests.sh → pre-commit/tests-csharp.sh} +3 -2
- package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +41 -0
- package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +24 -0
- package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +23 -0
- package/stacks/nextjs-supabase/.morph/config/agents.json +345 -345
- package/stacks/nextjs-supabase/.morph/hooks/pre-commit/tests-typescript.sh +61 -0
- package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +22 -0
- package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +22 -0
- package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +35 -0
- package/stacks/nextjs-supabase/README.md +6 -15
- package/CLAUDE.md +0 -648
- package/bin/render-template.js +0 -349
- package/bin/semantic-detect-agents.js +0 -247
- package/bin/validate-agents-skills.js +0 -257
- package/bin/validate-agents.js +0 -70
- package/bin/validate-phase.js +0 -263
- package/docs/examples.md +0 -328
- package/docs/llm-interaction-config.md +0 -735
- package/scripts/reorganize-skills.cjs +0 -175
- package/scripts/validate-agents-structure.cjs +0 -52
- package/scripts/validate-skills.cjs +0 -180
- package/src/commands/deploy.js +0 -780
- package/src/commands/migrate-state.js +0 -158
- package/src/commands/upgrade.js +0 -346
- package/src/lib/continuous-validator.js +0 -421
- package/src/lib/decision-constraint-loader.js +0 -109
- package/src/lib/design-system-scaffolder.js +0 -299
- package/src/lib/hook-executor.js +0 -257
- package/src/lib/mockup-generator.js +0 -366
- package/src/lib/ui-detector.js +0 -350
- package/src/llm/schema-validator.js +0 -121
- package/src/sanitizer/.gitkeep +0 -0
- package/src/scanner/.gitkeep +0 -0
- package/src/types/index.js +0 -477
- package/src/ui/.gitkeep +0 -0
- package/src/writer/.gitkeep +0 -0
- package/stacks/blazor-azure/.azure/README.md +0 -293
- package/stacks/blazor-azure/.azure/docs/azure-devops-setup.md +0 -454
- package/stacks/blazor-azure/.azure/docs/branch-strategy.md +0 -398
- package/stacks/blazor-azure/.azure/docs/local-development.md +0 -515
- package/stacks/blazor-azure/.azure/pipelines/pipeline-variables.yml +0 -34
- package/stacks/blazor-azure/.azure/pipelines/prod-pipeline.yml +0 -319
- package/stacks/blazor-azure/.azure/pipelines/staging-pipeline.yml +0 -234
- package/stacks/blazor-azure/.azure/pipelines/templates/build-dotnet.yml +0 -75
- package/stacks/blazor-azure/.azure/pipelines/templates/deploy-app-service.yml +0 -94
- package/stacks/blazor-azure/.azure/pipelines/templates/deploy-container-app.yml +0 -120
- package/stacks/blazor-azure/.azure/pipelines/templates/infra-deploy.yml +0 -90
- package/stacks/blazor-azure/.claude/commands/morph-apply.md +0 -221
- package/stacks/blazor-azure/.claude/commands/morph-archive.md +0 -79
- package/stacks/blazor-azure/.claude/commands/morph-deploy.md +0 -529
- package/stacks/blazor-azure/.claude/commands/morph-infra.md +0 -209
- package/stacks/blazor-azure/.claude/commands/morph-preflight.md +0 -227
- package/stacks/blazor-azure/.claude/commands/morph-proposal.md +0 -122
- package/stacks/blazor-azure/.claude/commands/morph-status.md +0 -86
- package/stacks/blazor-azure/.claude/commands/morph-troubleshoot.md +0 -122
- package/stacks/blazor-azure/.claude/settings.local.json +0 -15
- package/stacks/blazor-azure/.claude/skills/level-0-meta/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-0-meta/code-review.md +0 -226
- package/stacks/blazor-azure/.claude/skills/level-0-meta/morph-checklist.md +0 -117
- package/stacks/blazor-azure/.claude/skills/level-0-meta/simulation-checklist.md +0 -77
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/morph-replicate.md +0 -213
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-clarify.md +0 -131
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-design.md +0 -213
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-setup.md +0 -106
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-tasks.md +0 -164
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-uiux.md +0 -169
- package/stacks/blazor-azure/.claude/skills/level-2-domains/README.md +0 -14
- package/stacks/blazor-azure/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -192
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -197
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -189
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -320
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -156
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -287
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -113
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -109
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -210
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -154
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -191
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -142
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -699
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -131
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -119
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -130
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -142
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -108
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/resend-email.md +0 -119
- package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -235
- package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-3-technologies/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-4-patterns/README.md +0 -7
- package/stacks/blazor-azure/.morph/archive/.gitkeep +0 -25
- package/stacks/blazor-azure/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -392
- package/stacks/blazor-azure/.morph/docs/workflows/design-impl.md +0 -37
- package/stacks/blazor-azure/.morph/docs/workflows/enforcement-pipeline.md +0 -668
- package/stacks/blazor-azure/.morph/docs/workflows/fast-track.md +0 -29
- package/stacks/blazor-azure/.morph/docs/workflows/full-morph.md +0 -76
- package/stacks/blazor-azure/.morph/docs/workflows/standard.md +0 -44
- package/stacks/blazor-azure/.morph/docs/workflows/ui-refresh.md +0 -39
- package/stacks/blazor-azure/.morph/examples/api-nextjs/README.md +0 -241
- package/stacks/blazor-azure/.morph/examples/api-nextjs/contracts.ts +0 -307
- package/stacks/blazor-azure/.morph/examples/api-nextjs/spec.md +0 -399
- package/stacks/blazor-azure/.morph/examples/api-nextjs/tasks.md +0 -168
- package/stacks/blazor-azure/.morph/examples/micro-saas/README.md +0 -125
- package/stacks/blazor-azure/.morph/examples/micro-saas/contracts.cs +0 -358
- package/stacks/blazor-azure/.morph/examples/micro-saas/decisions.md +0 -246
- package/stacks/blazor-azure/.morph/examples/micro-saas/spec.md +0 -236
- package/stacks/blazor-azure/.morph/examples/micro-saas/tasks.md +0 -150
- package/stacks/blazor-azure/.morph/examples/multi-agent/README.md +0 -309
- package/stacks/blazor-azure/.morph/examples/multi-agent/contracts.cs +0 -433
- package/stacks/blazor-azure/.morph/examples/multi-agent/spec.md +0 -479
- package/stacks/blazor-azure/.morph/examples/multi-agent/tasks.md +0 -185
- package/stacks/blazor-azure/.morph/examples/scheduled-reports/decisions.md +0 -158
- package/stacks/blazor-azure/.morph/examples/scheduled-reports/proposal.md +0 -95
- package/stacks/blazor-azure/.morph/examples/scheduled-reports/spec.md +0 -267
- package/stacks/blazor-azure/.morph/examples/state-v3.json +0 -188
- package/stacks/blazor-azure/.morph/features/.gitkeep +0 -25
- package/stacks/blazor-azure/.morph/hooks/README.md +0 -348
- package/stacks/blazor-azure/.morph/hooks/pre-commit-agents.sh +0 -24
- package/stacks/blazor-azure/.morph/hooks/pre-commit-all.sh +0 -48
- package/stacks/blazor-azure/.morph/hooks/pre-commit-specs.sh +0 -49
- package/stacks/blazor-azure/.morph/hooks/task-completed.js +0 -73
- package/stacks/blazor-azure/.morph/hooks/teammate-idle.js +0 -68
- package/stacks/blazor-azure/.morph/schemas/agent.schema.json +0 -296
- package/stacks/blazor-azure/.morph/schemas/tasks.schema.json +0 -220
- package/stacks/blazor-azure/.morph/specs/.gitkeep +0 -20
- package/stacks/blazor-azure/.morph/standards/agent-framework-blazor-ui.md +0 -359
- package/stacks/blazor-azure/.morph/standards/agent-framework-production.md +0 -410
- package/stacks/blazor-azure/.morph/standards/agent-framework-setup.md +0 -413
- package/stacks/blazor-azure/.morph/standards/agent-framework-workflows.md +0 -349
- package/stacks/blazor-azure/.morph/standards/agent-teams-workflow.md +0 -474
- package/stacks/blazor-azure/.morph/standards/architecture.md +0 -325
- package/stacks/blazor-azure/.morph/standards/azure.md +0 -605
- package/stacks/blazor-azure/.morph/standards/coding.md +0 -377
- package/stacks/blazor-azure/.morph/standards/dotnet10-migration.md +0 -520
- package/stacks/blazor-azure/.morph/standards/fluent-ui-setup.md +0 -590
- package/stacks/blazor-azure/.morph/standards/migration-guide.md +0 -514
- package/stacks/blazor-azure/.morph/standards/passkeys-auth.md +0 -423
- package/stacks/blazor-azure/.morph/standards/vector-search-rag.md +0 -536
- package/stacks/blazor-azure/.morph/templates/CONTEXT-FEATURE.md +0 -276
- package/stacks/blazor-azure/.morph/templates/CONTEXT.md +0 -170
- package/stacks/blazor-azure/.morph/templates/FluentDesignTheme.cs +0 -149
- package/stacks/blazor-azure/.morph/templates/MudTheme.cs +0 -281
- package/stacks/blazor-azure/.morph/templates/agent.cs +0 -163
- package/stacks/blazor-azure/.morph/templates/clarify-questions.md +0 -159
- package/stacks/blazor-azure/.morph/templates/component.razor +0 -239
- package/stacks/blazor-azure/.morph/templates/contracts/Commands.cs +0 -74
- package/stacks/blazor-azure/.morph/templates/contracts/Entities.cs +0 -25
- package/stacks/blazor-azure/.morph/templates/contracts/Queries.cs +0 -74
- package/stacks/blazor-azure/.morph/templates/contracts/README.md +0 -74
- package/stacks/blazor-azure/.morph/templates/contracts.cs +0 -217
- package/stacks/blazor-azure/.morph/templates/decisions.md +0 -123
- package/stacks/blazor-azure/.morph/templates/design-system.css +0 -226
- package/stacks/blazor-azure/.morph/templates/infra/.dockerignore.example +0 -89
- package/stacks/blazor-azure/.morph/templates/infra/Dockerfile.example +0 -82
- package/stacks/blazor-azure/.morph/templates/infra/README.md +0 -286
- package/stacks/blazor-azure/.morph/templates/infra/app-insights.bicep +0 -63
- package/stacks/blazor-azure/.morph/templates/infra/app-service.bicep +0 -164
- package/stacks/blazor-azure/.morph/templates/infra/azure-pipelines-deploy.yml +0 -480
- package/stacks/blazor-azure/.morph/templates/infra/container-app-env.bicep +0 -49
- package/stacks/blazor-azure/.morph/templates/infra/container-app.bicep +0 -156
- package/stacks/blazor-azure/.morph/templates/infra/deploy-checklist.md +0 -426
- package/stacks/blazor-azure/.morph/templates/infra/deploy.ps1 +0 -229
- package/stacks/blazor-azure/.morph/templates/infra/deploy.sh +0 -208
- package/stacks/blazor-azure/.morph/templates/infra/key-vault.bicep +0 -91
- package/stacks/blazor-azure/.morph/templates/infra/main.bicep +0 -189
- package/stacks/blazor-azure/.morph/templates/infra/parameters.dev.json +0 -29
- package/stacks/blazor-azure/.morph/templates/infra/parameters.prod.json +0 -29
- package/stacks/blazor-azure/.morph/templates/infra/parameters.staging.json +0 -29
- package/stacks/blazor-azure/.morph/templates/infra/sql-database.bicep +0 -103
- package/stacks/blazor-azure/.morph/templates/infra/storage.bicep +0 -106
- package/stacks/blazor-azure/.morph/templates/integrations/asaas-client.cs +0 -387
- package/stacks/blazor-azure/.morph/templates/integrations/asaas-webhook.cs +0 -351
- package/stacks/blazor-azure/.morph/templates/integrations/azure-identity-config.cs +0 -288
- package/stacks/blazor-azure/.morph/templates/integrations/clerk-config.cs +0 -258
- package/stacks/blazor-azure/.morph/templates/job.cs +0 -171
- package/stacks/blazor-azure/.morph/templates/migration.cs +0 -83
- package/stacks/blazor-azure/.morph/templates/proposal.md +0 -141
- package/stacks/blazor-azure/.morph/templates/recap.md +0 -94
- package/stacks/blazor-azure/.morph/templates/repository.cs +0 -141
- package/stacks/blazor-azure/.morph/templates/saas/subscription.cs +0 -347
- package/stacks/blazor-azure/.morph/templates/saas/tenant.cs +0 -338
- package/stacks/blazor-azure/.morph/templates/service.cs +0 -139
- package/stacks/blazor-azure/.morph/templates/simulation.md +0 -353
- package/stacks/blazor-azure/.morph/templates/spec.md +0 -149
- package/stacks/blazor-azure/.morph/templates/sprint-status.yaml +0 -68
- package/stacks/blazor-azure/.morph/templates/state.template.json +0 -222
- package/stacks/blazor-azure/.morph/templates/story.md +0 -143
- package/stacks/blazor-azure/.morph/templates/tasks.md +0 -257
- package/stacks/blazor-azure/.morph/templates/test.cs +0 -239
- package/stacks/blazor-azure/.morph/templates/ui-components.md +0 -362
- package/stacks/blazor-azure/.morph/templates/ui-design-system.md +0 -286
- package/stacks/blazor-azure/.morph/templates/ui-flows.md +0 -336
- package/stacks/blazor-azure/.morph/templates/ui-mockups.md +0 -133
- package/stacks/blazor-azure/.morph/test-infra/example.bicep +0 -59
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +0 -244
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +0 -335
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +0 -189
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +0 -170
- package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +0 -169
- package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +0 -247
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +0 -697
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +0 -85
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +0 -86
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +0 -498
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +0 -121
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +0 -138
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +0 -162
- package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +0 -191
- package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +0 -193
- package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +0 -171
- package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +0 -164
- package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +0 -179
- package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +0 -148
- package/stacks/nextjs-supabase/.morph/templates/contracts.cs +0 -173
- package/stacks/nextjs-supabase/.morph/templates/contracts.ts +0 -168
- package/stacks/nextjs-supabase/.morph/templates/decisions.md +0 -115
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +0 -38
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +0 -48
- package/stacks/nextjs-supabase/.morph/templates/proposal.md +0 -145
- package/stacks/nextjs-supabase/.morph/templates/recap.md +0 -134
- package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +0 -57
- package/stacks/nextjs-supabase/.morph/templates/spec.md +0 -231
- package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +0 -100
- package/stacks/nextjs-supabase/.morph/templates/tasks.md +0 -257
- /package/src/commands/{search-patterns.js → learning/search-patterns.js} +0 -0
- /package/src/{lib → core/templates}/template-data-sources.js +0 -0
- /package/src/lib/{design-system-generator.js → generators/design-system-generator.js} +0 -0
- /package/src/lib/{learning-system.js → learning/learning-system.js} +0 -0
- /package/src/lib/validators/{package-validator.js → packages/package-validator.js} +0 -0
- /package/src/lib/validators/{ui-contrast-validator.js → ui/ui-contrast-validator.js} +0 -0
- /package/{src/generator → stacks/blazor-azure/.morph/templates}/.gitkeep +0 -0
- /package/{src/llm → stacks/nextjs-supabase/.morph/templates}/.gitkeep +0 -0
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Troubleshoot Index Search
|
|
3
|
-
* Searches the troubleshooting-index.json for matching problems
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { readFileSync, existsSync } from 'fs';
|
|
7
|
-
import { join, dirname } from 'path';
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
9
|
-
|
|
10
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
const __dirname = dirname(__filename);
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Load the troubleshooting index
|
|
15
|
-
* @returns {Object} The index object or null if not found
|
|
16
|
-
*/
|
|
17
|
-
export function loadIndex() {
|
|
18
|
-
const indexPath = join(__dirname, '../../framework/index/troubleshooting-index.json');
|
|
19
|
-
|
|
20
|
-
if (!existsSync(indexPath)) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const content = readFileSync(indexPath, 'utf-8');
|
|
26
|
-
return JSON.parse(content);
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.error('Error loading troubleshooting index:', error.message);
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Calculate relevance score for a problem based on keywords
|
|
35
|
-
* @param {Object} problem - The problem object from index
|
|
36
|
-
* @param {string[]} searchTerms - Search terms from user
|
|
37
|
-
* @returns {number} Relevance score (higher is better)
|
|
38
|
-
*/
|
|
39
|
-
function calculateScore(problem, searchTerms) {
|
|
40
|
-
let score = 0;
|
|
41
|
-
const searchLower = searchTerms.map(t => t.toLowerCase());
|
|
42
|
-
|
|
43
|
-
// Check keywords
|
|
44
|
-
for (const keyword of problem.keywords) {
|
|
45
|
-
const keywordLower = keyword.toLowerCase();
|
|
46
|
-
for (const term of searchLower) {
|
|
47
|
-
if (keywordLower.includes(term) || term.includes(keywordLower)) {
|
|
48
|
-
score += 10;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Check title
|
|
54
|
-
const titleLower = problem.title.toLowerCase();
|
|
55
|
-
for (const term of searchLower) {
|
|
56
|
-
if (titleLower.includes(term)) {
|
|
57
|
-
score += 5;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Check error pattern (regex match on search string)
|
|
62
|
-
if (problem.errorPattern) {
|
|
63
|
-
try {
|
|
64
|
-
const regex = new RegExp(problem.errorPattern, 'i');
|
|
65
|
-
const searchString = searchTerms.join(' ');
|
|
66
|
-
if (regex.test(searchString)) {
|
|
67
|
-
score += 20; // High score for error pattern match
|
|
68
|
-
}
|
|
69
|
-
} catch (e) {
|
|
70
|
-
// Invalid regex, skip
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Boost critical severity
|
|
75
|
-
if (problem.severity === 'critical') {
|
|
76
|
-
score *= 1.2;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return score;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Search the index for problems matching the keywords
|
|
84
|
-
* @param {string[]} keywords - Search keywords
|
|
85
|
-
* @param {Object} options - Search options
|
|
86
|
-
* @param {string} options.category - Filter by category
|
|
87
|
-
* @returns {Object[]} Array of matching problems with scores
|
|
88
|
-
*/
|
|
89
|
-
export function searchIndex(keywords, options = {}) {
|
|
90
|
-
const index = loadIndex();
|
|
91
|
-
|
|
92
|
-
if (!index || !index.problems) {
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let problems = index.problems;
|
|
97
|
-
|
|
98
|
-
// Filter by category if specified
|
|
99
|
-
if (options.category) {
|
|
100
|
-
problems = problems.filter(p => p.category === options.category);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Score and filter problems
|
|
104
|
-
const results = problems
|
|
105
|
-
.map(problem => ({
|
|
106
|
-
...problem,
|
|
107
|
-
score: calculateScore(problem, keywords)
|
|
108
|
-
}))
|
|
109
|
-
.filter(p => p.score > 0)
|
|
110
|
-
.sort((a, b) => b.score - a.score);
|
|
111
|
-
|
|
112
|
-
return results;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Get all categories from the index
|
|
117
|
-
* @returns {Object} Categories object
|
|
118
|
-
*/
|
|
119
|
-
export function getCategories() {
|
|
120
|
-
const index = loadIndex();
|
|
121
|
-
return index?.categories || {};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Get a specific problem by ID
|
|
126
|
-
* @param {string} id - Problem ID
|
|
127
|
-
* @returns {Object|null} Problem object or null
|
|
128
|
-
*/
|
|
129
|
-
export function getProblemById(id) {
|
|
130
|
-
const index = loadIndex();
|
|
131
|
-
|
|
132
|
-
if (!index || !index.problems) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return index.problems.find(p => p.id === id) || null;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export default {
|
|
140
|
-
loadIndex,
|
|
141
|
-
searchIndex,
|
|
142
|
-
getCategories,
|
|
143
|
-
getProblemById
|
|
144
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Troubleshoot Index Search
|
|
3
|
+
* Searches the troubleshooting-index.json for matching problems
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFileSync, existsSync } from 'fs';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Load the troubleshooting index
|
|
15
|
+
* @returns {Object} The index object or null if not found
|
|
16
|
+
*/
|
|
17
|
+
export function loadIndex() {
|
|
18
|
+
const indexPath = join(__dirname, '../../framework/index/troubleshooting-index.json');
|
|
19
|
+
|
|
20
|
+
if (!existsSync(indexPath)) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const content = readFileSync(indexPath, 'utf-8');
|
|
26
|
+
return JSON.parse(content);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error('Error loading troubleshooting index:', error.message);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculate relevance score for a problem based on keywords
|
|
35
|
+
* @param {Object} problem - The problem object from index
|
|
36
|
+
* @param {string[]} searchTerms - Search terms from user
|
|
37
|
+
* @returns {number} Relevance score (higher is better)
|
|
38
|
+
*/
|
|
39
|
+
function calculateScore(problem, searchTerms) {
|
|
40
|
+
let score = 0;
|
|
41
|
+
const searchLower = searchTerms.map(t => t.toLowerCase());
|
|
42
|
+
|
|
43
|
+
// Check keywords
|
|
44
|
+
for (const keyword of problem.keywords) {
|
|
45
|
+
const keywordLower = keyword.toLowerCase();
|
|
46
|
+
for (const term of searchLower) {
|
|
47
|
+
if (keywordLower.includes(term) || term.includes(keywordLower)) {
|
|
48
|
+
score += 10;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Check title
|
|
54
|
+
const titleLower = problem.title.toLowerCase();
|
|
55
|
+
for (const term of searchLower) {
|
|
56
|
+
if (titleLower.includes(term)) {
|
|
57
|
+
score += 5;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check error pattern (regex match on search string)
|
|
62
|
+
if (problem.errorPattern) {
|
|
63
|
+
try {
|
|
64
|
+
const regex = new RegExp(problem.errorPattern, 'i');
|
|
65
|
+
const searchString = searchTerms.join(' ');
|
|
66
|
+
if (regex.test(searchString)) {
|
|
67
|
+
score += 20; // High score for error pattern match
|
|
68
|
+
}
|
|
69
|
+
} catch (e) {
|
|
70
|
+
// Invalid regex, skip
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Boost critical severity
|
|
75
|
+
if (problem.severity === 'critical') {
|
|
76
|
+
score *= 1.2;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return score;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Search the index for problems matching the keywords
|
|
84
|
+
* @param {string[]} keywords - Search keywords
|
|
85
|
+
* @param {Object} options - Search options
|
|
86
|
+
* @param {string} options.category - Filter by category
|
|
87
|
+
* @returns {Object[]} Array of matching problems with scores
|
|
88
|
+
*/
|
|
89
|
+
export function searchIndex(keywords, options = {}) {
|
|
90
|
+
const index = loadIndex();
|
|
91
|
+
|
|
92
|
+
if (!index || !index.problems) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let problems = index.problems;
|
|
97
|
+
|
|
98
|
+
// Filter by category if specified
|
|
99
|
+
if (options.category) {
|
|
100
|
+
problems = problems.filter(p => p.category === options.category);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Score and filter problems
|
|
104
|
+
const results = problems
|
|
105
|
+
.map(problem => ({
|
|
106
|
+
...problem,
|
|
107
|
+
score: calculateScore(problem, keywords)
|
|
108
|
+
}))
|
|
109
|
+
.filter(p => p.score > 0)
|
|
110
|
+
.sort((a, b) => b.score - a.score);
|
|
111
|
+
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get all categories from the index
|
|
117
|
+
* @returns {Object} Categories object
|
|
118
|
+
*/
|
|
119
|
+
export function getCategories() {
|
|
120
|
+
const index = loadIndex();
|
|
121
|
+
return index?.categories || {};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get a specific problem by ID
|
|
126
|
+
* @param {string} id - Problem ID
|
|
127
|
+
* @returns {Object|null} Problem object or null
|
|
128
|
+
*/
|
|
129
|
+
export function getProblemById(id) {
|
|
130
|
+
const index = loadIndex();
|
|
131
|
+
|
|
132
|
+
if (!index || !index.problems) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return index.problems.find(p => p.id === id) || null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export default {
|
|
140
|
+
loadIndex,
|
|
141
|
+
searchIndex,
|
|
142
|
+
getCategories,
|
|
143
|
+
getProblemById
|
|
144
|
+
};
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Manager — Track-record and auto-approval logic
|
|
3
|
+
*
|
|
4
|
+
* Computes trust level from checkpoint pass rate history.
|
|
5
|
+
* Enables auto-approval gates for features with proven track records.
|
|
6
|
+
*
|
|
7
|
+
* Trust levels:
|
|
8
|
+
* low < 80% pass rate
|
|
9
|
+
* medium 80–90%
|
|
10
|
+
* high 90–95%
|
|
11
|
+
* maximum > 95%
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
|
|
17
|
+
// Default trust config (matches llm-interaction.json thresholds)
|
|
18
|
+
const TRUST_THRESHOLDS = {
|
|
19
|
+
low: 0,
|
|
20
|
+
medium: 0.80,
|
|
21
|
+
high: 0.90,
|
|
22
|
+
maximum: 0.95
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Gates that can be auto-approved by trust level
|
|
26
|
+
const AUTO_APPROVE_GATES = {
|
|
27
|
+
medium: ['design'],
|
|
28
|
+
high: ['design', 'tasks'],
|
|
29
|
+
maximum: ['design', 'tasks', 'proposal']
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Load state.json
|
|
34
|
+
* @returns {Object} State
|
|
35
|
+
*/
|
|
36
|
+
function loadState() {
|
|
37
|
+
const statePath = join(process.cwd(), '.morph/state.json');
|
|
38
|
+
if (!existsSync(statePath)) return { features: {} };
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(readFileSync(statePath, 'utf8'));
|
|
41
|
+
} catch {
|
|
42
|
+
return { features: {} };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Save state.json
|
|
48
|
+
* @param {Object} state
|
|
49
|
+
*/
|
|
50
|
+
function saveState(state) {
|
|
51
|
+
const statePath = join(process.cwd(), '.morph/state.json');
|
|
52
|
+
writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Calculate trust level from checkpoint history
|
|
57
|
+
* @param {Array} checkpoints - Array of { passed: boolean, ... }
|
|
58
|
+
* @returns {{ level: string, passRate: number, total: number, passed: number }}
|
|
59
|
+
*/
|
|
60
|
+
export function calculateTrust(checkpoints = []) {
|
|
61
|
+
if (checkpoints.length === 0) {
|
|
62
|
+
return { level: 'low', passRate: 0, total: 0, passed: 0 };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const total = checkpoints.length;
|
|
66
|
+
const passed = checkpoints.filter(c => c.passed).length;
|
|
67
|
+
const passRate = passed / total;
|
|
68
|
+
|
|
69
|
+
let level = 'low';
|
|
70
|
+
if (passRate >= TRUST_THRESHOLDS.maximum) level = 'maximum';
|
|
71
|
+
else if (passRate >= TRUST_THRESHOLDS.high) level = 'high';
|
|
72
|
+
else if (passRate >= TRUST_THRESHOLDS.medium) level = 'medium';
|
|
73
|
+
|
|
74
|
+
return { level, passRate, total, passed };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get current trust config for a feature
|
|
79
|
+
* @param {string} featureName
|
|
80
|
+
* @returns {{ level: string, passRate: number, autoApprove: string[], override?: string }}
|
|
81
|
+
*/
|
|
82
|
+
export function getTrust(featureName) {
|
|
83
|
+
const state = loadState();
|
|
84
|
+
const feature = state.features?.[featureName];
|
|
85
|
+
|
|
86
|
+
if (!feature) {
|
|
87
|
+
return { level: 'low', passRate: 0, autoApprove: [], source: 'default' };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Check for manual override first
|
|
91
|
+
if (feature.trustConfig?.override) {
|
|
92
|
+
return {
|
|
93
|
+
level: feature.trustConfig.override.level,
|
|
94
|
+
passRate: feature.trustConfig.passRate || 0,
|
|
95
|
+
autoApprove: AUTO_APPROVE_GATES[feature.trustConfig.override.level] || [],
|
|
96
|
+
source: 'manual',
|
|
97
|
+
overrideReason: feature.trustConfig.override.reason,
|
|
98
|
+
overrideAt: feature.trustConfig.override.setAt
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Calculate from checkpoint history
|
|
103
|
+
const checkpoints = feature.checkpoints || [];
|
|
104
|
+
const { level, passRate, total, passed } = calculateTrust(checkpoints);
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
level,
|
|
108
|
+
passRate,
|
|
109
|
+
total,
|
|
110
|
+
passed,
|
|
111
|
+
autoApprove: AUTO_APPROVE_GATES[level] || [],
|
|
112
|
+
source: 'calculated'
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Manually set trust level with reason
|
|
118
|
+
* @param {string} featureName
|
|
119
|
+
* @param {string} level - 'low' | 'medium' | 'high' | 'maximum'
|
|
120
|
+
* @param {string} reason
|
|
121
|
+
*/
|
|
122
|
+
export function setTrust(featureName, level, reason) {
|
|
123
|
+
const validLevels = ['low', 'medium', 'high', 'maximum'];
|
|
124
|
+
if (!validLevels.includes(level)) {
|
|
125
|
+
throw new Error(`Invalid trust level: ${level}. Valid: ${validLevels.join(', ')}`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const state = loadState();
|
|
129
|
+
if (!state.features[featureName]) {
|
|
130
|
+
throw new Error(`Feature not found: ${featureName}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!state.features[featureName].trustConfig) {
|
|
134
|
+
state.features[featureName].trustConfig = {};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
state.features[featureName].trustConfig.override = {
|
|
138
|
+
level,
|
|
139
|
+
reason,
|
|
140
|
+
setAt: new Date().toISOString(),
|
|
141
|
+
setBy: 'manual'
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
saveState(state);
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
feature: featureName,
|
|
148
|
+
level,
|
|
149
|
+
autoApprove: AUTO_APPROVE_GATES[level] || [],
|
|
150
|
+
reason
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Clear manual trust override (revert to calculated)
|
|
156
|
+
* @param {string} featureName
|
|
157
|
+
*/
|
|
158
|
+
export function clearTrustOverride(featureName) {
|
|
159
|
+
const state = loadState();
|
|
160
|
+
if (state.features[featureName]?.trustConfig?.override) {
|
|
161
|
+
delete state.features[featureName].trustConfig.override;
|
|
162
|
+
saveState(state);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Check if a gate should be auto-approved based on trust level
|
|
168
|
+
* @param {string} featureName
|
|
169
|
+
* @param {string} gate - 'design' | 'tasks' | 'proposal'
|
|
170
|
+
* @returns {{ autoApprove: boolean, level: string, reason: string }}
|
|
171
|
+
*/
|
|
172
|
+
export function shouldAutoApprove(featureName, gate) {
|
|
173
|
+
const trust = getTrust(featureName);
|
|
174
|
+
|
|
175
|
+
if (!trust.autoApprove.includes(gate)) {
|
|
176
|
+
return {
|
|
177
|
+
autoApprove: false,
|
|
178
|
+
level: trust.level,
|
|
179
|
+
reason: `Trust level "${trust.level}" does not auto-approve "${gate}" gate (need: ${getMinLevelForGate(gate)})`
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
autoApprove: true,
|
|
185
|
+
level: trust.level,
|
|
186
|
+
reason: `Auto-approved: ${trust.level} trust (${Math.round(trust.passRate * 100)}% pass rate, ${trust.total} checkpoints)`,
|
|
187
|
+
passRate: trust.passRate,
|
|
188
|
+
checkpointsTotal: trust.total
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get minimum trust level required for a gate
|
|
194
|
+
* @param {string} gate
|
|
195
|
+
* @returns {string}
|
|
196
|
+
*/
|
|
197
|
+
function getMinLevelForGate(gate) {
|
|
198
|
+
for (const [level, gates] of Object.entries(AUTO_APPROVE_GATES)) {
|
|
199
|
+
if (gates.includes(gate)) return level;
|
|
200
|
+
}
|
|
201
|
+
return 'maximum';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Get trust history for all features
|
|
206
|
+
* @returns {Array} Feature trust summaries
|
|
207
|
+
*/
|
|
208
|
+
export function getTrustHistory() {
|
|
209
|
+
const state = loadState();
|
|
210
|
+
const features = state.features || {};
|
|
211
|
+
|
|
212
|
+
return Object.entries(features).map(([name, feature]) => {
|
|
213
|
+
const trust = getTrust(name);
|
|
214
|
+
return {
|
|
215
|
+
feature: name,
|
|
216
|
+
level: trust.level,
|
|
217
|
+
passRate: trust.passRate,
|
|
218
|
+
checkpointsTotal: trust.total || 0,
|
|
219
|
+
checkpointsPassed: trust.passed || 0,
|
|
220
|
+
autoApprove: trust.autoApprove,
|
|
221
|
+
source: trust.source,
|
|
222
|
+
phase: feature.phase,
|
|
223
|
+
status: feature.status
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Auto-calculate and update trust in state
|
|
230
|
+
* @param {string} featureName
|
|
231
|
+
* @returns {Object} Updated trust config
|
|
232
|
+
*/
|
|
233
|
+
export function autoCalculateTrust(featureName) {
|
|
234
|
+
const state = loadState();
|
|
235
|
+
const feature = state.features?.[featureName];
|
|
236
|
+
|
|
237
|
+
if (!feature) {
|
|
238
|
+
throw new Error(`Feature not found: ${featureName}`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const checkpoints = feature.checkpoints || [];
|
|
242
|
+
const { level, passRate, total, passed } = calculateTrust(checkpoints);
|
|
243
|
+
|
|
244
|
+
if (!state.features[featureName].trustConfig) {
|
|
245
|
+
state.features[featureName].trustConfig = {};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
state.features[featureName].trustConfig = {
|
|
249
|
+
...state.features[featureName].trustConfig,
|
|
250
|
+
level,
|
|
251
|
+
passRate,
|
|
252
|
+
checkpointsTotal: total,
|
|
253
|
+
checkpointsPassed: passed,
|
|
254
|
+
lastCalculated: new Date().toISOString()
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
saveState(state);
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
feature: featureName,
|
|
261
|
+
level,
|
|
262
|
+
passRate,
|
|
263
|
+
total,
|
|
264
|
+
passed,
|
|
265
|
+
autoApprove: AUTO_APPROVE_GATES[level] || []
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export { TRUST_THRESHOLDS, AUTO_APPROVE_GATES };
|
package/src/lib/validators/{architecture-validator.js → architecture/architecture-validator.js}
RENAMED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Validates architectural patterns and detects anti-patterns in Blazor apps.
|
|
5
5
|
* Prevents common DI mistakes, lifecycle issues, and coupling problems.
|
|
6
6
|
*
|
|
7
|
-
* Source: framework/standards/blazor
|
|
7
|
+
* Source: framework/standards/frontend/blazor/pitfalls.md
|
|
8
8
|
* MORPH-SPEC 3.0 - Sprint 4
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -21,7 +21,7 @@ const VALIDATION_RULES = {
|
|
|
21
21
|
pattern: /\[Inject\].*I\w+(Command|Query|Handler)/,
|
|
22
22
|
level: 'error',
|
|
23
23
|
message: 'Blazor component injecting Application layer directly (use HttpClient pattern)',
|
|
24
|
-
reference: 'framework/standards/blazor
|
|
24
|
+
reference: 'framework/standards/frontend/blazor/pitfalls.md#di-pattern',
|
|
25
25
|
solution: 'Replace with HttpClient and call API endpoint'
|
|
26
26
|
},
|
|
27
27
|
|
|
@@ -29,7 +29,7 @@ const VALIDATION_RULES = {
|
|
|
29
29
|
pattern: /\[Inject\].*DbContext/,
|
|
30
30
|
level: 'error',
|
|
31
31
|
message: 'Blazor component injecting DbContext directly (use HttpClient → API → Handler)',
|
|
32
|
-
reference: 'framework/standards/blazor
|
|
32
|
+
reference: 'framework/standards/frontend/blazor/pitfalls.md#di-pattern',
|
|
33
33
|
solution: 'Use HttpClient to call API, which then uses handler/repository'
|
|
34
34
|
},
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ const VALIDATION_RULES = {
|
|
|
37
37
|
pattern: /\[Inject\].*I\w+Repository/,
|
|
38
38
|
level: 'warning',
|
|
39
39
|
message: 'Blazor component injecting Repository directly (prefer HttpClient → API pattern)',
|
|
40
|
-
reference: 'framework/standards/blazor
|
|
40
|
+
reference: 'framework/standards/frontend/blazor/pitfalls.md#di-pattern',
|
|
41
41
|
solution: 'Consider using HttpClient for better separation'
|
|
42
42
|
},
|
|
43
43
|
|
|
@@ -46,7 +46,7 @@ const VALIDATION_RULES = {
|
|
|
46
46
|
pattern: /OnInitialized(?:Async)?\(\)[\s\S]*?JSRuntime/,
|
|
47
47
|
level: 'error',
|
|
48
48
|
message: 'JSRuntime called in OnInitialized (must use OnAfterRenderAsync)',
|
|
49
|
-
reference: 'framework/standards/blazor
|
|
49
|
+
reference: 'framework/standards/frontend/blazor/lifecycle.md#jsruntime',
|
|
50
50
|
solution: 'Move JSRuntime calls to OnAfterRenderAsync with firstRender guard'
|
|
51
51
|
},
|
|
52
52
|
|
|
@@ -54,7 +54,7 @@ const VALIDATION_RULES = {
|
|
|
54
54
|
pattern: /async\s+void\s+On\w+/,
|
|
55
55
|
level: 'warning',
|
|
56
56
|
message: 'Async void event handler (prefer async Task for error handling)',
|
|
57
|
-
reference: 'framework/standards/blazor
|
|
57
|
+
reference: 'framework/standards/frontend/blazor/lifecycle.md#async',
|
|
58
58
|
solution: 'Change return type to async Task'
|
|
59
59
|
},
|
|
60
60
|
|
|
@@ -99,7 +99,7 @@ const VALIDATION_RULES = {
|
|
|
99
99
|
pattern: /IFormFile.*Blazor/,
|
|
100
100
|
level: 'error',
|
|
101
101
|
message: 'Using IFormFile in Blazor (use IBrowserFile)',
|
|
102
|
-
reference: 'framework/standards/blazor
|
|
102
|
+
reference: 'framework/standards/frontend/blazor/pitfalls.md#file-upload',
|
|
103
103
|
solution: 'Use IBrowserFile in Blazor components, convert to IFormFile in API'
|
|
104
104
|
},
|
|
105
105
|
|
|
@@ -108,7 +108,7 @@ const VALIDATION_RULES = {
|
|
|
108
108
|
pattern: /private\s+(?:static\s+)?List<.*>.*=\s*new/,
|
|
109
109
|
level: 'warning',
|
|
110
110
|
message: 'In-memory state in component (consider using proper state management)',
|
|
111
|
-
reference: 'framework/standards/blazor
|
|
111
|
+
reference: 'framework/standards/frontend/blazor/pitfalls.md#state',
|
|
112
112
|
solution: 'Use Fluxor, or move state to API/database'
|
|
113
113
|
}
|
|
114
114
|
};
|