@polymorphism-tech/morph-spec 4.12.0 → 4.14.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 +7 -7
- package/README.md +28 -34
- package/bin/morph-spec.js +41 -24
- package/bin/task-manager.js +962 -1341
- package/bin/validate.js +1 -1
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +14 -16
- package/docs/QUICKSTART.md +15 -15
- package/framework/CLAUDE.md +5 -2
- package/framework/agents/README.md +3 -4
- package/framework/agents/ai-agents/ai-system-architect.md +6 -10
- package/framework/agents/architecture/seo-growth-hacker.md +166 -326
- package/framework/agents/architecture/standards-architect.md +21 -31
- package/framework/agents/backend/dotnet-senior.md +160 -86
- package/framework/agents/backend/ef-modeler.md +2 -6
- package/framework/agents/backend/hangfire-orchestrator.md +8 -9
- package/framework/agents/backend/ms-agent-expert.md +1 -1
- package/framework/agents/frontend/nextjs-expert.md +198 -133
- package/framework/agents/frontend/ui-ux-designer.md +226 -267
- package/framework/agents/infrastructure/infra-architect.md +191 -27
- package/framework/agents/integrations/clerk-auth.md +19 -26
- package/framework/agents/integrations/hangfire-integration.md +1 -4
- package/framework/agents.json +1084 -2278
- package/framework/commands/morph-apply.md +4 -6
- package/framework/commands/morph-preflight.md +192 -269
- package/framework/commands/morph-proposal.md +210 -238
- package/framework/commands/morph-status.md +72 -92
- package/framework/commands/morph-troubleshoot.md +6 -13
- package/framework/hooks/README.md +1 -6
- package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +4 -6
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
- package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
- package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
- package/framework/hooks/claude-code/statusline.py +4 -5
- package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
- package/framework/hooks/shared/compact-restore.js +28 -5
- package/framework/hooks/shared/phase-utils.js +4 -8
- package/framework/hooks/shared/state-reader.js +34 -3
- package/framework/phases.json +162 -200
- package/framework/rules/ai-agents-standards.md +15 -0
- package/framework/rules/asaas-standards.md +13 -0
- package/framework/rules/clerk-standards.md +13 -0
- package/framework/rules/csharp-standards.md +8 -4
- package/framework/rules/data-standards.md +18 -0
- package/framework/rules/dotnet-templates.md +87 -0
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/hangfire-standards.md +13 -0
- package/framework/rules/infrastructure-standards.md +27 -16
- package/framework/rules/morph-workflow.md +73 -13
- package/framework/rules/nextjs-standards.md +1 -0
- package/framework/rules/nextjs-templates.md +40 -0
- package/framework/rules/resend-standards.md +12 -0
- package/framework/rules/supabase-standards.md +29 -0
- package/framework/skills/README.md +6 -8
- package/framework/skills/level-0-meta/mcp-registry.json +21 -99
- package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
- package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
- package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
- package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
- package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
- package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
- package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
- package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
- package/framework/skills/level-1-workflows/README.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +57 -123
- package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
- package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
- package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +143 -172
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +57 -77
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
- package/framework/squad-templates/backend-only.json +6 -6
- package/framework/squad-templates/frontend-only.json +17 -8
- package/framework/squad-templates/full-stack.json +29 -24
- package/framework/standards/STANDARDS.json +1021 -2369
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
- package/framework/standards/backend/dotnet/result-pattern.md +213 -0
- package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
- package/framework/standards/backend/dotnet/scrutor.md +158 -0
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
- package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
- package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
- package/framework/standards/integration/mcp/mcp-tools.md +91 -77
- package/framework/templates/IDE-SNIPPETS.md +2 -6
- package/framework/templates/README.md +709 -814
- package/framework/templates/REGISTRY.json +223 -762
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
- package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
- package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
- package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
- package/framework/templates/code/dotnet/backend/repository.cs +148 -141
- package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
- package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
- package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
- package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
- package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
- package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
- package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
- package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
- package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
- package/framework/templates/code/dotnet/jobs/job.cs +21 -17
- package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
- package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
- package/framework/templates/code/dotnet/test.cs +192 -106
- package/framework/templates/context/ARCHITECTURE.md +89 -0
- package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
- package/framework/templates/context/CONTEXT.md +180 -181
- package/framework/templates/context/design-system.md +1 -5
- package/framework/templates/docs/onboarding.md +2 -3
- package/framework/templates/docs/proposal.md +171 -182
- package/framework/templates/docs/spec.md +1 -3
- package/framework/templates/docs/ui-components.md +0 -72
- package/framework/templates/examples/design-system-examples.md +4 -4
- package/framework/templates/feature/decisions.md +0 -66
- package/framework/templates/feature/recap.md +1 -2
- package/framework/templates/infrastructure/github/README.md +56 -593
- package/framework/templates/integrations/clerk-config.cs +0 -41
- package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
- package/framework/templates/project/validate.js +2 -4
- package/framework/templates/ui/design-system.css +1 -1
- package/framework/workflows/README.md +8 -8
- package/framework/workflows/configs/fast-track.json +51 -0
- package/framework/workflows/configs/full.json +68 -0
- package/framework/workflows/configs/standard.json +7 -3
- package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
- package/framework/workflows/docs/enforcement-pipeline.md +18 -19
- package/framework/workflows/docs/full-morph.md +69 -76
- package/framework/workflows/docs/standard.md +49 -44
- package/framework/workflows/docs/ui-refresh.md +1 -1
- package/package.json +3 -3
- package/src/commands/agents/dispatch-agents.js +55 -116
- package/src/commands/context/context-refresh.js +79 -0
- package/src/commands/phase/phase-reset.js +1 -1
- package/src/commands/project/doctor.js +10 -32
- package/src/commands/project/init.js +12 -0
- package/src/commands/project/status.js +6 -12
- package/src/commands/scaffold/scaffold.js +131 -0
- package/src/commands/scope/escalate.js +1 -1
- package/src/commands/state/advance-phase.js +15 -29
- package/src/commands/state/state.js +20 -5
- package/src/commands/tasks/task.js +0 -30
- package/src/commands/validation/validate-feature.js +3 -10
- package/src/core/paths/output-schema.js +12 -13
- package/src/core/state/phase-state-machine.js +211 -217
- package/src/core/state/state-manager.js +9 -9
- package/src/lib/agents/agents-manager.js +2 -2
- package/src/lib/agents/output-collector.js +1 -2
- package/src/lib/detectors/design-system-detector.js +4 -4
- package/src/lib/detectors/index.js +1 -11
- package/src/lib/generators/architecture-scanner.js +640 -0
- package/src/lib/generators/context-generator.js +3 -3
- package/src/lib/generators/design-system-generator.js +508 -587
- package/src/lib/generators/index.js +12 -10
- package/src/lib/generators/metadata-extractor.js +386 -387
- package/src/lib/generators/recap-generator.js +4 -4
- package/src/lib/generators/scaffold-generator.js +317 -0
- package/src/lib/generators/settings-generator.js +0 -1
- package/src/lib/phase-chain/phase-validator.js +64 -42
- package/src/lib/stack/stack-profile.js +2 -2
- package/src/lib/standards/digest-builder.js +72 -285
- package/src/lib/tasks/task-parser.js +11 -5
- package/src/lib/validators/architecture/architecture-validator.js +259 -387
- package/src/lib/validators/content/content-validator.js +287 -287
- package/src/lib/validators/css/css-validator.js +340 -352
- package/src/lib/validators/packages/package-validator.js +347 -360
- package/src/lib/validators/shared/issue-counter.js +14 -18
- package/src/lib/validators/validation-runner.js +3 -19
- package/src/scripts/setup-infra.js +1 -1
- package/src/utils/agents-installer.js +61 -10
- package/src/utils/file-copier.js +1 -0
- package/src/utils/hooks-installer.js +11 -19
- package/src/utils/skills-installer.js +178 -178
- package/framework/agents/architecture/prompt-engineer.md +0 -195
- package/framework/agents/backend/api-designer.md +0 -106
- package/framework/agents/frontend/blazor-builder.md +0 -229
- package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
- package/framework/agents/infrastructure/azure-architect.md +0 -150
- package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
- package/framework/agents/infrastructure/bicep-architect.md +0 -132
- package/framework/agents/infrastructure/container-specialist.md +0 -137
- package/framework/agents/infrastructure/devops-engineer.md +0 -126
- package/framework/agents/integrations/azure-identity.md +0 -148
- package/framework/agents/quality/code-analyzer.md +0 -239
- package/framework/agents/quality/testing-specialist.md +0 -130
- package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
- package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
- package/framework/index/troubleshooting-index.json +0 -184
- package/framework/rules/testing-standards.md +0 -14
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
- package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
- package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
- package/framework/standards/ai-agents/blazor-ui.md +0 -364
- package/framework/standards/architecture/ddd/aggregates.md +0 -120
- package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
- package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
- package/framework/standards/architecture/ddd/entities.md +0 -99
- package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
- package/framework/standards/architecture/ddd/value-objects.md +0 -124
- package/framework/standards/backend/api/minimal-api.md +0 -494
- package/framework/standards/backend/api/rest.md +0 -492
- package/framework/standards/backend/authentication/passkeys.md +0 -428
- package/framework/standards/backend/database/ef-core.md +0 -199
- package/framework/standards/backend/database/migrations.md +0 -393
- package/framework/standards/backend/database/repository-patterns.md +0 -528
- package/framework/standards/backend/dotnet/async.md +0 -366
- package/framework/standards/backend/dotnet/core.md +0 -117
- package/framework/standards/backend/dotnet/di.md +0 -439
- package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
- package/framework/standards/context/analytics.md +0 -96
- package/framework/standards/context/bundles.md +0 -110
- package/framework/standards/context/priming.md +0 -78
- package/framework/standards/core/architecture.md +0 -185
- package/framework/standards/core/coding.md +0 -214
- package/framework/standards/core/git-branching-strategy.md +0 -403
- package/framework/standards/core/git.md +0 -185
- package/framework/standards/core/testing.md +0 -295
- package/framework/standards/data/nosql/blob-storage.md +0 -102
- package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
- package/framework/standards/frontend/blazor/design-checklist.md +0 -222
- package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
- package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
- package/framework/standards/frontend/blazor/html-conversion.md +0 -184
- package/framework/standards/frontend/blazor/lifecycle.md +0 -195
- package/framework/standards/frontend/blazor/pitfalls.md +0 -198
- package/framework/standards/frontend/blazor/state.md +0 -191
- package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -266
- package/framework/standards/frontend/design-system/design-trends.md +0 -171
- package/framework/standards/infrastructure/azure/azure.md +0 -624
- package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
- package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
- package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
- package/framework/standards/infrastructure/azure/services/functions.md +0 -486
- package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
- package/framework/standards/infrastructure/azure/services/storage.md +0 -407
- package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
- package/framework/standards/integration/api/graphql.md +0 -91
- package/framework/standards/integration/api/grpc.md +0 -114
- package/framework/standards/integration/api/rest-design.md +0 -95
- package/framework/standards/integration/event-driven/cqrs.md +0 -101
- package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
- package/framework/standards/integration/event-driven/service-bus.md +0 -95
- package/framework/standards/observability/logging.md +0 -131
- package/framework/standards/observability/metrics.md +0 -121
- package/framework/standards/observability/monitoring.md +0 -114
- package/framework/standards/observability/tracing.md +0 -132
- package/framework/standards/workflows/parallel-execution.md +0 -112
- package/framework/standards/workflows/thread-management.md +0 -113
- package/framework/templates/code/dotnet/backend/service.cs +0 -139
- package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
- package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
- package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
- package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
- package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
- package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
- package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
- package/framework/templates/code/dotnet/frontend/component.razor +0 -239
- package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
- package/framework/templates/infrastructure/azure/README.md +0 -286
- package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
- package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
- package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
- package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
- package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
- package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
- package/framework/templates/infrastructure/azure/deploy.sh +0 -208
- package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
- package/framework/templates/infrastructure/azure/main.bicep +0 -189
- package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
- package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
- package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
- package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
- package/framework/templates/infrastructure/azure/storage.bicep +0 -106
- package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
- package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
- package/framework/templates/integrations/azure-identity-config.cs +0 -288
- package/framework/templates/project-structure/dotnet-ddd.md +0 -70
- package/framework/templates/saas/subscription.cs +0 -347
- package/framework/templates/saas/tenant.cs +0 -338
- package/framework/templates/ui/FluentDesignTheme.cs +0 -149
- package/framework/templates/ui/MudTheme.cs +0 -281
- package/framework/workflows/configs/nodejs-cli.json +0 -40
- package/src/commands/standards/context-budget.js +0 -89
- package/src/lib/standards/index.js +0 -7
- package/src/lib/standards/standards-context-injector.js +0 -302
- package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
- package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
- package/src/lib/validators/blazor/blazor-validator.js +0 -369
- package/src/lib/validators/blazor/index.js +0 -9
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: code-analyzer
|
|
3
|
-
description: Code Analyzer specialist for refactoring, complexity analysis, technical debt assessment, and identifying code smells in .NET/TypeScript codebases. Use when analyzing code quality, identifying refactoring opportunities, assessing technical debt, or reviewing code for duplication and architecture violations.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Code Analyzer
|
|
8
|
-
|
|
9
|
-
Deep code analysis specialist. Automates architecture review, clean code checks, and duplication detection.
|
|
10
|
-
|
|
11
|
-
> **Ref:** `framework/standards/core/coding.md` for naming conventions.
|
|
12
|
-
> **Ref:** `framework/standards/core/architecture.md` for architectural patterns.
|
|
13
|
-
> **Ref:** `.claude/skills/checklists/code-review.md` for runtime pattern checks.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## When to Run
|
|
18
|
-
|
|
19
|
-
| Trigger | Automatic? | Scope |
|
|
20
|
-
|---------|-----------|-------|
|
|
21
|
-
| FASE 5 completion (`/morph-apply` done) | Yes | Full feature code |
|
|
22
|
-
| Checkpoint (every 3 tasks) | Yes | Code since last checkpoint |
|
|
23
|
-
| Manual: `analyze`, `review code`, `code quality` | No | Specified scope |
|
|
24
|
-
| Pre-merge review | Recommended | All changed files |
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 3 Analysis Modes
|
|
29
|
-
|
|
30
|
-
Run all 3 modes by default. Use `--mode architecture`, `--mode clean`, or `--mode duplication` for targeted analysis.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
### Mode 1: Architecture Analysis
|
|
35
|
-
|
|
36
|
-
Analyze the codebase for structural and architectural issues.
|
|
37
|
-
|
|
38
|
-
#### Checklist
|
|
39
|
-
|
|
40
|
-
**Layer Integrity:**
|
|
41
|
-
- [ ] `[CRITICAL]` Domain project has zero references to Infrastructure or Web
|
|
42
|
-
- [ ] `[CRITICAL]` Application does NOT reference Web project
|
|
43
|
-
- [ ] `[HIGH]` No circular dependencies between projects
|
|
44
|
-
- [ ] `[HIGH]` Infrastructure details don't leak into Application (no EF types in DTOs)
|
|
45
|
-
|
|
46
|
-
**Responsibility Separation:**
|
|
47
|
-
- [ ] `[HIGH]` Each class has a single, clear responsibility (< 300 lines)
|
|
48
|
-
- [ ] `[HIGH]` Controllers/pages are thin (< 50 lines logic, delegate to services)
|
|
49
|
-
- [ ] `[MEDIUM]` Interfaces are focused (< 7 methods per interface)
|
|
50
|
-
- [ ] `[MEDIUM]` No "God classes" (classes with 10+ dependencies)
|
|
51
|
-
|
|
52
|
-
**Abstractions:**
|
|
53
|
-
- [ ] `[MEDIUM]` External services accessed through interfaces (testable)
|
|
54
|
-
- [ ] `[LOW]` No over-abstraction (interfaces with exactly 1 implementation that's never mocked)
|
|
55
|
-
- [ ] `[MEDIUM]` Missing abstractions: direct HTTP calls, file I/O, or DB access without interface
|
|
56
|
-
|
|
57
|
-
**File Organization:**
|
|
58
|
-
- [ ] `[MEDIUM]` One class per file (file name matches class name)
|
|
59
|
-
- [ ] `[MEDIUM]` Files in correct project/folder per architecture.md
|
|
60
|
-
- [ ] `[LOW]` Consistent folder structure across all layers
|
|
61
|
-
|
|
62
|
-
**Configuration:**
|
|
63
|
-
- [ ] `[HIGH]` No hardcoded connection strings, URLs, or secrets
|
|
64
|
-
- [ ] `[MEDIUM]` Configuration via Options pattern (`IOptions<T>`)
|
|
65
|
-
- [ ] `[LOW]` No duplicate configuration across projects
|
|
66
|
-
|
|
67
|
-
**Unused Code:**
|
|
68
|
-
- [ ] `[MEDIUM]` No unused classes or interfaces (search for zero references)
|
|
69
|
-
- [ ] `[MEDIUM]` No dead code paths (unreachable branches)
|
|
70
|
-
- [ ] `[LOW]` No commented-out code blocks (> 3 lines)
|
|
71
|
-
- [ ] `[LOW]` No empty or near-empty files (< 10 lines of actual code)
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
### Mode 2: Clean Code Analysis
|
|
76
|
-
|
|
77
|
-
Analyze for code smells, style violations, and improvement opportunities.
|
|
78
|
-
|
|
79
|
-
#### Checklist
|
|
80
|
-
|
|
81
|
-
**Naming (ref: coding.md):**
|
|
82
|
-
- [ ] `[HIGH]` All naming follows coding.md conventions (PascalCase constants, _camelCase fields, etc.)
|
|
83
|
-
- [ ] `[HIGH]` No Hungarian notation (`strName`, `iCount`, `btnSubmit`)
|
|
84
|
-
- [ ] `[HIGH]` No ALL_CAPS constants (`MAX_RETRY` -> `MaxRetry`)
|
|
85
|
-
- [ ] `[MEDIUM]` Descriptive names (no `data`, `info`, `item`, `result` without context)
|
|
86
|
-
- [ ] `[MEDIUM]` No abbreviations in public APIs (`repo` -> `repository`)
|
|
87
|
-
|
|
88
|
-
**Method Quality:**
|
|
89
|
-
- [ ] `[HIGH]` No methods > 30 lines (extract sub-methods)
|
|
90
|
-
- [ ] `[HIGH]` No methods with > 4 parameters (use request object)
|
|
91
|
-
- [ ] `[MEDIUM]` No nested conditionals > 3 levels (extract or use early return)
|
|
92
|
-
- [ ] `[MEDIUM]` No complex conditionals (> 3 conditions in one `if` — extract to named bool or method)
|
|
93
|
-
|
|
94
|
-
**Class Quality:**
|
|
95
|
-
- [ ] `[HIGH]` No classes > 300 lines (SRP violation — split)
|
|
96
|
-
- [ ] `[HIGH]` No classes with > 7 constructor dependencies (God class — split)
|
|
97
|
-
- [ ] `[MEDIUM]` Classes are `sealed` unless designed for inheritance
|
|
98
|
-
|
|
99
|
-
**Magic Values:**
|
|
100
|
-
- [ ] `[HIGH]` No magic strings in comparisons (`if (status == "active")` -> use enum or constant)
|
|
101
|
-
- [ ] `[HIGH]` No magic numbers (`if (items.Count > 50)` -> extract `const int MaxItemsPerPage = 50`)
|
|
102
|
-
- [ ] `[MEDIUM]` No hardcoded URLs, file paths, or configuration values
|
|
103
|
-
|
|
104
|
-
**Dead Code:**
|
|
105
|
-
- [ ] `[MEDIUM]` No unused private methods (zero callers)
|
|
106
|
-
- [ ] `[MEDIUM]` No unused parameters in methods
|
|
107
|
-
- [ ] `[LOW]` No TODO/FIXME/HACK comments older than 2 sprints
|
|
108
|
-
- [ ] `[LOW]` No `#if DEBUG` blocks with substantial logic
|
|
109
|
-
|
|
110
|
-
**Error Handling:**
|
|
111
|
-
- [ ] `[CRITICAL]` No empty catch blocks
|
|
112
|
-
- [ ] `[HIGH]` No generic `catch (Exception)` without re-throw
|
|
113
|
-
- [ ] `[HIGH]` Result pattern used for business errors (not exceptions)
|
|
114
|
-
- [ ] `[MEDIUM]` Consistent error handling pattern across all services
|
|
115
|
-
|
|
116
|
-
**Logging:**
|
|
117
|
-
- [ ] `[HIGH]` No `$""` string interpolation in log methods (use message templates)
|
|
118
|
-
- [ ] `[HIGH]` Critical operations have entry/exit/error logging
|
|
119
|
-
- [ ] `[MEDIUM]` Log messages include correlation IDs (OrderId, UserId)
|
|
120
|
-
- [ ] `[MEDIUM]` Consistent log levels across similar operations
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
### Mode 3: Duplication Detection
|
|
125
|
-
|
|
126
|
-
Find redundant, duplicate, and unnecessary code.
|
|
127
|
-
|
|
128
|
-
#### Targets
|
|
129
|
-
|
|
130
|
-
**Exact/Near-Exact Duplicates:**
|
|
131
|
-
- [ ] `[HIGH]` Methods with identical or near-identical logic in different classes
|
|
132
|
-
- Same method body, different class -> extract to shared service or extension
|
|
133
|
-
- Same logic with different types -> extract to generic method
|
|
134
|
-
- [ ] `[HIGH]` Repeated code blocks (> 5 lines identical in 2+ locations)
|
|
135
|
-
|
|
136
|
-
**Thin Wrappers:**
|
|
137
|
-
- [ ] `[MEDIUM]` Methods that only delegate to another method with same parameters
|
|
138
|
-
```csharp
|
|
139
|
-
// SMELL: Thin wrapper with no added value
|
|
140
|
-
public Task<Order> GetOrderAsync(int id, CancellationToken ct)
|
|
141
|
-
=> _innerService.GetOrderAsync(id, ct);
|
|
142
|
-
```
|
|
143
|
-
- [ ] `[MEDIUM]` Service methods that only call a repository method (no logic added)
|
|
144
|
-
|
|
145
|
-
**Interface Redundancy:**
|
|
146
|
-
- [ ] `[MEDIUM]` Same method signature appearing in multiple interfaces (extract base interface)
|
|
147
|
-
- [ ] `[LOW]` Interface that exactly mirrors another interface (merge or inherit)
|
|
148
|
-
|
|
149
|
-
**Passthrough Delegates:**
|
|
150
|
-
- [ ] `[MEDIUM]` Controller/page methods that only call one service method and return result
|
|
151
|
-
- If no validation, auth, or mapping: consider simplifying the layer
|
|
152
|
-
|
|
153
|
-
**DTO/Model Duplication:**
|
|
154
|
-
- [ ] `[HIGH]` Duplicate model definitions (same properties in different classes)
|
|
155
|
-
- [ ] `[MEDIUM]` Request/Response DTOs that are identical (merge or use shared base)
|
|
156
|
-
- [ ] `[MEDIUM]` Enums defined in multiple projects (centralize in Domain)
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## Output Format
|
|
161
|
-
|
|
162
|
-
For each finding, report:
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
### [{SEVERITY}] {Category}: {Short Description}
|
|
166
|
-
|
|
167
|
-
**File:** `path/to/file.cs:42`
|
|
168
|
-
**Rule:** {rule reference from checklist above}
|
|
169
|
-
|
|
170
|
-
**Current code:**
|
|
171
|
-
```csharp
|
|
172
|
-
// problematic code snippet
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
**Suggested fix:**
|
|
176
|
-
```csharp
|
|
177
|
-
// corrected code snippet
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
**Why:** {brief explanation of the problem and impact}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Summary Template
|
|
186
|
-
|
|
187
|
-
After analysis, generate a summary:
|
|
188
|
-
|
|
189
|
-
```markdown
|
|
190
|
-
## Code Analysis Summary
|
|
191
|
-
|
|
192
|
-
**Scope:** {files/feature analyzed}
|
|
193
|
-
**Date:** {date}
|
|
194
|
-
**Modes:** Architecture | Clean Code | Duplication
|
|
195
|
-
|
|
196
|
-
### Findings by Severity
|
|
197
|
-
|
|
198
|
-
| Severity | Count |
|
|
199
|
-
|----------|-------|
|
|
200
|
-
| CRITICAL | {n} |
|
|
201
|
-
| HIGH | {n} |
|
|
202
|
-
| MEDIUM | {n} |
|
|
203
|
-
| LOW | {n} |
|
|
204
|
-
|
|
205
|
-
### Top 5 Priorities
|
|
206
|
-
|
|
207
|
-
1. {Most critical finding with file:line}
|
|
208
|
-
2. {Second most critical}
|
|
209
|
-
3. ...
|
|
210
|
-
|
|
211
|
-
### Estimated Effort
|
|
212
|
-
|
|
213
|
-
| Category | Findings | Effort |
|
|
214
|
-
|----------|----------|--------|
|
|
215
|
-
| Quick fixes (naming, style) | {n} | ~{h}h |
|
|
216
|
-
| Refactoring (extraction, splitting) | {n} | ~{h}h |
|
|
217
|
-
| Architecture (layer changes) | {n} | ~{h}h |
|
|
218
|
-
|
|
219
|
-
### Recommendations
|
|
220
|
-
|
|
221
|
-
- {Key recommendation 1}
|
|
222
|
-
- {Key recommendation 2}
|
|
223
|
-
- {Key recommendation 3}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## Integration with Other Specialists
|
|
229
|
-
|
|
230
|
-
| Specialist | Handoff |
|
|
231
|
-
|------------|---------|
|
|
232
|
-
| **Standards Architect** | Code Analyzer validates naming rules defined by Standards Architect |
|
|
233
|
-
| **.NET Senior Engineer** | Code Analyzer reviews code produced by dotnet-senior |
|
|
234
|
-
| **Code Review Checklist** | Code Analyzer runs architecture/clean code checks; code-review.md covers runtime patterns |
|
|
235
|
-
| **Testing Specialist** | Findings may generate new test requirements |
|
|
236
|
-
|
|
237
|
-
---
|
|
238
|
-
|
|
239
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: testing-specialist
|
|
3
|
-
description: Testing Specialist for test strategy, TDD/BDD implementation, unit and integration tests using xUnit, Vitest, and Jest, and quality assurance automation. Use when designing test strategies, implementing TDD cycles, writing unit/integration tests, or improving test coverage in .NET and TypeScript projects.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Testing Specialist
|
|
8
|
-
|
|
9
|
-
Especialista em testes, mocking e simulação para projetos .NET.
|
|
10
|
-
|
|
11
|
-
## Strategy
|
|
12
|
-
|
|
13
|
-
| Level | What | Tools |
|
|
14
|
-
|-------|------|-------|
|
|
15
|
-
| **Unit** | Business logic, domain, handlers | xUnit + Moq + FluentAssertions |
|
|
16
|
-
| **Integration** | API flows, DB operations | WebApplicationFactory + TestContainers |
|
|
17
|
-
| **Component** | Blazor rendering, events | bUnit |
|
|
18
|
-
| **E2E** | Critical user journeys | Playwright (if needed) |
|
|
19
|
-
|
|
20
|
-
**Focus:** Critical/complex code. Don't aim for 100%, aim for value. Cover edge cases and error paths.
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Core Patterns
|
|
25
|
-
|
|
26
|
-
### AAA (Arrange-Act-Assert)
|
|
27
|
-
|
|
28
|
-
```csharp
|
|
29
|
-
[Fact]
|
|
30
|
-
public async Task CreateOrder_Should_ReturnSuccess_When_ValidInput()
|
|
31
|
-
{
|
|
32
|
-
// Arrange
|
|
33
|
-
var command = new CreateOrderCommand { CustomerId = 1, Items = [...] };
|
|
34
|
-
var handler = new CreateOrderHandler(_mockRepo.Object);
|
|
35
|
-
// Act
|
|
36
|
-
var result = await handler.Handle(command, CancellationToken.None);
|
|
37
|
-
// Assert
|
|
38
|
-
result.IsSuccess.Should().BeTrue();
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Naming Convention
|
|
43
|
-
```
|
|
44
|
-
[Method]_Should_[ExpectedResult]_When_[Condition]
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Test Data Builders
|
|
48
|
-
Use builder pattern for complex test entities: `new OrderBuilder().WithCustomer(123).WithStatus(Completed).Build()`
|
|
49
|
-
|
|
50
|
-
### Mocking (Moq)
|
|
51
|
-
```csharp
|
|
52
|
-
var mockRepo = new Mock<IOrderRepository>();
|
|
53
|
-
mockRepo.Setup(r => r.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(new Order { Id = 1 });
|
|
54
|
-
mockRepo.Verify(r => r.SaveAsync(It.IsAny<Order>()), Times.Once);
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Integration Tests (WebApplicationFactory)
|
|
58
|
-
Replace real DB with in-memory in `ConfigureServices`, use `CreateClient()` for HTTP calls.
|
|
59
|
-
|
|
60
|
-
### bUnit (Blazor)
|
|
61
|
-
`RenderComponent<Counter>()` → `Find("button").Click()` → assert `TextContent`.
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## Libraries
|
|
66
|
-
|
|
67
|
-
| Library | Purpose | NuGet |
|
|
68
|
-
|---------|---------|-------|
|
|
69
|
-
| xUnit | Test framework | `xunit` |
|
|
70
|
-
| Moq | Mocking | `Moq` |
|
|
71
|
-
| FluentAssertions | Readable assertions | `FluentAssertions` |
|
|
72
|
-
| Bogus | Fake data | `Bogus` |
|
|
73
|
-
| TestContainers | DB containers | `Testcontainers` |
|
|
74
|
-
| Respawn | DB reset | `Respawn` |
|
|
75
|
-
| WireMock | HTTP mocking | `WireMock.Net` |
|
|
76
|
-
| bUnit | Blazor testing | `bunit` |
|
|
77
|
-
|
|
78
|
-
## Folder Structure
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
tests/
|
|
82
|
-
├── Unit/{Domain,Application,Builders}/
|
|
83
|
-
├── Integration/{Api,Fixtures}/
|
|
84
|
-
└── E2E/
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Anti-Patterns
|
|
88
|
-
1. **Fragile tests** — test behavior, not implementation
|
|
89
|
-
2. **Slow tests** — use mocks, not real DB for unit tests
|
|
90
|
-
3. **Coupled tests** — each test independent
|
|
91
|
-
4. **Vague assertions** — use specific FluentAssertions
|
|
92
|
-
5. **Giant setup** — extract to builders/fixtures
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## Simulation of External Services
|
|
97
|
-
|
|
98
|
-
> **Ref:** `.claude/skills/checklists/simulation-checklist.md` for complete checklist
|
|
99
|
-
|
|
100
|
-
### Key Rules
|
|
101
|
-
|
|
102
|
-
| Mock Type | Characteristic | DI Lifetime |
|
|
103
|
-
|-----------|---------------|-------------|
|
|
104
|
-
| **Stateful** (Dictionary, List) | Keeps data between calls | `Singleton` |
|
|
105
|
-
| **Stateless** | No state | `Scoped` |
|
|
106
|
-
|
|
107
|
-
```csharp
|
|
108
|
-
// ❌ Stateful with Scoped = loses state between requests
|
|
109
|
-
services.AddScoped<IReplicateClient, FakeReplicateClient>();
|
|
110
|
-
// ✅ Stateful with Singleton
|
|
111
|
-
services.AddSingleton<IReplicateClient, FakeReplicateClient>();
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Before implementing mocks:** Map ALL dependencies (interfaces, transitive deps, lifetimes).
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Checklists
|
|
119
|
-
|
|
120
|
-
### Per Test Type
|
|
121
|
-
| Target | Test |
|
|
122
|
-
|--------|------|
|
|
123
|
-
| Entity/Domain | Creation validation, state transitions (valid + invalid), invariants |
|
|
124
|
-
| Handler/Service | Happy path, invalid input, not found (404), auth error, timeout |
|
|
125
|
-
| API | Status codes, response body, request validation, auth |
|
|
126
|
-
| Blazor Component | Initial render, user events, states (loading/error/empty), form validation |
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Notification Hook: Approval Reminder on Idle
|
|
5
|
-
*
|
|
6
|
-
* Event: Notification | Matcher: idle_prompt
|
|
7
|
-
*
|
|
8
|
-
* When Claude is idle, checks for pending approval gates and reminds the user.
|
|
9
|
-
*
|
|
10
|
-
* Fail-open: exits 0 on any error.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { stateExists, getActiveFeature, getPendingGates, derivePhaseForFeature } from '../../shared/state-reader.js';
|
|
14
|
-
import { injectContext, pass } from '../../shared/hook-response.js';
|
|
15
|
-
import { logHookActivity } from '../../shared/activity-logger.js';
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
if (!stateExists()) pass();
|
|
19
|
-
|
|
20
|
-
const active = getActiveFeature();
|
|
21
|
-
if (!active) pass();
|
|
22
|
-
|
|
23
|
-
const { name, feature } = active;
|
|
24
|
-
const pending = getPendingGates(name);
|
|
25
|
-
|
|
26
|
-
if (pending.length === 0) pass();
|
|
27
|
-
|
|
28
|
-
// Only remind about gates relevant to the current phase
|
|
29
|
-
const phaseGateRelevance = {
|
|
30
|
-
proposal: ['proposal'],
|
|
31
|
-
setup: ['proposal'],
|
|
32
|
-
design: ['design'],
|
|
33
|
-
clarify: ['design'],
|
|
34
|
-
tasks: ['design', 'tasks'],
|
|
35
|
-
uiux: ['uiux'],
|
|
36
|
-
implement: ['design', 'tasks']
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const currentPhase = feature.phase || derivePhaseForFeature(name);
|
|
40
|
-
const relevantGates = phaseGateRelevance[currentPhase] || [];
|
|
41
|
-
const pendingRelevant = pending.filter(g => relevantGates.includes(g));
|
|
42
|
-
|
|
43
|
-
if (pendingRelevant.length === 0) pass();
|
|
44
|
-
|
|
45
|
-
const reminders = pendingRelevant.map(gate =>
|
|
46
|
-
` morph-spec approve ${name} ${gate}`
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
logHookActivity('approval-reminder', 'Notification', `pending(${pendingRelevant.join(',')})`);
|
|
50
|
-
injectContext(
|
|
51
|
-
`MORPH-SPEC: Feature '${name}' has pending approval(s) that may be blocking progress:\n` +
|
|
52
|
-
reminders.join('\n')
|
|
53
|
-
);
|
|
54
|
-
} catch {
|
|
55
|
-
// Fail-open
|
|
56
|
-
process.exit(0);
|
|
57
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* PostToolUse Hook: Context Auto-Refresh
|
|
5
|
-
*
|
|
6
|
-
* Event: PostToolUse | Matcher: Bash
|
|
7
|
-
*
|
|
8
|
-
* Detects `git commit` commands that touch structural files (package.json,
|
|
9
|
-
* *.csproj, next.config.*, etc.) and injects instructions for Claude to
|
|
10
|
-
* update .morph/context/README.md and .morph/config/config.json.
|
|
11
|
-
*
|
|
12
|
-
* Only fires when:
|
|
13
|
-
* 1. .morph/state.json exists (morph-spec project)
|
|
14
|
-
* 2. Command contains `git commit`
|
|
15
|
-
* 3. .morph/context/README.md is initialized (not a setup-infra placeholder)
|
|
16
|
-
* 4. Structural files changed in the commit (compared to HEAD~1)
|
|
17
|
-
*
|
|
18
|
-
* Fail-open: exits 0 on any error.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import { execSync } from 'child_process';
|
|
22
|
-
import { readFileSync, existsSync } from 'fs';
|
|
23
|
-
import { join, basename } from 'path';
|
|
24
|
-
import { readStdin } from '../../shared/stdin-reader.js';
|
|
25
|
-
import { stateExists } from '../../shared/state-reader.js';
|
|
26
|
-
import { pass, injectContext } from '../../shared/hook-response.js';
|
|
27
|
-
import { logHookActivity } from '../../shared/activity-logger.js';
|
|
28
|
-
|
|
29
|
-
const STRUCTURAL_PATTERNS = [
|
|
30
|
-
/^package\.json$/,
|
|
31
|
-
/\.csproj$/,
|
|
32
|
-
/\.sln$/,
|
|
33
|
-
/^next\.config\./,
|
|
34
|
-
/^tailwind\.config\./,
|
|
35
|
-
/^tsconfig\.json$/,
|
|
36
|
-
/^jsconfig\.json$/,
|
|
37
|
-
/^docker-compose/,
|
|
38
|
-
/^Dockerfile/,
|
|
39
|
-
/^\.env\.example$/,
|
|
40
|
-
/^go\.mod$/,
|
|
41
|
-
/^requirements\.txt$/,
|
|
42
|
-
/^pyproject\.toml$/,
|
|
43
|
-
/^Gemfile$/,
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
if (!stateExists()) pass();
|
|
48
|
-
|
|
49
|
-
const payload = await readStdin();
|
|
50
|
-
if (!payload) pass();
|
|
51
|
-
|
|
52
|
-
const command = payload?.tool_input?.command || '';
|
|
53
|
-
if (!/\bgit\s+commit\b/.test(command)) pass();
|
|
54
|
-
|
|
55
|
-
if (!isContextInitialized()) pass();
|
|
56
|
-
|
|
57
|
-
let changedFiles = [];
|
|
58
|
-
try {
|
|
59
|
-
const output = execSync('git diff HEAD~1 --name-only', {
|
|
60
|
-
encoding: 'utf-8',
|
|
61
|
-
stdio: 'pipe',
|
|
62
|
-
cwd: process.cwd(),
|
|
63
|
-
timeout: 10000,
|
|
64
|
-
});
|
|
65
|
-
changedFiles = output.trim().split('\n').filter(Boolean);
|
|
66
|
-
} catch {
|
|
67
|
-
// First commit (no HEAD~1) or git error — pass silently
|
|
68
|
-
pass();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const structuralFiles = changedFiles.filter(file => {
|
|
72
|
-
const name = basename(file);
|
|
73
|
-
return STRUCTURAL_PATTERNS.some(pattern => pattern.test(name));
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
if (structuralFiles.length === 0) pass();
|
|
77
|
-
|
|
78
|
-
const fileList = structuralFiles.join(', ');
|
|
79
|
-
logHookActivity('context-refresh', 'PostToolUse', `structural_change(${structuralFiles.length})`);
|
|
80
|
-
injectContext(
|
|
81
|
-
`📋 [morph-spec] Mudanças estruturais detectadas no commit: ${fileList}\n\n` +
|
|
82
|
-
`Atualizar contexto do projeto automaticamente:\n` +
|
|
83
|
-
`1. \`git show HEAD --stat\` — ver escopo completo da mudança\n` +
|
|
84
|
-
`2. Ler \`.morph/context/README.md\` → atualizar seções afetadas\n` +
|
|
85
|
-
` (Tech Stack, Architecture, Key Integrations, Agent Notes)\n` +
|
|
86
|
-
`3. Ler \`.morph/config/config.json\` → atualizar campos relevantes\n` +
|
|
87
|
-
` (stack, architecture, integrations, paths)\n` +
|
|
88
|
-
`4. Escrever os arquivos atualizados com as mudanças detectadas`
|
|
89
|
-
);
|
|
90
|
-
} catch {
|
|
91
|
-
// Fail-open
|
|
92
|
-
process.exit(0);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Check if .morph/context/README.md is initialized (not a setup-infra placeholder).
|
|
97
|
-
* Returns false if the file is missing or contains the placeholder sentinel.
|
|
98
|
-
* @returns {boolean}
|
|
99
|
-
*/
|
|
100
|
-
function isContextInitialized() {
|
|
101
|
-
try {
|
|
102
|
-
const contextPath = join(process.cwd(), '.morph/context/README.md');
|
|
103
|
-
if (!existsSync(contextPath)) return false;
|
|
104
|
-
const content = readFileSync(contextPath, 'utf-8');
|
|
105
|
-
return !content.includes('Run /morph-init to generate');
|
|
106
|
-
} catch {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* PostToolUse Hook: Skill Reminder on Task Start
|
|
5
|
-
*
|
|
6
|
-
* Event: PostToolUse | Matcher: Bash
|
|
7
|
-
*
|
|
8
|
-
* Fires after `morph-spec task start <feature> <task>` completes.
|
|
9
|
-
* Reads requiredSkills from phases.json for the current phase and injects
|
|
10
|
-
* mandatory skill invocation instructions as additionalContext.
|
|
11
|
-
*
|
|
12
|
-
* The additionalContext appears directly in Claude's view of the Bash tool
|
|
13
|
-
* result — more prominent than any pre-loaded prompt text.
|
|
14
|
-
*
|
|
15
|
-
* Fail-open: exits 0 on any error.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { readFileSync, existsSync } from 'fs';
|
|
19
|
-
import { join } from 'path';
|
|
20
|
-
import { readStdin } from '../../shared/stdin-reader.js';
|
|
21
|
-
import { stateExists, loadState, derivePhaseForFeature } from '../../shared/state-reader.js';
|
|
22
|
-
import { injectContext, pass } from '../../shared/hook-response.js';
|
|
23
|
-
import { logHookActivity } from '../../shared/activity-logger.js';
|
|
24
|
-
import { parseTaskStartCommand, buildSkillReminderMessage } from '../../shared/skill-reminder-helpers.js';
|
|
25
|
-
|
|
26
|
-
// Re-export for backwards compatibility (tests may import from this file)
|
|
27
|
-
export { parseTaskStartCommand, buildSkillReminderMessage };
|
|
28
|
-
|
|
29
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
-
// Hook entry point
|
|
31
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
if (!stateExists()) pass();
|
|
35
|
-
|
|
36
|
-
const payload = await readStdin();
|
|
37
|
-
if (!payload) pass();
|
|
38
|
-
|
|
39
|
-
const command = payload?.tool_input?.command || '';
|
|
40
|
-
const parsed = parseTaskStartCommand(command);
|
|
41
|
-
if (!parsed) pass();
|
|
42
|
-
|
|
43
|
-
const { featureName, taskId } = parsed;
|
|
44
|
-
|
|
45
|
-
// Load state to get current phase
|
|
46
|
-
const state = loadState();
|
|
47
|
-
if (!state) pass();
|
|
48
|
-
|
|
49
|
-
const feature = state?.features?.[featureName];
|
|
50
|
-
if (!feature) pass();
|
|
51
|
-
|
|
52
|
-
const phase = feature.phase || derivePhaseForFeature(featureName);
|
|
53
|
-
if (!phase) pass();
|
|
54
|
-
|
|
55
|
-
// Load phases.json (project-local first, fall back to package-level)
|
|
56
|
-
const localPhasesPath = join(process.cwd(), 'framework', 'phases.json');
|
|
57
|
-
const pkgPhasesPath = join(
|
|
58
|
-
process.cwd(), 'node_modules', '@polymorphism-tech', 'morph-spec', 'framework', 'phases.json'
|
|
59
|
-
);
|
|
60
|
-
const phasesPath = existsSync(localPhasesPath) ? localPhasesPath : pkgPhasesPath;
|
|
61
|
-
if (!existsSync(phasesPath)) pass();
|
|
62
|
-
|
|
63
|
-
let phasesData;
|
|
64
|
-
try {
|
|
65
|
-
phasesData = JSON.parse(readFileSync(phasesPath, 'utf8'));
|
|
66
|
-
} catch {
|
|
67
|
-
pass();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const message = buildSkillReminderMessage(featureName, taskId, phase, phasesData);
|
|
71
|
-
if (!message) pass();
|
|
72
|
-
|
|
73
|
-
logHookActivity('skill-reminder', 'PostToolUse', `injected(${featureName}/${taskId}/${phase})`);
|
|
74
|
-
injectContext(message);
|
|
75
|
-
} catch {
|
|
76
|
-
// Fail-open
|
|
77
|
-
process.exit(0);
|
|
78
|
-
}
|