@polymorphism-tech/morph-spec 3.2.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +352 -7
- package/README.md +1 -14
- package/bin/detect-agents.js +1 -1
- package/bin/morph-spec.js +122 -34
- package/bin/validate.js +1 -1
- package/docs/getting-started.md +0 -5
- package/docs/v3.0/AGENTS.md +521 -0
- package/docs/v3.0/ANALYSIS.md +555 -0
- package/docs/v3.0/ARCHITECTURE.md +436 -0
- package/docs/v3.0/EXECUTION-FLOW.md +1304 -0
- package/docs/v3.0/FEATURES.md +688 -0
- package/docs/v3.0/README.md +231 -0
- package/docs/v3.0/ROADMAP.md +801 -0
- package/docs/validation-checklist.md +0 -1
- package/package.json +1 -1
- package/src/commands/agents/index.js +4 -0
- package/src/commands/{spawn-team.js → agents/spawn-team.js} +172 -172
- 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/{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} +356 -356
- 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} +416 -357
- 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 +95 -0
- package/src/commands/templates/template-show.js +131 -0
- package/src/commands/templates/template-validate.js +91 -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/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 +572 -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 +354 -0
- package/src/lib/{complexity-analyzer.js → analysis/complexity-analyzer.js} +441 -441
- package/src/lib/analysis/index.js +7 -0
- package/src/lib/{checkpoint-hooks.js → checkpoints/checkpoint-hooks.js} +258 -258
- package/src/lib/checkpoints/index.js +7 -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/{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/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/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/validators/architecture/architecture-validator.js +387 -0
- package/src/lib/validators/architecture/index.js +7 -0
- package/src/lib/validators/architecture-validator.js +40 -367
- 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/content-validator.js +351 -0
- package/src/lib/validators/content/index.js +7 -0
- package/src/lib/validators/content-validator.js +164 -351
- 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/package-validator.js +41 -340
- package/src/lib/validators/packages/index.js +7 -0
- package/src/lib/validators/packages/package-validator.js +360 -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/validators/ui/ui-contrast-validator.js +422 -0
- package/src/lib/validators/ui-contrast-validator.js +31 -409
- 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/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +3 -3
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/api-designer.md +59 -0
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +45 -255
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +33 -88
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +25 -89
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/hangfire-orchestrator.md +64 -0
- package/stacks/blazor-azure/.morph/config/agents.json +879 -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/.claude/commands/morph-apply.md +221 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +79 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +529 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +209 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +227 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +122 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-status.md +86 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +122 -0
- package/stacks/nextjs-supabase/.claude/settings.local.json +6 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +30 -150
- 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/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/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/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/settings.local.json +0 -15
- 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/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/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/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/commands/{migrate-state.js → utils/migrate-state.js} +0 -0
- /package/src/commands/{upgrade.js → utils/upgrade.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/generator → stacks/blazor-azure/.morph/templates}/.gitkeep +0 -0
- /package/{src/llm → stacks/nextjs-supabase/.morph/templates}/.gitkeep +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified color utilities for CLI output
|
|
3
|
+
*
|
|
4
|
+
* Replaces manual ANSI codes with consistent chalk usage.
|
|
5
|
+
* Standardizes color handling across the codebase.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
|
|
10
|
+
// Re-export chalk for direct usage
|
|
11
|
+
export { chalk };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Predefined color functions for common use cases
|
|
15
|
+
*/
|
|
16
|
+
export const colors = {
|
|
17
|
+
error: chalk.red,
|
|
18
|
+
success: chalk.green,
|
|
19
|
+
warning: chalk.yellow,
|
|
20
|
+
info: chalk.blue,
|
|
21
|
+
dim: chalk.gray,
|
|
22
|
+
bold: chalk.bold,
|
|
23
|
+
highlight: chalk.cyan,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Status indicators with colors
|
|
28
|
+
*/
|
|
29
|
+
export const status = {
|
|
30
|
+
success: chalk.green('✓'),
|
|
31
|
+
error: chalk.red('✗'),
|
|
32
|
+
warning: chalk.yellow('⚠'),
|
|
33
|
+
info: chalk.blue('ℹ'),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Format a success message
|
|
38
|
+
* @param {string} message - Message to format
|
|
39
|
+
* @returns {string} Formatted message
|
|
40
|
+
*/
|
|
41
|
+
export function formatSuccess(message) {
|
|
42
|
+
return `${status.success} ${chalk.green(message)}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Format an error message
|
|
47
|
+
* @param {string} message - Message to format
|
|
48
|
+
* @returns {string} Formatted message
|
|
49
|
+
*/
|
|
50
|
+
export function formatError(message) {
|
|
51
|
+
return `${status.error} ${chalk.red(message)}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Format a warning message
|
|
56
|
+
* @param {string} message - Message to format
|
|
57
|
+
* @returns {string} Formatted message
|
|
58
|
+
*/
|
|
59
|
+
export function formatWarning(message) {
|
|
60
|
+
return `${status.warning} ${chalk.yellow(message)}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Format an info message
|
|
65
|
+
* @param {string} message - Message to format
|
|
66
|
+
* @returns {string} Formatted message
|
|
67
|
+
*/
|
|
68
|
+
export function formatInfo(message) {
|
|
69
|
+
return `${status.info} ${chalk.blue(message)}`;
|
|
70
|
+
}
|
package/src/utils/file-copier.js
CHANGED
|
@@ -1,189 +1,188 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import { join, dirname, resolve } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { resolveStackPath } from '../lib/stack-resolver.js';
|
|
5
|
-
|
|
6
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const frameworkRoot = join(__dirname, '..', '..');
|
|
8
|
-
|
|
9
|
-
function isSamePath(a, b) {
|
|
10
|
-
return resolve(a) === resolve(b);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function getContentDir() {
|
|
14
|
-
return resolveStackPath(frameworkRoot);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function copyDirectory(src, dest, options = {}) {
|
|
18
|
-
if (isSamePath(src, dest)) return;
|
|
19
|
-
|
|
20
|
-
const { filter, overwrite = true } = options;
|
|
21
|
-
|
|
22
|
-
await fs.copy(src, dest, {
|
|
23
|
-
overwrite,
|
|
24
|
-
filter: filter || (() => true),
|
|
25
|
-
errorOnExist: false
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function copyFile(src, dest) {
|
|
30
|
-
if (isSamePath(src, dest)) return;
|
|
31
|
-
|
|
32
|
-
await fs.ensureDir(dirname(dest));
|
|
33
|
-
await fs.copy(src, dest, { overwrite: true });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export async function pathExists(path) {
|
|
37
|
-
return fs.pathExists(path);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function readJson(path) {
|
|
41
|
-
return fs.readJson(path);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function writeJson(path, data) {
|
|
45
|
-
await fs.ensureDir(dirname(path));
|
|
46
|
-
await fs.writeJson(path, data, { spaces: 2 });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function ensureDir(path) {
|
|
50
|
-
await fs.ensureDir(path);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export async function writeFile(path, content) {
|
|
54
|
-
await fs.ensureDir(dirname(path));
|
|
55
|
-
await fs.writeFile(path, content, 'utf8');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function removeDir(path) {
|
|
59
|
-
await fs.remove(path);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export async function readFile(path) {
|
|
63
|
-
return fs.readFile(path, 'utf8');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Create symlink with fallback to copy if symlink fails
|
|
68
|
-
* @param {string} target - Path to the original file/folder
|
|
69
|
-
* @param {string} link - Path where symlink should be created
|
|
70
|
-
* @param {string} type - 'file' or 'dir'
|
|
71
|
-
* @returns {Promise<'symlink' | 'copy'>} - Returns how the link was created
|
|
72
|
-
*/
|
|
73
|
-
export async function createSymlink(target, link, type = 'file') {
|
|
74
|
-
await fs.ensureDir(dirname(link));
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
// Try to create symlink
|
|
78
|
-
await fs.ensureSymlink(target, link, type);
|
|
79
|
-
return 'symlink';
|
|
80
|
-
} catch (error) {
|
|
81
|
-
// Fallback: copy the file/directory if symlink fails
|
|
82
|
-
// (Windows may require admin permissions for symlinks)
|
|
83
|
-
if (type === 'file') {
|
|
84
|
-
await copyFile(target, link);
|
|
85
|
-
} else {
|
|
86
|
-
await copyDirectory(target, link);
|
|
87
|
-
}
|
|
88
|
-
return 'copy';
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Create a directory link (junction on Windows, symlink on other platforms)
|
|
94
|
-
* with fallback to directory copy if linking fails.
|
|
95
|
-
* @param {string} target - Path to the original directory
|
|
96
|
-
* @param {string} link - Path where the link should be created
|
|
97
|
-
* @returns {Promise<'junction' | 'symlink' | 'copy'>} - How the link was created
|
|
98
|
-
*/
|
|
99
|
-
export async function createDirectoryLink(target, link) {
|
|
100
|
-
await fs.ensureDir(dirname(link));
|
|
101
|
-
|
|
102
|
-
// Remove existing link/directory before recreating
|
|
103
|
-
if (await pathExists(link)) {
|
|
104
|
-
await fs.remove(link);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (process.platform === 'win32') {
|
|
108
|
-
try {
|
|
109
|
-
// Junction on Windows - does NOT require admin privileges
|
|
110
|
-
await fs.symlink(target, link, 'junction');
|
|
111
|
-
return 'junction';
|
|
112
|
-
} catch {
|
|
113
|
-
try {
|
|
114
|
-
await fs.ensureSymlink(target, link, 'dir');
|
|
115
|
-
return 'symlink';
|
|
116
|
-
} catch {
|
|
117
|
-
await copyDirectory(target, link);
|
|
118
|
-
return 'copy';
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
try {
|
|
123
|
-
await fs.ensureSymlink(target, link, 'dir');
|
|
124
|
-
return 'symlink';
|
|
125
|
-
} catch {
|
|
126
|
-
await copyDirectory(target, link);
|
|
127
|
-
return 'copy';
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export async function updateGitignore(projectPath) {
|
|
133
|
-
const gitignorePath = join(projectPath, '.gitignore');
|
|
134
|
-
|
|
135
|
-
const morphRules = [
|
|
136
|
-
'',
|
|
137
|
-
'# MORPH-SPEC',
|
|
138
|
-
'.morph/
|
|
139
|
-
'.
|
|
140
|
-
'
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
let
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
lines[morphEndIndex].
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { join, dirname, resolve } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { resolveStackPath } from '../lib/stacks/stack-resolver.js';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const frameworkRoot = join(__dirname, '..', '..');
|
|
8
|
+
|
|
9
|
+
function isSamePath(a, b) {
|
|
10
|
+
return resolve(a) === resolve(b);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getContentDir() {
|
|
14
|
+
return resolveStackPath(frameworkRoot);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function copyDirectory(src, dest, options = {}) {
|
|
18
|
+
if (isSamePath(src, dest)) return;
|
|
19
|
+
|
|
20
|
+
const { filter, overwrite = true } = options;
|
|
21
|
+
|
|
22
|
+
await fs.copy(src, dest, {
|
|
23
|
+
overwrite,
|
|
24
|
+
filter: filter || (() => true),
|
|
25
|
+
errorOnExist: false
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function copyFile(src, dest) {
|
|
30
|
+
if (isSamePath(src, dest)) return;
|
|
31
|
+
|
|
32
|
+
await fs.ensureDir(dirname(dest));
|
|
33
|
+
await fs.copy(src, dest, { overwrite: true });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function pathExists(path) {
|
|
37
|
+
return fs.pathExists(path);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function readJson(path) {
|
|
41
|
+
return fs.readJson(path);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function writeJson(path, data) {
|
|
45
|
+
await fs.ensureDir(dirname(path));
|
|
46
|
+
await fs.writeJson(path, data, { spaces: 2 });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function ensureDir(path) {
|
|
50
|
+
await fs.ensureDir(path);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function writeFile(path, content) {
|
|
54
|
+
await fs.ensureDir(dirname(path));
|
|
55
|
+
await fs.writeFile(path, content, 'utf8');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function removeDir(path) {
|
|
59
|
+
await fs.remove(path);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function readFile(path) {
|
|
63
|
+
return fs.readFile(path, 'utf8');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Create symlink with fallback to copy if symlink fails
|
|
68
|
+
* @param {string} target - Path to the original file/folder
|
|
69
|
+
* @param {string} link - Path where symlink should be created
|
|
70
|
+
* @param {string} type - 'file' or 'dir'
|
|
71
|
+
* @returns {Promise<'symlink' | 'copy'>} - Returns how the link was created
|
|
72
|
+
*/
|
|
73
|
+
export async function createSymlink(target, link, type = 'file') {
|
|
74
|
+
await fs.ensureDir(dirname(link));
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// Try to create symlink
|
|
78
|
+
await fs.ensureSymlink(target, link, type);
|
|
79
|
+
return 'symlink';
|
|
80
|
+
} catch (error) {
|
|
81
|
+
// Fallback: copy the file/directory if symlink fails
|
|
82
|
+
// (Windows may require admin permissions for symlinks)
|
|
83
|
+
if (type === 'file') {
|
|
84
|
+
await copyFile(target, link);
|
|
85
|
+
} else {
|
|
86
|
+
await copyDirectory(target, link);
|
|
87
|
+
}
|
|
88
|
+
return 'copy';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create a directory link (junction on Windows, symlink on other platforms)
|
|
94
|
+
* with fallback to directory copy if linking fails.
|
|
95
|
+
* @param {string} target - Path to the original directory
|
|
96
|
+
* @param {string} link - Path where the link should be created
|
|
97
|
+
* @returns {Promise<'junction' | 'symlink' | 'copy'>} - How the link was created
|
|
98
|
+
*/
|
|
99
|
+
export async function createDirectoryLink(target, link) {
|
|
100
|
+
await fs.ensureDir(dirname(link));
|
|
101
|
+
|
|
102
|
+
// Remove existing link/directory before recreating
|
|
103
|
+
if (await pathExists(link)) {
|
|
104
|
+
await fs.remove(link);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (process.platform === 'win32') {
|
|
108
|
+
try {
|
|
109
|
+
// Junction on Windows - does NOT require admin privileges
|
|
110
|
+
await fs.symlink(target, link, 'junction');
|
|
111
|
+
return 'junction';
|
|
112
|
+
} catch {
|
|
113
|
+
try {
|
|
114
|
+
await fs.ensureSymlink(target, link, 'dir');
|
|
115
|
+
return 'symlink';
|
|
116
|
+
} catch {
|
|
117
|
+
await copyDirectory(target, link);
|
|
118
|
+
return 'copy';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
try {
|
|
123
|
+
await fs.ensureSymlink(target, link, 'dir');
|
|
124
|
+
return 'symlink';
|
|
125
|
+
} catch {
|
|
126
|
+
await copyDirectory(target, link);
|
|
127
|
+
return 'copy';
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function updateGitignore(projectPath) {
|
|
133
|
+
const gitignorePath = join(projectPath, '.gitignore');
|
|
134
|
+
|
|
135
|
+
const morphRules = [
|
|
136
|
+
'',
|
|
137
|
+
'# MORPH-SPEC',
|
|
138
|
+
'.morph/templates/',
|
|
139
|
+
'.claude/settings.local.json',
|
|
140
|
+
''
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
let content = '';
|
|
144
|
+
let hasMorphSection = false;
|
|
145
|
+
|
|
146
|
+
// Read existing .gitignore if it exists
|
|
147
|
+
if (await pathExists(gitignorePath)) {
|
|
148
|
+
content = await readFile(gitignorePath);
|
|
149
|
+
hasMorphSection = content.includes('# MORPH-SPEC');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// If MORPH section already exists, check if rules are up to date
|
|
153
|
+
if (hasMorphSection) {
|
|
154
|
+
const lines = content.split('\n');
|
|
155
|
+
const morphStartIndex = lines.findIndex(line => line.trim() === '# MORPH-SPEC');
|
|
156
|
+
|
|
157
|
+
// Find the end of MORPH section (next empty line or section header)
|
|
158
|
+
let morphEndIndex = morphStartIndex + 1;
|
|
159
|
+
while (morphEndIndex < lines.length &&
|
|
160
|
+
lines[morphEndIndex].trim() !== '' &&
|
|
161
|
+
!lines[morphEndIndex].startsWith('#')) {
|
|
162
|
+
morphEndIndex++;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Extract current MORPH rules
|
|
166
|
+
const currentMorphRules = lines.slice(morphStartIndex, morphEndIndex + 1);
|
|
167
|
+
const expectedMorphRules = morphRules.slice(1, -1); // Remove empty lines from comparison
|
|
168
|
+
|
|
169
|
+
// Check if all expected rules are present
|
|
170
|
+
const missingRules = expectedMorphRules.filter(rule =>
|
|
171
|
+
rule.startsWith('#') || !currentMorphRules.some(line => line.trim() === rule)
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
if (missingRules.length > 0) {
|
|
175
|
+
// Update the section with all rules
|
|
176
|
+
lines.splice(morphStartIndex, morphEndIndex - morphStartIndex, ...morphRules.slice(1, -1));
|
|
177
|
+
content = lines.join('\n');
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
// Add MORPH section
|
|
181
|
+
if (content && !content.endsWith('\n')) {
|
|
182
|
+
content += '\n';
|
|
183
|
+
}
|
|
184
|
+
content += morphRules.join('\n');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
await writeFile(gitignorePath, content);
|
|
188
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Handler - Testable Exit Strategy
|
|
3
|
+
*
|
|
4
|
+
* Replaces direct process.exit() calls with a mockable handler.
|
|
5
|
+
* Makes the codebase testable by allowing exit behavior to be intercepted.
|
|
6
|
+
*
|
|
7
|
+
* @module process-handler
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Process Handler Class
|
|
14
|
+
*
|
|
15
|
+
* Provides testable process exit functionality.
|
|
16
|
+
*/
|
|
17
|
+
export class ProcessHandler {
|
|
18
|
+
/**
|
|
19
|
+
* @param {Function} exitFn - Exit function (defaults to process.exit)
|
|
20
|
+
*/
|
|
21
|
+
constructor(exitFn = process.exit.bind(process)) {
|
|
22
|
+
this.exitFn = exitFn;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Exit the process with optional message
|
|
27
|
+
*
|
|
28
|
+
* @param {number} code - Exit code (0 = success, non-zero = error)
|
|
29
|
+
* @param {string} [message] - Optional message to display
|
|
30
|
+
*/
|
|
31
|
+
exit(code = 0, message = null) {
|
|
32
|
+
if (message) {
|
|
33
|
+
if (code === 0) {
|
|
34
|
+
console.log(message);
|
|
35
|
+
} else {
|
|
36
|
+
console.error(message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
this.exitFn(code);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Exit with error message (code 1)
|
|
44
|
+
*
|
|
45
|
+
* @param {string} message - Error message
|
|
46
|
+
* @param {number} [code=1] - Error code
|
|
47
|
+
*/
|
|
48
|
+
exitWithError(message, code = 1) {
|
|
49
|
+
this.exit(code, chalk.red(message));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Exit with success message (code 0)
|
|
54
|
+
*
|
|
55
|
+
* @param {string} message - Success message
|
|
56
|
+
*/
|
|
57
|
+
exitWithSuccess(message) {
|
|
58
|
+
this.exit(0, chalk.green(message));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Exit with warning message (code 0, but highlighted)
|
|
63
|
+
*
|
|
64
|
+
* @param {string} message - Warning message
|
|
65
|
+
*/
|
|
66
|
+
exitWithWarning(message) {
|
|
67
|
+
this.exit(0, chalk.yellow(message));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Default instance for general use
|
|
72
|
+
export const processHandler = new ProcessHandler();
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Create a test handler for unit tests
|
|
76
|
+
*
|
|
77
|
+
* @returns {{handler: ProcessHandler, getExitCode: Function, getExited: Function}}
|
|
78
|
+
*/
|
|
79
|
+
export function createTestHandler() {
|
|
80
|
+
let exitCode = null;
|
|
81
|
+
let exited = false;
|
|
82
|
+
|
|
83
|
+
const handler = new ProcessHandler((code) => {
|
|
84
|
+
exitCode = code;
|
|
85
|
+
exited = true;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
handler,
|
|
90
|
+
getExitCode: () => exitCode,
|
|
91
|
+
getExited: () => exited,
|
|
92
|
+
reset: () => {
|
|
93
|
+
exitCode = null;
|
|
94
|
+
exited = false;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -4,9 +4,9 @@ Expert in agentic system architecture, multi-agent orchestration, and RAG pipeli
|
|
|
4
4
|
|
|
5
5
|
> **Layer:** 2 | **Load:** on-keyword | **Keywords:** orchestration, multi-agent, rag, vector search, embedding, agentic, memory, reasoning
|
|
6
6
|
|
|
7
|
-
> **Ref:** `
|
|
8
|
-
> **Ref:** `
|
|
9
|
-
> **Ref:** `vector-search-rag.md` — Vector Search + RAG with EF Core 10
|
|
7
|
+
> **Ref:** `framework/standards/ai-agents/workflows.md` — Workflow patterns with AgentWorkflowBuilder
|
|
8
|
+
> **Ref:** `framework/standards/ai-agents/production.md` — Middleware, A2A, MCP, caching
|
|
9
|
+
> **Ref:** `framework/standards/backend/database/vector-search-rag.md` — Vector Search + RAG with EF Core 10
|
|
10
10
|
|
|
11
11
|
## Responsibilities
|
|
12
12
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# API Designer
|
|
2
|
+
|
|
3
|
+
**Tier:** 3 (Specialist)
|
|
4
|
+
**Always Active:** No
|
|
5
|
+
**Keywords:** api, endpoint, controller, rest, http, route, dto, request, response
|
|
6
|
+
**Reports to:** dotnet-senior
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Role
|
|
11
|
+
|
|
12
|
+
REST API design specialist for .NET Minimal API and controllers, focusing on clean endpoint design and DTO contracts.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Standards Applied
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
framework/standards/core/coding.md
|
|
20
|
+
framework/standards/backend/dotnet/core.md
|
|
21
|
+
framework/standards/backend/dotnet/async.md
|
|
22
|
+
framework/standards/backend/api/rest.md
|
|
23
|
+
framework/standards/backend/api/validation.md
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Responsibilities
|
|
29
|
+
|
|
30
|
+
- Design REST API endpoints following conventions
|
|
31
|
+
- Create request/response DTOs
|
|
32
|
+
- Implement API controllers or Minimal API endpoints
|
|
33
|
+
- Apply proper HTTP status codes (200, 201, 400, 404, etc.)
|
|
34
|
+
- Implement input validation with FluentValidation
|
|
35
|
+
- Design API versioning strategy
|
|
36
|
+
- Create error response formats
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## When to Use
|
|
41
|
+
|
|
42
|
+
- Creating new API endpoints
|
|
43
|
+
- Designing DTO contracts
|
|
44
|
+
- API refactoring
|
|
45
|
+
- Implementing validation logic
|
|
46
|
+
- Designing error responses
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Collaborates With
|
|
51
|
+
|
|
52
|
+
- **dotnet-senior** - Service layer consumed by endpoints
|
|
53
|
+
- **ef-modeler** - Entity → DTO mapping
|
|
54
|
+
- **blazor-builder** - Frontend consuming API
|
|
55
|
+
- **testing-specialist** - API integration tests
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
*MORPH-SPEC by Polymorphism Tech*
|