@polymorphism-tech/morph-spec 3.0.0 → 3.1.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 +68 -400
- package/README.md +198 -76
- package/bin/detect-agents.js +227 -225
- package/bin/morph-spec.js +10 -0
- package/bin/render-template.js +303 -302
- package/bin/semantic-detect-agents.js +247 -246
- package/bin/{task-manager.js → task-manager.cjs} +12 -1
- package/bin/validate-agents-skills.js +257 -251
- package/bin/validate-agents.js +70 -69
- package/bin/validate-phase.js +263 -263
- package/docs/getting-started.md +3 -3
- package/package.json +3 -4
- package/scripts/reorganize-skills.cjs +175 -0
- package/scripts/validate-agents-structure.cjs +52 -0
- package/scripts/validate-skills.cjs +180 -0
- package/src/commands/create-story.js +354 -351
- package/src/commands/detect-agents.js +13 -2
- package/src/commands/detect.js +104 -104
- package/src/commands/state.js +334 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/task.js +1 -1
- package/src/commands/update.js +13 -1
- package/src/lib/context-generator.js +7 -4
- package/{detectors → src/lib/detectors}/config-detector.js +223 -223
- package/{detectors → src/lib/detectors}/conversation-analyzer.js +163 -163
- package/{detectors → src/lib/detectors}/index.js +84 -84
- package/{detectors → src/lib/detectors}/standards-generator.js +275 -275
- package/src/lib/hook-executor.js +2 -1
- package/src/lib/stack-resolver.js +148 -0
- package/src/lib/standards-context-injector.js +4 -3
- package/src/lib/state-manager.js +21 -4
- package/src/lib/team-orchestrator.js +2 -1
- package/src/lib/troubleshoot-grep.js +13 -3
- package/src/lib/validation-runner.js +2 -1
- package/src/utils/file-copier.js +3 -1
- package/{content → stacks/blazor-azure}/.azure/README.md +293 -293
- package/{content → stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +454 -454
- package/{content → stacks/blazor-azure}/.azure/docs/branch-strategy.md +398 -398
- package/{content → stacks/blazor-azure}/.azure/docs/local-development.md +515 -515
- package/{content → stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +34 -34
- package/{content → stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +319 -319
- package/{content → stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +234 -234
- package/{content → stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/{content → stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/{content → stacks/blazor-azure}/.claude/commands/morph-archive.md +79 -79
- package/{content → stacks/blazor-azure}/.claude/commands/morph-deploy.md +529 -529
- package/{content → stacks/blazor-azure}/.claude/commands/morph-infra.md +209 -209
- package/{content → stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +1 -1
- package/{content → stacks/blazor-azure}/.claude/settings.local.json +15 -15
- package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
- package/{content/.claude/skills/specialists → stacks/blazor-azure/.claude/skills/level-2-domains/architecture}/prompt-engineer.md +189 -189
- package/{content/.claude/skills/specialists → stacks/blazor-azure/.claude/skills/level-2-domains/architecture}/seo-growth-hacker.md +320 -320
- package/{content/.claude/skills/infra → stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure}/azure-deploy-specialist.md +699 -699
- package/{content → stacks/blazor-azure}/.morph/.morphversion +5 -5
- package/{content → stacks/blazor-azure}/.morph/archive/.gitkeep +25 -25
- package/{content → stacks/blazor-azure}/.morph/config/agents.json +7 -5
- package/{content → stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/{content → stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
- package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +241 -241
- package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +399 -399
- package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +168 -168
- package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/README.md +125 -125
- package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +358 -358
- package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +246 -246
- package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +236 -236
- package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +150 -150
- package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/README.md +309 -309
- package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +433 -433
- package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +479 -479
- package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +185 -185
- package/{content → stacks/blazor-azure}/.morph/examples/state-v3.json +188 -188
- package/{content → stacks/blazor-azure}/.morph/features/.gitkeep +25 -25
- package/{content → stacks/blazor-azure}/.morph/hooks/README.md +12 -12
- package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +48 -48
- package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +49 -49
- package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +60 -60
- package/{content → stacks/blazor-azure}/.morph/project.md +160 -160
- package/{content → stacks/blazor-azure}/.morph/schemas/agent.schema.json +296 -296
- package/{content → stacks/blazor-azure}/.morph/specs/.gitkeep +20 -20
- package/{content → stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
- package/{content → stacks/blazor-azure}/.morph/standards/coding.md +377 -377
- package/{content → stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +590 -590
- package/{content → stacks/blazor-azure}/.morph/standards/migration-guide.md +514 -514
- package/{content → stacks/blazor-azure}/.morph/standards/passkeys-auth.md +423 -423
- package/{content → stacks/blazor-azure}/.morph/standards/vector-search-rag.md +536 -536
- package/{content → stacks/blazor-azure}/.morph/state.json +17 -17
- package/{content → stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +149 -149
- package/{content → stacks/blazor-azure}/.morph/templates/MudTheme.cs +281 -281
- package/{content → stacks/blazor-azure}/.morph/templates/component.razor +239 -239
- package/{content → stacks/blazor-azure}/.morph/templates/contracts.cs +217 -217
- package/{content → stacks/blazor-azure}/.morph/templates/design-system.css +226 -226
- package/{content → stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +89 -89
- package/{content → stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +82 -82
- package/{content → stacks/blazor-azure}/.morph/templates/infra/README.md +286 -286
- package/{content → stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +63 -63
- package/{content → stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +164 -164
- package/{content → stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +480 -480
- package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +49 -49
- package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +156 -156
- package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +229 -229
- package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.sh +208 -208
- package/{content → stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +91 -91
- package/{content → stacks/blazor-azure}/.morph/templates/infra/main.bicep +189 -189
- package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +29 -29
- package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +29 -29
- package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +29 -29
- package/{content → stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +103 -103
- package/{content → stacks/blazor-azure}/.morph/templates/infra/storage.bicep +106 -106
- package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +387 -387
- package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/{content → stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/{content → stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +258 -258
- package/{content → stacks/blazor-azure}/.morph/templates/job.cs +171 -171
- package/{content → stacks/blazor-azure}/.morph/templates/migration.cs +83 -83
- package/{content → stacks/blazor-azure}/.morph/templates/repository.cs +141 -141
- package/{content → stacks/blazor-azure}/.morph/templates/saas/subscription.cs +347 -347
- package/{content → stacks/blazor-azure}/.morph/templates/saas/tenant.cs +338 -338
- package/{content → stacks/blazor-azure}/.morph/templates/service.cs +139 -139
- package/{content → stacks/blazor-azure}/.morph/templates/sprint-status.yaml +68 -68
- package/{content → stacks/blazor-azure}/.morph/templates/story.md +143 -143
- package/{content → stacks/blazor-azure}/.morph/templates/test.cs +239 -239
- package/{content → stacks/blazor-azure}/.morph/templates/ui-design-system.md +286 -286
- package/{content → stacks/blazor-azure}/.morph/templates/ui-flows.md +336 -336
- package/{content → stacks/blazor-azure}/.morph/templates/ui-mockups.md +133 -133
- package/{content → stacks/blazor-azure}/.morph/test-infra/example.bicep +59 -59
- package/{content → stacks/blazor-azure}/README.md +79 -79
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
- package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
- package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
- package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
- package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
- package/stacks/nextjs-supabase/.morph/project.md +168 -0
- package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
- package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
- package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
- package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
- package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
- package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
- package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
- package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
- package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
- package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
- package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
- package/stacks/nextjs-supabase/CLAUDE.md +149 -0
- package/stacks/nextjs-supabase/README.md +112 -0
- /package/{detectors → src/lib/detectors}/structure-detector.js +0 -0
- /package/{content → stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/commands/morph-preflight.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
- /package/{content → stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/config/config.template.json +0 -0
- /package/{content → stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
- /package/{content → stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
- /package/{content → stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
- /package/{content → stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/azure.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/recap.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/spec.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
- /package/{content → stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
- /package/{content → stacks/blazor-azure}/CLAUDE.md +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack Resolver - Centralized stack path resolution for multi-stack support.
|
|
3
|
+
*
|
|
4
|
+
* Detects the active stack and resolves all stack-relative paths.
|
|
5
|
+
* Resolution order: explicit > config.json > state.json > auto-detect > fallback
|
|
6
|
+
*
|
|
7
|
+
* @module stack-resolver
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readFileSync, existsSync, readdirSync } from 'fs';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
|
|
13
|
+
const STACK_TYPE_TO_DIR = {
|
|
14
|
+
'blazor-server': 'blazor-azure',
|
|
15
|
+
'blazor-azure': 'blazor-azure',
|
|
16
|
+
'nextjs-supabase': 'nextjs-supabase',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Module-level override set by CLI --stack flag via setGlobalStack()
|
|
20
|
+
let _globalStackOverride = null;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Set a global stack override (called by CLI --stack flag).
|
|
24
|
+
* Once set, all resolveStackId() calls use this value unless
|
|
25
|
+
* an explicit parameter is provided.
|
|
26
|
+
* @param {string} stackId - Stack identifier
|
|
27
|
+
*/
|
|
28
|
+
export function setGlobalStack(stackId) {
|
|
29
|
+
_globalStackOverride = stackId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Detect which stack directory to use.
|
|
34
|
+
*
|
|
35
|
+
* Resolution order:
|
|
36
|
+
* 1. explicitStack parameter (from CLI --stack flag)
|
|
37
|
+
* 2. .morph/config/config.json → project.type
|
|
38
|
+
* 3. .morph/state.json → project.type
|
|
39
|
+
* 4. Auto-detect: scan stacks/ for existing directories
|
|
40
|
+
* 5. Fallback: 'blazor-azure'
|
|
41
|
+
*
|
|
42
|
+
* @param {string} projectPath - Absolute path to project root
|
|
43
|
+
* @param {string} [explicitStack] - Override from CLI --stack flag
|
|
44
|
+
* @returns {string} Stack directory name (e.g., 'blazor-azure', 'nextjs-supabase')
|
|
45
|
+
*/
|
|
46
|
+
export function resolveStackId(projectPath, explicitStack) {
|
|
47
|
+
// 1. Explicit parameter override
|
|
48
|
+
if (explicitStack) {
|
|
49
|
+
return STACK_TYPE_TO_DIR[explicitStack] || explicitStack;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 1b. Global CLI --stack override
|
|
53
|
+
if (_globalStackOverride) {
|
|
54
|
+
return STACK_TYPE_TO_DIR[_globalStackOverride] || _globalStackOverride;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 2. config.json → project.type
|
|
58
|
+
try {
|
|
59
|
+
const configPath = join(projectPath, '.morph/config/config.json');
|
|
60
|
+
if (existsSync(configPath)) {
|
|
61
|
+
const config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
62
|
+
const projectType = config?.project?.type;
|
|
63
|
+
if (projectType && STACK_TYPE_TO_DIR[projectType]) {
|
|
64
|
+
return STACK_TYPE_TO_DIR[projectType];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} catch { /* continue to next source */ }
|
|
68
|
+
|
|
69
|
+
// 3. state.json → project.type
|
|
70
|
+
try {
|
|
71
|
+
const statePath = join(projectPath, '.morph/state.json');
|
|
72
|
+
if (existsSync(statePath)) {
|
|
73
|
+
const state = JSON.parse(readFileSync(statePath, 'utf8'));
|
|
74
|
+
const projectType = state?.project?.type;
|
|
75
|
+
if (projectType && STACK_TYPE_TO_DIR[projectType]) {
|
|
76
|
+
return STACK_TYPE_TO_DIR[projectType];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} catch { /* continue to next source */ }
|
|
80
|
+
|
|
81
|
+
// 4. Auto-detect: first directory in stacks/
|
|
82
|
+
try {
|
|
83
|
+
const stacksDir = join(projectPath, 'stacks');
|
|
84
|
+
if (existsSync(stacksDir)) {
|
|
85
|
+
const dirs = readdirSync(stacksDir, { withFileTypes: true })
|
|
86
|
+
.filter(d => d.isDirectory())
|
|
87
|
+
.map(d => d.name);
|
|
88
|
+
if (dirs.length === 1) {
|
|
89
|
+
return dirs[0];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} catch { /* continue to fallback */ }
|
|
93
|
+
|
|
94
|
+
// 5. Fallback
|
|
95
|
+
return 'blazor-azure';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get absolute path to the active stack's root directory.
|
|
100
|
+
* @param {string} projectPath
|
|
101
|
+
* @param {string} [explicitStack]
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
export function resolveStackPath(projectPath, explicitStack) {
|
|
105
|
+
return join(projectPath, 'stacks', resolveStackId(projectPath, explicitStack));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get absolute path to the active stack's agents.json.
|
|
110
|
+
* @param {string} projectPath
|
|
111
|
+
* @param {string} [explicitStack]
|
|
112
|
+
* @returns {string}
|
|
113
|
+
*/
|
|
114
|
+
export function resolveAgentsConfigPath(projectPath, explicitStack) {
|
|
115
|
+
return join(resolveStackPath(projectPath, explicitStack), '.morph/config/agents.json');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Get absolute path to the active stack's standards directory.
|
|
120
|
+
* @param {string} projectPath
|
|
121
|
+
* @param {string} [explicitStack]
|
|
122
|
+
* @returns {string}
|
|
123
|
+
*/
|
|
124
|
+
export function resolveStandardsDir(projectPath, explicitStack) {
|
|
125
|
+
return join(resolveStackPath(projectPath, explicitStack), '.morph/standards');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get absolute path to the active stack's templates directory.
|
|
130
|
+
* @param {string} projectPath
|
|
131
|
+
* @param {string} [explicitStack]
|
|
132
|
+
* @returns {string}
|
|
133
|
+
*/
|
|
134
|
+
export function resolveTemplatesDir(projectPath, explicitStack) {
|
|
135
|
+
return join(resolveStackPath(projectPath, explicitStack), '.morph/templates');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get absolute path to the active stack's config directory.
|
|
140
|
+
* @param {string} projectPath
|
|
141
|
+
* @param {string} [explicitStack]
|
|
142
|
+
* @returns {string}
|
|
143
|
+
*/
|
|
144
|
+
export function resolveConfigDir(projectPath, explicitStack) {
|
|
145
|
+
return join(resolveStackPath(projectPath, explicitStack), '.morph/config');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { STACK_TYPE_TO_DIR };
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { readFileSync, existsSync } from 'fs';
|
|
11
11
|
import { join } from 'path';
|
|
12
|
+
import { resolveStandardsDir } from './stack-resolver.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Agent → Standards mapping
|
|
@@ -191,8 +192,8 @@ function loadStandard(standardName, projectPath) {
|
|
|
191
192
|
const locations = [
|
|
192
193
|
// 1. Project override
|
|
193
194
|
join(projectPath, '.morph/project/standards', `${standardName}.md`),
|
|
194
|
-
// 2.
|
|
195
|
-
join(projectPath,
|
|
195
|
+
// 2. Stack standards (resolved dynamically based on project type)
|
|
196
|
+
join(resolveStandardsDir(projectPath), `${standardName}.md`),
|
|
196
197
|
// 3. Framework standards (Blazor, CSS, .NET)
|
|
197
198
|
join(projectPath, 'framework/standards', `${standardName}.md`)
|
|
198
199
|
];
|
|
@@ -273,7 +274,7 @@ export function getStandardsListForAgent(agentId) {
|
|
|
273
274
|
export function checkStandardExists(standardName, projectPath = '.') {
|
|
274
275
|
const locations = [
|
|
275
276
|
{ type: 'project', path: join(projectPath, '.morph/project/standards', `${standardName}.md`) },
|
|
276
|
-
{ type: '
|
|
277
|
+
{ type: 'stack', path: join(resolveStandardsDir(projectPath), `${standardName}.md`) },
|
|
277
278
|
{ type: 'framework', path: join(projectPath, 'framework/standards', `${standardName}.md`) }
|
|
278
279
|
];
|
|
279
280
|
|
package/src/lib/state-manager.js
CHANGED
|
@@ -291,6 +291,21 @@ export function removeAgent(featureName, agentId) {
|
|
|
291
291
|
return false;
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Normalize output type from kebab-case to camelCase for UI types (BUG #12 fix)
|
|
296
|
+
* @param {string} type - Output type (e.g., 'ui-design-system' or 'uiDesignSystem')
|
|
297
|
+
* @returns {string} Normalized type in camelCase
|
|
298
|
+
*/
|
|
299
|
+
function normalizeOutputType(type) {
|
|
300
|
+
const kebabMap = {
|
|
301
|
+
'ui-design-system': 'uiDesignSystem',
|
|
302
|
+
'ui-mockups': 'uiMockups',
|
|
303
|
+
'ui-components': 'uiComponents',
|
|
304
|
+
'ui-flows': 'uiFlows'
|
|
305
|
+
};
|
|
306
|
+
return kebabMap[type] || type;
|
|
307
|
+
}
|
|
308
|
+
|
|
294
309
|
/**
|
|
295
310
|
* Mark output as created
|
|
296
311
|
* @param {string} featureName - Feature name
|
|
@@ -300,15 +315,17 @@ export function markOutput(featureName, outputType) {
|
|
|
300
315
|
ensureFeature(featureName);
|
|
301
316
|
const state = loadState();
|
|
302
317
|
|
|
303
|
-
|
|
304
|
-
|
|
318
|
+
const normalized = normalizeOutputType(outputType);
|
|
319
|
+
|
|
320
|
+
if (!state.features[featureName].outputs[normalized]) {
|
|
321
|
+
throw new Error(`Output type '${outputType}' not valid. Valid types: proposal, spec, contracts, tasks, uiDesignSystem (or ui-design-system), uiMockups (or ui-mockups), uiComponents (or ui-components), uiFlows (or ui-flows), decisions, recap`);
|
|
305
322
|
}
|
|
306
323
|
|
|
307
|
-
state.features[featureName].outputs[
|
|
324
|
+
state.features[featureName].outputs[normalized].created = true;
|
|
308
325
|
state.features[featureName].updatedAt = new Date().toISOString();
|
|
309
326
|
|
|
310
327
|
// If marking tasks output, try to sync task count from state tasks array
|
|
311
|
-
if (
|
|
328
|
+
if (normalized === 'tasks') {
|
|
312
329
|
syncTasksCount(state.features[featureName]);
|
|
313
330
|
}
|
|
314
331
|
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import fs from 'fs/promises';
|
|
14
14
|
import path from 'path';
|
|
15
15
|
import { fileURLToPath } from 'url';
|
|
16
|
+
import { resolveAgentsConfigPath } from './stack-resolver.js';
|
|
16
17
|
|
|
17
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
19
|
const __dirname = path.dirname(__filename);
|
|
@@ -23,7 +24,7 @@ const __dirname = path.dirname(__filename);
|
|
|
23
24
|
* @returns {Promise<Object>} Parsed agents configuration
|
|
24
25
|
*/
|
|
25
26
|
async function loadAgentsConfig(projectPath) {
|
|
26
|
-
const agentsPath =
|
|
27
|
+
const agentsPath = resolveAgentsConfigPath(projectPath);
|
|
27
28
|
const content = await fs.readFile(agentsPath, 'utf8');
|
|
28
29
|
return JSON.parse(content);
|
|
29
30
|
}
|
|
@@ -6,17 +6,27 @@
|
|
|
6
6
|
import { readFileSync, readdirSync, existsSync } from 'fs';
|
|
7
7
|
import { join, dirname, basename } from 'path';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
|
+
import { resolveStandardsDir } from './stack-resolver.js';
|
|
9
10
|
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = dirname(__filename);
|
|
13
|
+
const frameworkRoot = join(__dirname, '..', '..');
|
|
12
14
|
|
|
13
|
-
// Directories to search
|
|
15
|
+
// Directories to search (stack standards resolved dynamically)
|
|
14
16
|
const SEARCH_PATHS = [
|
|
15
17
|
'framework/standards',
|
|
16
|
-
'content/.morph/standards',
|
|
17
18
|
'.wiki'
|
|
18
19
|
];
|
|
19
20
|
|
|
21
|
+
function getSearchPaths(basePath) {
|
|
22
|
+
const paths = [...SEARCH_PATHS];
|
|
23
|
+
// Insert resolved stack standards path
|
|
24
|
+
const stackStandards = resolveStandardsDir(basePath || frameworkRoot);
|
|
25
|
+
const relativePath = stackStandards.replace(basePath || frameworkRoot, '').replace(/^[\\/]/, '');
|
|
26
|
+
paths.splice(1, 0, relativePath);
|
|
27
|
+
return paths;
|
|
28
|
+
}
|
|
29
|
+
|
|
20
30
|
/**
|
|
21
31
|
* Get all markdown files from search paths
|
|
22
32
|
* @param {string} basePath - Base path of the project
|
|
@@ -25,7 +35,7 @@ const SEARCH_PATHS = [
|
|
|
25
35
|
function getMarkdownFiles(basePath) {
|
|
26
36
|
const files = [];
|
|
27
37
|
|
|
28
|
-
for (const searchPath of
|
|
38
|
+
for (const searchPath of getSearchPaths(basePath)) {
|
|
29
39
|
const fullPath = join(basePath, searchPath);
|
|
30
40
|
|
|
31
41
|
if (!existsSync(fullPath)) {
|
|
@@ -12,6 +12,7 @@ import { join } from 'path';
|
|
|
12
12
|
import chalk from 'chalk';
|
|
13
13
|
import { loadState } from './state-manager.js';
|
|
14
14
|
import { loadConstraints } from './decision-constraint-loader.js';
|
|
15
|
+
import { resolveAgentsConfigPath } from './stack-resolver.js';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Load agent → validators map from agents.json (data-driven)
|
|
@@ -20,7 +21,7 @@ import { loadConstraints } from './decision-constraint-loader.js';
|
|
|
20
21
|
*/
|
|
21
22
|
function loadAgentValidatorMap(projectPath) {
|
|
22
23
|
try {
|
|
23
|
-
const agentsPath =
|
|
24
|
+
const agentsPath = resolveAgentsConfigPath(projectPath);
|
|
24
25
|
const agentsConfig = JSON.parse(readFileSync(agentsPath, 'utf8'));
|
|
25
26
|
|
|
26
27
|
const map = {};
|
package/src/utils/file-copier.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import { join, dirname, resolve } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
+
import { resolveStackPath } from '../lib/stack-resolver.js';
|
|
4
5
|
|
|
5
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const frameworkRoot = join(__dirname, '..', '..');
|
|
6
8
|
|
|
7
9
|
function isSamePath(a, b) {
|
|
8
10
|
return resolve(a) === resolve(b);
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export function getContentDir() {
|
|
12
|
-
return
|
|
14
|
+
return resolveStackPath(frameworkRoot);
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export async function copyDirectory(src, dest, options = {}) {
|