@polymorphism-tech/morph-spec 8.47.0 → 9.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 +51 -43
- package/README.md +39 -38
- package/bin/morph-spec.js +41 -113
- package/bin/validate.js +1 -147
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +41 -101
- package/framework/MORPH.md +95 -252
- package/framework/agents.json +86 -21
- package/framework/commands/morph-apply.md +5 -28
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-hotfix.md +8 -8
- package/framework/commands/morph-infra.md +1 -1
- package/framework/commands/morph-preflight.md +2 -3
- package/framework/commands/morph-status.md +4 -4
- package/framework/docs/CLI.md +574 -286
- package/framework/evals/review-checklist.md +82 -41
- package/framework/hooks/README.md +10 -11
- package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
- package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
- package/framework/hooks/claude-code/core/chain.js +4 -65
- package/framework/hooks/claude-code/core/comment-guard.js +3 -17
- package/framework/hooks/claude-code/core/denylist.json +33 -3
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +15 -63
- package/framework/hooks/claude-code/core/gate-guard.js +9 -78
- package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
- package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
- package/framework/hooks/claude-code/core/heavy-release.js +2 -13
- package/framework/hooks/claude-code/core/loop-detect.js +2 -31
- package/framework/hooks/claude-code/core/pre-bash-denylist.js +36 -2
- package/framework/hooks/claude-code/core/protect-spec-files.js +25 -297
- package/framework/hooks/claude-code/core/state-sync.js +15 -85
- package/framework/hooks/claude-code/core/telemetry-log.js +15 -96
- package/framework/hooks/claude-code/core/validate-completion.js +37 -147
- package/framework/hooks/claude-code/core/warn-bash-source-write.js +23 -0
- package/framework/hooks/claude-code/core/worktree-context.js +15 -114
- package/framework/hooks/claude-code/core/worktree-create.js +6 -70
- package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
- package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
- package/framework/hooks/claude-code/statusline.py +55 -41
- package/framework/hooks/package.json +3 -0
- package/framework/hooks/shared/activity-logger.js +9 -89
- package/framework/hooks/shared/agent-reap.js +2 -17
- package/framework/hooks/shared/build-check.js +11 -76
- package/framework/hooks/shared/claim-registry.js +9 -119
- package/framework/hooks/shared/command-tokens.js +168 -44
- package/framework/hooks/shared/comment-rules.js +5 -20
- package/framework/hooks/shared/comment-scanner.js +11 -43
- package/framework/hooks/shared/comment-stripper.js +11 -85
- package/framework/hooks/shared/e2e-check.js +0 -0
- package/framework/hooks/shared/errata.js +59 -0
- package/framework/hooks/shared/feature-locator.js +11 -95
- package/framework/hooks/shared/frontend-locations.js +4 -0
- package/framework/hooks/shared/gate-question.js +12 -0
- package/framework/hooks/shared/git-exclude.js +3 -20
- package/framework/hooks/shared/git-paths.js +8 -104
- package/framework/hooks/shared/graph-freshness.js +22 -166
- package/framework/hooks/shared/graph-refresh.js +21 -149
- package/framework/hooks/shared/heavy-command.js +4 -12
- package/framework/hooks/shared/hook-response.js +8 -83
- package/framework/hooks/shared/morph-cli.js +8 -52
- package/framework/hooks/shared/payload-utils.js +10 -132
- package/framework/hooks/shared/phase-utils.js +14 -72
- package/framework/hooks/shared/redact-secrets.js +4 -15
- package/framework/hooks/shared/reparse-scan.js +6 -66
- package/framework/hooks/shared/slice-progress.js +99 -0
- package/framework/hooks/shared/source-files.js +4 -17
- package/framework/hooks/shared/spawn-command.js +23 -0
- package/framework/hooks/shared/state-reader.js +51 -247
- package/framework/hooks/shared/state-writer.js +9 -54
- package/framework/hooks/shared/stdin-reader.js +1 -11
- package/framework/hooks/shared/telemetry-logger.js +7 -67
- package/framework/hooks/shared/transcript-usage.js +7 -29
- package/framework/hooks/shared/worktree-root.js +7 -29
- package/framework/mcp/registry.json +3 -4
- package/framework/phases.json +23 -39
- package/framework/rules/csharp-standards.md +1 -1
- package/framework/rules/frontend-standards.md +1 -0
- package/framework/rules/hangfire-standards.md +1 -1
- package/framework/rules/neon-standards.md +1 -1
- package/framework/schemas/config.schema.json +14 -9
- package/framework/schemas/feature.schema.json +15 -50
- package/framework/skills/README.md +3 -4
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +149 -222
- package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
- package/framework/skills/core/morph-machine/SKILL.md +2 -2
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +137 -299
- package/framework/skills/core/morph-review/SKILL.md +111 -136
- package/framework/skills/core/morph-standards/SKILL.md +27 -39
- package/framework/skills/core/morph-uiux/SKILL.md +94 -152
- package/framework/standards/STANDARDS.json +109 -1219
- package/framework/standards/STANDARDS.meta.json +1319 -0
- package/framework/standards/ai-agents/agent-archetypes.md +2 -2
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
- package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
- package/framework/standards/ai-agents/evals-with-cache.md +1 -2
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
- package/framework/standards/ai-agents/observability-patterns.md +1 -1
- package/framework/standards/ai-agents/production.md +1 -1
- package/framework/standards/ai-agents/prompt-sources.md +2 -2
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
- package/framework/standards/ai-agents/setup.md +3 -3
- package/framework/standards/ai-agents/sweet-spot.md +2 -2
- package/framework/standards/ai-agents/tool-adapters.md +0 -2
- package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/standards/architecture/code-comments.md +7 -7
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
- package/framework/standards/backend/api/validation.md +1 -1
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
- package/framework/standards/data/nosql/cache/redis.md +1 -1
- package/framework/standards/data/nosql/cosmos-db.md +3 -3
- package/framework/standards/frontend/admin-app/forms.md +1 -1
- package/framework/standards/frontend/design-system/art-direction.md +88 -0
- package/framework/standards/frontend/design-system/premium-finish.md +77 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
- package/framework/standards/integration/mcp/mcp-tools.md +7 -7
- package/framework/templates/CLAUDE.md.core.template +3 -3
- package/framework/templates/README.md +2 -3
- package/framework/templates/REGISTRY.json +15 -179
- package/framework/templates/docs/plan.md +72 -0
- package/framework/templates/docs/ui-mockups.md +4 -0
- package/framework/templates/dotnet/ai-kit/README.md +1 -9
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
- package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
- package/package.json +1 -1
- package/src/commands/context/context-refresh.js +0 -16
- package/src/commands/dashboard/dashboard.js +2 -8
- package/src/commands/e2e/e2e.js +18 -105
- package/src/commands/graph/affected.js +0 -14
- package/src/commands/graph/build.js +11 -50
- package/src/commands/graph/explain.js +0 -16
- package/src/commands/graph/status.js +1 -12
- package/src/commands/mcp/mcp-setup.js +4 -62
- package/src/commands/observability/cost.js +17 -111
- package/src/commands/observability/telemetry.js +1 -14
- package/src/commands/project/branch.js +4 -45
- package/src/commands/project/claim.js +4 -48
- package/src/commands/project/doctor-procs.js +1 -1
- package/src/commands/project/doctor.js +53 -307
- package/src/commands/project/env.js +1 -27
- package/src/commands/project/fleet.js +6 -35
- package/src/commands/project/heavy.js +3 -3
- package/src/commands/project/init.js +8 -68
- package/src/commands/project/install-plugin-cmd.js +0 -1
- package/src/commands/project/setup-infra-cmd.js +2 -1
- package/src/commands/project/stack-scan.js +58 -0
- package/src/commands/project/standards.js +65 -72
- package/src/commands/project/status.js +28 -121
- package/src/commands/project/update.js +31 -223
- package/src/commands/project/worktree.js +109 -883
- package/src/commands/scaffold/scaffold.js +0 -25
- package/src/commands/state/advance.js +65 -120
- package/src/commands/state/approve.js +87 -229
- package/src/commands/state/archive.js +23 -139
- package/src/commands/state/auto-approval.js +65 -0
- package/src/commands/state/create.js +49 -109
- package/src/commands/state/delete.js +11 -63
- package/src/commands/state/finish.js +105 -494
- package/src/commands/state/gate-check.js +74 -183
- package/src/commands/state/gate-decision.js +8 -42
- package/src/commands/state/handoff.js +4 -31
- package/src/commands/state/list.js +21 -91
- package/src/commands/state/report-check.js +134 -338
- package/src/commands/state/retype.js +12 -28
- package/src/commands/validation/index.js +0 -3
- package/src/commands/validation/mutate.js +79 -19
- package/src/commands/validation/plan-check.js +81 -0
- package/src/commands/validation/validate-feature.js +52 -216
- package/src/commands/validation/verify.js +45 -160
- package/src/core/paths/output-schema.js +9 -155
- package/src/core/state/feature-identity.js +1 -25
- package/src/core/state/gate-order.js +2 -30
- package/src/core/state/lifecycle-audit.js +8 -100
- package/src/core/state/state-manager.js +32 -395
- package/src/core/templates/template-registry.js +2 -97
- package/src/core/templates/template-renderer.js +13 -93
- package/src/core/templates/template-seed.js +21 -0
- package/src/core/work-types.js +10 -45
- package/src/dashboard/app/App.jsx +1 -8
- package/src/dashboard/app/components/ActivityFeed.jsx +2 -8
- package/src/dashboard/app/components/CommandPalette.jsx +4 -11
- package/src/dashboard/app/components/DetailPanel.jsx +1 -5
- package/src/dashboard/app/components/EntityLink.jsx +0 -12
- package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
- package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
- package/src/dashboard/app/components/Markdown.jsx +0 -9
- package/src/dashboard/app/components/PhaseRail.jsx +0 -11
- package/src/dashboard/app/components/SearchFilter.jsx +0 -4
- package/src/dashboard/app/components/Sidebar.jsx +0 -5
- package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
- package/src/dashboard/app/hooks/usePref.js +1 -5
- package/src/dashboard/app/lib/format.js +0 -2
- package/src/dashboard/app/lib/phases.js +3 -9
- package/src/dashboard/app/lib/project.js +0 -12
- package/src/dashboard/app/pages/Activity.jsx +1 -1
- package/src/dashboard/app/pages/AgentMap.jsx +1 -8
- package/src/dashboard/app/pages/FeatureDetail.jsx +139 -133
- package/src/dashboard/app/pages/Features.jsx +9 -16
- package/src/dashboard/app/pages/Guide.jsx +2 -3
- package/src/dashboard/app/pages/HookInspector.jsx +2 -23
- package/src/dashboard/app/pages/PhasePipeline.jsx +3 -7
- package/src/dashboard/app/pages/Portfolio.jsx +0 -1
- package/src/dashboard/app/pages/RulesMap.jsx +1 -16
- package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
- package/src/dashboard/app/pages/Standards.jsx +2 -17
- package/src/dashboard/scanner/activity-scanner.js +14 -83
- package/src/dashboard/scanner/agents-scanner.js +1 -23
- package/src/dashboard/scanner/docs-scanner.js +1 -7
- package/src/dashboard/scanner/feature-status.js +2 -5
- package/src/dashboard/scanner/features-scanner.js +92 -113
- package/src/dashboard/scanner/hooks-scanner.js +5 -28
- package/src/dashboard/scanner/index.js +0 -4
- package/src/dashboard/scanner/portfolio.js +5 -29
- package/src/dashboard/scanner/project-api.js +8 -54
- package/src/dashboard/scanner/rules-scanner.js +1 -2
- package/src/dashboard/scanner/skills-scanner.js +2 -12
- package/src/dashboard/scanner/standards-scanner.js +4 -7
- package/src/dashboard/vite-plugin-morph-data.js +5 -19
- package/src/lib/ai/ai-checks.js +7 -52
- package/src/lib/ai/ai-project-scan.js +14 -108
- package/src/lib/ai/code-audit.js +7 -63
- package/src/lib/ai/pin-drift.js +8 -51
- package/src/lib/ai/registry-audit.js +11 -90
- package/src/lib/ci/ci-verify.js +14 -13
- package/src/lib/ci/github-ci.js +9 -37
- package/src/lib/ci/workflow-scaffold.js +2 -10
- package/src/lib/detectors/claude-config-detector.js +13 -74
- package/src/lib/detectors/index.js +8 -59
- package/src/lib/e2e/compose-env.js +5 -66
- package/src/lib/e2e/stack-teardown.js +6 -40
- package/src/lib/generators/architecture-scanner.js +18 -156
- package/src/lib/generators/handoff-generator.js +37 -112
- package/src/lib/generators/scaffold-generator.js +5 -101
- package/src/lib/generators/settings-generator.js +11 -122
- package/src/lib/git/branch-classifier.js +11 -84
- package/src/lib/git/default-branch.js +14 -169
- package/src/lib/git/evidence-staleness.js +2 -1
- package/src/lib/git/gh.js +2 -17
- package/src/lib/git/pending-prs.js +6 -37
- package/src/lib/git/pr-files.js +3 -28
- package/src/lib/git/pr-index.js +3 -34
- package/src/lib/git/tree-fingerprint.js +17 -17
- package/src/lib/git/tree-state.js +6 -33
- package/src/lib/graph/god-nodes.js +2 -22
- package/src/lib/graph/graph-health.js +3 -24
- package/src/lib/graph/graph-loader.js +5 -56
- package/src/lib/graph/graphify-runtime.js +7 -37
- package/src/lib/graph/graphifyignore.js +8 -74
- package/src/lib/graph/sanitize.js +16 -136
- package/src/lib/heavy/cleanup.js +2 -6
- package/src/lib/installers/effects.js +8 -93
- package/src/lib/installers/mcp-installer.js +9 -169
- package/src/lib/installers/memory-installer.js +8 -33
- package/src/lib/installers/templates-reconcile.js +5 -60
- package/src/lib/mutation/commands.js +3 -2
- package/src/lib/mutation/dotnet-introspection.js +281 -0
- package/src/lib/mutation/plan.js +14 -6
- package/src/lib/mutation/runner.js +1 -1
- package/src/lib/mutation/subset.js +47 -13
- package/src/lib/plan/artifact-vocabulary.js +40 -0
- package/src/lib/plan/checks.js +208 -0
- package/src/lib/plan/plan-parser.js +204 -0
- package/src/lib/plan/plan-template.js +18 -0
- package/src/lib/projects/registry.js +7 -44
- package/src/lib/review-reports.js +204 -0
- package/src/lib/risk-detector.js +131 -274
- package/src/lib/specs/adr-index.js +38 -85
- package/src/lib/specs/design-seed.js +18 -0
- package/src/lib/specs/frontmatter.js +31 -0
- package/src/lib/specs/gfm-table.js +11 -0
- package/src/lib/specs/revocations.js +31 -102
- package/src/lib/specs/screen-checklist.js +56 -132
- package/src/lib/stack/dotnet-build-ignores.js +43 -0
- package/src/lib/stack/stack-profile.js +1 -28
- package/src/lib/stack/stack-scan.js +260 -0
- package/src/lib/stack-filter.js +4 -27
- package/src/lib/standards/registry.js +37 -0
- package/src/lib/standards/sections.js +47 -0
- package/src/lib/standards/verified-against.js +19 -191
- package/src/lib/tasks/eval-node.js +23 -179
- package/src/lib/tasks/linux-runner.js +18 -142
- package/src/lib/tasks/test-nodes.js +43 -313
- package/src/lib/tasks/test-runner.js +107 -447
- package/src/lib/telemetry/metrics.js +13 -103
- package/src/lib/telemetry/telemetry-reader.js +13 -238
- package/src/lib/telemetry/verify-event.js +4 -34
- package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
- package/src/lib/validators/code-budget/index.js +0 -7
- package/src/lib/validators/contracts/contract-compliance-validator.js +4 -26
- package/src/lib/validators/contracts/index.js +0 -6
- package/src/lib/validators/nextjs/index.js +0 -5
- package/src/lib/validators/nextjs/next-component-validator.js +4 -81
- package/src/lib/validators/packages/index.js +0 -6
- package/src/lib/validators/packages/package-validator.js +6 -56
- package/src/lib/validators/reuse/index.js +0 -8
- package/src/lib/validators/reuse/reuse-validator.js +24 -137
- package/src/lib/validators/reuse/symbol-scanner.js +6 -62
- package/src/lib/validators/traceability-check.js +54 -156
- package/src/lib/validators/validation-runner.js +20 -125
- package/src/lib/validators/verify-runner.js +152 -575
- package/src/lib/work-type-detector.js +5 -67
- package/src/lib/worktree/docker-audit.js +17 -137
- package/src/lib/worktree/env-allocator.js +10 -98
- package/src/lib/worktree/feature-truth.js +12 -115
- package/src/lib/worktree/finish-backup.js +32 -242
- package/src/lib/worktree/fleet-scanner.js +31 -126
- package/src/lib/worktree/ignored-triage.js +15 -91
- package/src/lib/worktree/vscode-settings.js +2 -3
- package/src/lib/worktree/worktree-audit.js +21 -213
- package/src/lib/worktree/worktree-include.js +3 -5
- package/src/scripts/global-install.js +3 -9
- package/src/scripts/install-plugin.js +1 -13
- package/src/scripts/setup-infra.js +17 -138
- package/src/utils/agents-installer.js +92 -272
- package/src/utils/banner.js +4 -25
- package/src/utils/claude-md-injector.js +1 -37
- package/src/utils/claude-settings-manager.js +1 -87
- package/src/utils/file-copier.js +32 -90
- package/src/utils/hooks-installer.js +26 -296
- package/src/utils/skills-installer.js +4 -102
- package/src/utils/version-checker.js +4 -83
- package/framework/commands/morph-proposal.md +0 -57
- package/framework/evals/trace-schema.md +0 -67
- package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
- package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
- package/framework/hooks/git/pre-commit/specs.sh +0 -50
- package/framework/hooks/shared/tasks-validator.js +0 -111
- package/framework/rules/morph-task-tracking.md +0 -54
- package/framework/rules/morph-workflow.md +0 -244
- package/framework/schemas/tasks.schema.json +0 -79
- package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
- package/framework/skills/core/morph-implement/SKILL.md +0 -194
- package/framework/skills/core/morph-proposal/SKILL.md +0 -152
- package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
- package/framework/templates/docs/proposal.md +0 -192
- package/framework/templates/docs/spec.md +0 -57
- package/framework/templates/docs/ui-components.md +0 -52
- package/framework/templates/docs/ui-design-system.md +0 -76
- package/framework/templates/docs/ui-flows.md +0 -167
- package/framework/templates/examples/spec-examples.md +0 -91
- package/framework/templates/feature/decisions.md +0 -124
- package/framework/templates/feature/recap.md +0 -145
- package/framework/templates/tasks.template.json +0 -17
- package/src/commands/state/usecase.js +0 -143
- package/src/commands/tasks/dag.js +0 -181
- package/src/commands/utils/index.js +0 -3
- package/src/lib/agents/output-collector.js +0 -76
- package/src/lib/detectors/design-system-detector.js +0 -188
- package/src/lib/evaluator-report.js +0 -104
- package/src/lib/generators/design-system-generator.js +0 -508
- package/src/lib/specs/acervo-format.js +0 -70
- package/src/lib/specs/acervo-lifecycle.js +0 -264
- package/src/lib/specs/done-criteria-check.js +0 -200
- package/src/lib/specs/usecase-check.js +0 -301
- package/src/lib/specs/usecase-promoter.js +0 -301
- package/src/lib/specs/usecase-registry.js +0 -237
- package/src/lib/tasks/dispatch-planner.js +0 -319
- package/src/lib/tasks/dotnet-test-introspection.js +0 -632
- package/src/lib/tasks/mermaid-renderer.js +0 -132
- package/src/lib/tasks/task-classifier.js +0 -30
- package/src/lib/tasks/task-parser.js +0 -209
- package/src/lib/tasks/tasks-json-parser.js +0 -296
- package/src/lib/tasks/test-scope.js +0 -597
- package/src/utils/agent-id-mapper.js +0 -11
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Design System Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects if a design system exists for the project or feature.
|
|
5
|
-
* Checks multiple locations in priority order.
|
|
6
|
-
*
|
|
7
|
-
* @module design-system-detector
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
11
|
-
import { join } from 'path';
|
|
12
|
-
|
|
13
|
-
const SKIP_DIRS = new Set(['node_modules', '.git', '.morph', 'dist', 'build', '.next', 'obj', 'bin', '.vs']);
|
|
14
|
-
const CSS_SCAN_MAX_DEPTH = 6;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Recursively walk a directory collecting files with given extensions.
|
|
18
|
-
* @param {string} dir - Directory to walk
|
|
19
|
-
* @param {string[]} extensions - File extensions to collect (e.g. ['.css', '.scss'])
|
|
20
|
-
* @param {string[]} files - Accumulator array (mutated in-place)
|
|
21
|
-
* @param {number} depth - Current recursion depth
|
|
22
|
-
* @param {number} maxDepth - Maximum recursion depth
|
|
23
|
-
*/
|
|
24
|
-
function walkDirForCss(dir, extensions, files, depth, maxDepth) {
|
|
25
|
-
if (depth > maxDepth) return;
|
|
26
|
-
let entries;
|
|
27
|
-
try {
|
|
28
|
-
entries = readdirSync(dir, { withFileTypes: true });
|
|
29
|
-
} catch {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
for (const entry of entries) {
|
|
33
|
-
if (entry.isDirectory()) {
|
|
34
|
-
if (!SKIP_DIRS.has(entry.name)) {
|
|
35
|
-
walkDirForCss(join(dir, entry.name), extensions, files, depth + 1, maxDepth);
|
|
36
|
-
}
|
|
37
|
-
} else if (entry.isFile()) {
|
|
38
|
-
const lower = entry.name.toLowerCase();
|
|
39
|
-
if (extensions.some(ext => lower.endsWith(ext))) {
|
|
40
|
-
files.push(join(dir, entry.name));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Detect design system for project or feature
|
|
48
|
-
* @param {string} projectPath - Root path of the project
|
|
49
|
-
* @param {string|null} featureName - Feature name (optional, checks feature-level if provided)
|
|
50
|
-
* @returns {Object} { hasDesignSystem, path, isProjectLevel, isFeatureLevel, source }
|
|
51
|
-
*/
|
|
52
|
-
export function detectDesignSystem(projectPath, featureName = null) {
|
|
53
|
-
const result = {
|
|
54
|
-
hasDesignSystem: false,
|
|
55
|
-
path: null,
|
|
56
|
-
isProjectLevel: false,
|
|
57
|
-
isFeatureLevel: false,
|
|
58
|
-
source: null
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// Priority 1: Feature-level design system (if feature specified)
|
|
62
|
-
if (featureName) {
|
|
63
|
-
const featureDesignSystemPath = join(
|
|
64
|
-
projectPath,
|
|
65
|
-
'.morph/features',
|
|
66
|
-
featureName,
|
|
67
|
-
'1-design',
|
|
68
|
-
'design-system.md'
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
if (existsSync(featureDesignSystemPath)) {
|
|
72
|
-
return {
|
|
73
|
-
hasDesignSystem: true,
|
|
74
|
-
path: featureDesignSystemPath,
|
|
75
|
-
isProjectLevel: false,
|
|
76
|
-
isFeatureLevel: true,
|
|
77
|
-
source: 'feature-output'
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Priority 2: Project-level design system (markdown)
|
|
83
|
-
const projectDesignSystemPath = join(projectPath, '.morph/context/design-system.md');
|
|
84
|
-
if (existsSync(projectDesignSystemPath)) {
|
|
85
|
-
return {
|
|
86
|
-
hasDesignSystem: true,
|
|
87
|
-
path: projectDesignSystemPath,
|
|
88
|
-
isProjectLevel: true,
|
|
89
|
-
isFeatureLevel: false,
|
|
90
|
-
source: 'project-markdown'
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Priority 3: Generated CSS design system
|
|
95
|
-
const cssDesignSystemPath = join(projectPath, 'wwwroot/css/design-system.css');
|
|
96
|
-
if (existsSync(cssDesignSystemPath)) {
|
|
97
|
-
return {
|
|
98
|
-
hasDesignSystem: true,
|
|
99
|
-
path: cssDesignSystemPath,
|
|
100
|
-
isProjectLevel: true,
|
|
101
|
-
isFeatureLevel: false,
|
|
102
|
-
source: 'generated-css'
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Priority 4: Recursively scan frontend root directories for CSS/SCSS with design tokens
|
|
107
|
-
const frontendRoots = ['wwwroot', 'styles', 'src/styles', 'src', 'public'];
|
|
108
|
-
const extensions = ['.css', '.scss'];
|
|
109
|
-
const collected = [];
|
|
110
|
-
|
|
111
|
-
for (const root of frontendRoots) {
|
|
112
|
-
const rootPath = join(projectPath, root);
|
|
113
|
-
if (existsSync(rootPath)) {
|
|
114
|
-
walkDirForCss(rootPath, extensions, collected, 0, CSS_SCAN_MAX_DEPTH);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Deduplicate by resolved path
|
|
119
|
-
const seen = new Set();
|
|
120
|
-
const cssFiles = [];
|
|
121
|
-
for (const file of collected) {
|
|
122
|
-
if (!seen.has(file)) {
|
|
123
|
-
seen.add(file);
|
|
124
|
-
cssFiles.push(file);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Sort for deterministic first-match across platforms
|
|
129
|
-
cssFiles.sort();
|
|
130
|
-
|
|
131
|
-
for (const cssFile of cssFiles) {
|
|
132
|
-
try {
|
|
133
|
-
const content = readFileSync(cssFile, 'utf8');
|
|
134
|
-
const hasDesignTokens = /:root\s*\{[\s\S]*?--/.test(content);
|
|
135
|
-
if (hasDesignTokens) {
|
|
136
|
-
return {
|
|
137
|
-
hasDesignSystem: true,
|
|
138
|
-
path: cssFile,
|
|
139
|
-
isProjectLevel: true,
|
|
140
|
-
isFeatureLevel: false,
|
|
141
|
-
source: 'existing-css-variables'
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
} catch {
|
|
145
|
-
// Continue checking other files
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// No design system found
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Get recommended design system locations based on project type
|
|
155
|
-
* @param {string} projectPath - Root path of the project
|
|
156
|
-
* @returns {Object} { markdown, css, description }
|
|
157
|
-
*/
|
|
158
|
-
export function getRecommendedLocations(projectPath) {
|
|
159
|
-
try {
|
|
160
|
-
const configPath = join(projectPath, '.morph/config/config.json');
|
|
161
|
-
|
|
162
|
-
let projectType = 'unknown';
|
|
163
|
-
if (existsSync(configPath)) {
|
|
164
|
-
const config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
165
|
-
projectType = config.project?.type || 'unknown';
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Default locations
|
|
169
|
-
const locations = {
|
|
170
|
-
markdown: '.morph/context/design-system.md',
|
|
171
|
-
css: 'public/design-system.css',
|
|
172
|
-
description: 'Project-level design system (shared across features)'
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Adjust based on project type
|
|
176
|
-
if (projectType === 'nextjs' || projectType.includes('nextjs')) {
|
|
177
|
-
locations.css = 'styles/design-system.css';
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return locations;
|
|
181
|
-
} catch {
|
|
182
|
-
return {
|
|
183
|
-
markdown: '.morph/context/design-system.md',
|
|
184
|
-
css: 'wwwroot/css/design-system.css',
|
|
185
|
-
description: 'Project-level design system (shared across features)'
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'fs';
|
|
2
|
-
import { getAbsoluteOutputPath } from '../core/paths/output-schema.js';
|
|
3
|
-
|
|
4
|
-
export const VERDICT_TOKEN = '**Verdict:**';
|
|
5
|
-
export const VERDICTS = ['SHIP', 'FIX'];
|
|
6
|
-
export const BLOCKER_TYPES = ['uc', 'teste', 'regressao', 'seguranca'];
|
|
7
|
-
|
|
8
|
-
// O relatório é append-only: uma reavaliação acrescenta ao fim, e o token vigente é o ÚLTIMO.
|
|
9
|
-
const VERDICT_RE = /\*\*Verdict:\*\*\s*([A-Za-z]+)/g;
|
|
10
|
-
const BLOCKERS_SECTION_RE = /^##\s+Bloqueadores\s*$/gim;
|
|
11
|
-
const MEDIA_SECTION_RE = /^##\s+M[íi]dia\s+gerada\s*$/m;
|
|
12
|
-
const SCREEN_CHECKLIST_SECTION_RE = /^##\s+Checklist\s+de\s+tela\s*$/gim;
|
|
13
|
-
|
|
14
|
-
export function evaluatorReportPath(cwd, featureName) {
|
|
15
|
-
return getAbsoluteOutputPath(cwd, featureName, 'evaluatorReport');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function readReport(cwd, featureName) {
|
|
19
|
-
try {
|
|
20
|
-
const p = evaluatorReportPath(cwd, featureName);
|
|
21
|
-
return existsSync(p) ? readFileSync(p, 'utf8') : null;
|
|
22
|
-
} catch {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function lastSectionBody(text, re) {
|
|
28
|
-
const matches = [...text.matchAll(re)];
|
|
29
|
-
if (matches.length === 0) return null;
|
|
30
|
-
const last = matches[matches.length - 1];
|
|
31
|
-
const rest = text.slice(last.index + last[0].length);
|
|
32
|
-
const next = rest.search(/^#{1,2}\s/m);
|
|
33
|
-
return next === -1 ? rest : rest.slice(0, next);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const normalizeType = (s) => s.toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').trim();
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Linhas de tabela da última `## Bloqueadores`: `| id | tipo | onde | evidência |`.
|
|
40
|
-
* Cabeçalho e separador não contam; `untyped` são as linhas cujo tipo não é de {@link BLOCKER_TYPES}.
|
|
41
|
-
*/
|
|
42
|
-
function parseBlockers(body) {
|
|
43
|
-
const blockers = [];
|
|
44
|
-
const untyped = [];
|
|
45
|
-
for (const line of body.split(/\r?\n/)) {
|
|
46
|
-
if (!/^\s*\|/.test(line)) continue;
|
|
47
|
-
const cells = line.trim().replace(/^\||\|$/g, '').split('|').map((c) => c.trim());
|
|
48
|
-
if (cells.every((c) => /^:?-{2,}:?$/.test(c) || c === '')) continue;
|
|
49
|
-
if (/^#$|^id$/i.test(cells[0]) && /^tipo$/i.test(cells[1] ?? '')) continue;
|
|
50
|
-
const row = { id: cells[0], type: normalizeType(cells[1] ?? ''), where: cells[2] ?? '', evidence: cells[3] ?? '' };
|
|
51
|
-
(BLOCKER_TYPES.includes(row.type) ? blockers : untyped).push(row);
|
|
52
|
-
}
|
|
53
|
-
return { blockers, untyped };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function evaluatorVerdictFromText(text) {
|
|
57
|
-
if (typeof text !== 'string') return { verdict: undefined, blockers: [], untyped: [], superseded: [] };
|
|
58
|
-
const verdicts = [...text.matchAll(VERDICT_RE)].map((m) => m[1].toUpperCase());
|
|
59
|
-
const body = lastSectionBody(text, BLOCKERS_SECTION_RE);
|
|
60
|
-
const { blockers, untyped } = body === null ? { blockers: [], untyped: [] } : parseBlockers(body);
|
|
61
|
-
return {
|
|
62
|
-
verdict: verdicts.length ? verdicts[verdicts.length - 1] : undefined,
|
|
63
|
-
blockers,
|
|
64
|
-
untyped,
|
|
65
|
-
superseded: verdicts.slice(0, -1),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* `missing`: sem relatório. `unverdicted`: relatório sem `**Verdict:** SHIP|FIX` válido.
|
|
71
|
-
* `ok`: veredito legível — quem decide se ele libera o ship é o risk-detector.
|
|
72
|
-
*/
|
|
73
|
-
export function evaluatorReportState(cwd, featureName) {
|
|
74
|
-
const path = evaluatorReportPath(cwd, featureName);
|
|
75
|
-
const text = readReport(cwd, featureName);
|
|
76
|
-
if (text === null) return { status: 'missing', path };
|
|
77
|
-
const parsed = evaluatorVerdictFromText(text);
|
|
78
|
-
if (!VERDICTS.includes(parsed.verdict)) return { status: 'unverdicted', path };
|
|
79
|
-
return { status: 'ok', path, ...parsed };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** O sinal `evaluatorVerdict` que `verdictPause` (risk-detector) lê — gate-check e approve leem o mesmo. */
|
|
83
|
-
export function verdictSignal(report) {
|
|
84
|
-
if (report.status !== 'ok') return { status: report.status };
|
|
85
|
-
return {
|
|
86
|
-
status: 'ok',
|
|
87
|
-
verdict: report.verdict,
|
|
88
|
-
blockers: report.blockers.length,
|
|
89
|
-
blockerIds: report.blockers.map((b) => b.id),
|
|
90
|
-
untyped: report.untyped.length,
|
|
91
|
-
superseded: report.superseded,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function evaluatorMediaSection(cwd, featureName) {
|
|
96
|
-
const text = readReport(cwd, featureName);
|
|
97
|
-
return text !== null && MEDIA_SECTION_RE.test(text);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function evaluatorScreenChecklist(cwd, featureName) {
|
|
101
|
-
const text = readReport(cwd, featureName);
|
|
102
|
-
const body = text === null ? null : lastSectionBody(text, SCREEN_CHECKLIST_SECTION_RE);
|
|
103
|
-
return body === null ? { section: false, body: '' } : { section: true, body };
|
|
104
|
-
}
|