tribunal-kit 6.0.1 → 7.0.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/.agent/ARCHITECTURE.md +9 -6
- package/.agent/agents/accessibility-reviewer.md +23 -16
- package/.agent/agents/ai-code-reviewer.md +25 -21
- package/.agent/agents/anti-pattern-reviewer.md +12 -7
- package/.agent/agents/api-architect.md +1 -0
- package/.agent/agents/backend-specialist.md +23 -22
- package/.agent/agents/cloud-engineer.md +1 -0
- package/.agent/agents/code-archaeologist.md +1 -0
- package/.agent/agents/complexity-reviewer.md +10 -7
- package/.agent/agents/database-architect.md +3 -2
- package/.agent/agents/db-latency-auditor.md +6 -2
- package/.agent/agents/debugger.md +3 -2
- package/.agent/agents/dependency-reviewer.md +1 -0
- package/.agent/agents/devops-engineer.md +9 -8
- package/.agent/agents/documentation-writer.md +6 -5
- package/.agent/agents/explorer-agent.md +1 -0
- package/.agent/agents/frontend-reviewer.md +21 -17
- package/.agent/agents/frontend-specialist.md +23 -20
- package/.agent/agents/game-developer.md +1 -0
- package/.agent/agents/interaction-reviewer.md +10 -5
- package/.agent/agents/logic-reviewer.md +3 -0
- package/.agent/agents/minimalist-reviewer.md +6 -0
- package/.agent/agents/mobile-developer.md +7 -6
- package/.agent/agents/mobile-reviewer.md +14 -13
- package/.agent/agents/orchestrator.md +3 -0
- package/.agent/agents/penetration-tester.md +1 -0
- package/.agent/agents/performance-optimizer.md +6 -5
- package/.agent/agents/performance-reviewer.md +6 -6
- package/.agent/agents/pipeline-reviewer.md +144 -0
- package/.agent/agents/precedence-reviewer.md +1 -0
- package/.agent/agents/product-manager.md +1 -0
- package/.agent/agents/product-owner.md +1 -0
- package/.agent/agents/product-reviewer.md +12 -7
- package/.agent/agents/project-planner.md +3 -0
- package/.agent/agents/qa-automation-engineer.md +50 -43
- package/.agent/agents/resilience-reviewer.md +1 -0
- package/.agent/agents/schema-reviewer.md +1 -0
- package/.agent/agents/security-auditor.md +24 -24
- package/.agent/agents/seo-specialist.md +33 -23
- package/.agent/agents/sql-reviewer.md +5 -4
- package/.agent/agents/supervisor-agent.md +12 -2
- package/.agent/agents/swarm-worker-contracts.md +13 -13
- package/.agent/agents/swarm-worker-registry.md +51 -51
- package/.agent/agents/system-architect.md +1 -0
- package/.agent/agents/test-coverage-reviewer.md +25 -22
- package/.agent/agents/test-engineer.md +12 -11
- package/.agent/agents/throughput-optimizer.md +45 -40
- package/.agent/agents/type-safety-reviewer.md +5 -4
- package/.agent/agents/ui-ux-auditor.md +6 -4
- package/.agent/agents/ui-visual-auditor.md +3 -0
- package/.agent/agents/ux-reviewer.md +11 -6
- package/.agent/agents/visual-reviewer.md +11 -6
- package/.agent/agents/vitals-reviewer.md +5 -4
- package/.agent/history/memory/.memory.idx +1532 -1
- package/.agent/history/memory/MEMORY.md +102 -1
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2033 -263
- package/.agent/rules/GEMINI.md +11 -9
- package/.agent/rules/GEMINI_PLANNER.md +19 -21
- package/.agent/scripts/_colors.js +52 -54
- package/.agent/scripts/_utils.js +52 -53
- package/.agent/scripts/auto_preview.js +39 -43
- package/.agent/scripts/bundle_analyzer.js +47 -60
- package/.agent/scripts/case_law_manager.js +200 -294
- package/.agent/scripts/checklist.js +73 -94
- package/.agent/scripts/cicd_validator.js +305 -0
- package/.agent/scripts/compile_router.py +4 -111
- package/.agent/scripts/context_broker.js +317 -412
- package/.agent/scripts/contract_engine.js +402 -0
- package/.agent/scripts/dependency_analyzer.js +112 -124
- package/.agent/scripts/graph_builder.js +75 -103
- package/.agent/scripts/graph_visualizer.js +10 -12
- package/.agent/scripts/graph_zoom.js +38 -55
- package/.agent/scripts/guardrail_engine.js +195 -145
- package/.agent/scripts/impact_classifier.js +55 -30
- package/.agent/scripts/inner_loop_validator.js +108 -159
- package/.agent/scripts/integrity_manifest.js +59 -67
- package/.agent/scripts/lint_runner.js +65 -75
- package/.agent/scripts/marathon_harness.js +131 -208
- package/.agent/scripts/migrate_skills_frontmatter.py +4 -63
- package/.agent/scripts/minify_context.js +29 -33
- package/.agent/scripts/minimal_change_engine.js +95 -87
- package/.agent/scripts/mutation_runner.js +46 -62
- package/.agent/scripts/pipeline_engine.js +320 -209
- package/.agent/scripts/prompt_compiler.js +118 -93
- package/.agent/scripts/schema_validator.js +73 -121
- package/.agent/scripts/security_scan.js +88 -117
- package/.agent/scripts/session_manager.js +52 -69
- package/.agent/scripts/signal_detector.js +24 -22
- package/.agent/scripts/skill_evolution.js +184 -245
- package/.agent/scripts/skill_integrator.js +35 -48
- package/.agent/scripts/socratic_gate_policy.js +15 -12
- package/.agent/scripts/strengthen_skills.js +29 -33
- package/.agent/scripts/swarm_dispatcher.js +120 -151
- package/.agent/scripts/test_runner.js +54 -56
- package/.agent/scripts/token_budget_broker.js +9 -7
- package/.agent/scripts/trace_engine.js +126 -0
- package/.agent/scripts/verify_all.js +76 -93
- package/.agent/scripts/visual_audit.js +16 -21
- package/.agent/skill_topic_map.json +22 -3
- package/.agent/skills/12-principles-of-animation/SKILL.md +7 -0
- package/.agent/skills/60fps-animation/SKILL.md +7 -0
- package/.agent/skills/accessible-animation/SKILL.md +5 -1
- package/.agent/skills/adapt/SKILL.md +7 -1
- package/.agent/skills/advanced-rag-pipelines/SKILL.md +1 -0
- package/.agent/skills/agent-organizer/SKILL.md +1 -0
- package/.agent/skills/agentic-patterns/SKILL.md +33 -25
- package/.agent/skills/agentic-workflows-2026/SKILL.md +6 -2
- package/.agent/skills/ai-app-hardening/SKILL.md +9 -8
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +7 -6
- package/.agent/skills/animation-on-scroll/SKILL.md +24 -15
- package/.agent/skills/animation-systems/SKILL.md +11 -10
- package/.agent/skills/antfu-conventions/SKILL.md +7 -2
- package/.agent/skills/api-patterns/SKILL.md +14 -10
- package/.agent/skills/api-security-auditor/SKILL.md +15 -14
- package/.agent/skills/app-builder/SKILL.md +1 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +2 -2
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +12 -12
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +3 -3
- package/.agent/skills/apple-design/SKILL.md +8 -7
- package/.agent/skills/architecture/SKILL.md +3 -2
- package/.agent/skills/audit-and-fix/SKILL.md +8 -5
- package/.agent/skills/authentication-best-practices/SKILL.md +9 -8
- package/.agent/skills/backend-security-expert/SKILL.md +1 -0
- package/.agent/skills/baseline-ui/SKILL.md +8 -7
- package/.agent/skills/bash-linux/SKILL.md +1 -0
- package/.agent/skills/behavioral-modes/SKILL.md +1 -0
- package/.agent/skills/better-colors/SKILL.md +11 -7
- package/.agent/skills/better-typography/SKILL.md +30 -16
- package/.agent/skills/better-ui/SKILL.md +17 -10
- package/.agent/skills/bolder/SKILL.md +6 -0
- package/.agent/skills/brainstorming/SKILL.md +6 -4
- package/.agent/skills/browser-native-ai/SKILL.md +5 -4
- package/.agent/skills/build-primitive/SKILL.md +5 -0
- package/.agent/skills/building-native-ui/SKILL.md +1 -0
- package/.agent/skills/cicd-pro/SKILL.md +2 -1
- package/.agent/skills/clarify/SKILL.md +19 -14
- package/.agent/skills/clean-code/SKILL.md +16 -15
- package/.agent/skills/cloud-architect/SKILL.md +1 -0
- package/.agent/skills/cobejs/SKILL.md +7 -9
- package/.agent/skills/code-review-checklist/SKILL.md +1 -0
- package/.agent/skills/codebase-design/SKILL.md +7 -2
- package/.agent/skills/colorize/SKILL.md +8 -3
- package/.agent/skills/compact-landing/SKILL.md +8 -3
- package/.agent/skills/company-logos/SKILL.md +6 -0
- package/.agent/skills/config-validator/SKILL.md +10 -9
- package/.agent/skills/containerization-pro/SKILL.md +6 -5
- package/.agent/skills/context-engineering-pro/SKILL.md +5 -4
- package/.agent/skills/create-design-md/SKILL.md +13 -5
- package/.agent/skills/critique/SKILL.md +10 -8
- package/.agent/skills/csharp-developer/SKILL.md +1 -0
- package/.agent/skills/data-validation-schemas/SKILL.md +28 -23
- package/.agent/skills/database-design/SKILL.md +2 -1
- package/.agent/skills/delight/SKILL.md +6 -0
- package/.agent/skills/deployment-procedures/SKILL.md +2 -1
- package/.agent/skills/design-lab/SKILL.md +5 -0
- package/.agent/skills/devops-engineer/SKILL.md +3 -2
- package/.agent/skills/devops-incident-responder/SKILL.md +2 -1
- package/.agent/skills/diagnosing-bugs/SKILL.md +12 -2
- package/.agent/skills/distill/SKILL.md +7 -2
- package/.agent/skills/documentation-templates/SKILL.md +3 -2
- package/.agent/skills/domain-modeling/SKILL.md +12 -4
- package/.agent/skills/duckdb-analytical-sql/SKILL.md +7 -3
- package/.agent/skills/edge-ai-mobile/SKILL.md +5 -1
- package/.agent/skills/edge-computing/SKILL.md +9 -8
- package/.agent/skills/emil-design-eng/SKILL.md +43 -27
- package/.agent/skills/error-resilience/SKILL.md +34 -16
- package/.agent/skills/expo-router-v4/SKILL.md +2 -1
- package/.agent/skills/extract-design-system/SKILL.md +12 -11
- package/.agent/skills/fabel-protocol/SKILL.md +24 -17
- package/.agent/skills/fixing-accessibility/SKILL.md +23 -16
- package/.agent/skills/fixing-metadata/SKILL.md +24 -13
- package/.agent/skills/fixing-motion-performance/SKILL.md +7 -5
- package/.agent/skills/framer-motion-expert/SKILL.md +29 -15
- package/.agent/skills/frontend-design/SKILL.md +21 -13
- package/.agent/skills/frontend-security-expert/SKILL.md +1 -0
- package/.agent/skills/game-design-expert/SKILL.md +1 -0
- package/.agent/skills/game-engineering-expert/SKILL.md +1 -0
- package/.agent/skills/generative-ui-expert/SKILL.md +3 -2
- package/.agent/skills/geo-fundamentals/SKILL.md +2 -1
- package/.agent/skills/git-pro/SKILL.md +10 -9
- package/.agent/skills/github-operations/SKILL.md +2 -1
- package/.agent/skills/gpt-taste/SKILL.md +7 -0
- package/.agent/skills/gsap-core/SKILL.md +26 -22
- package/.agent/skills/gsap-frameworks/SKILL.md +6 -5
- package/.agent/skills/gsap-performance/SKILL.md +4 -3
- package/.agent/skills/gsap-plugins/SKILL.md +34 -33
- package/.agent/skills/gsap-react/SKILL.md +9 -8
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +34 -33
- package/.agent/skills/gsap-timeline/SKILL.md +18 -15
- package/.agent/skills/gsap-utils/SKILL.md +25 -24
- package/.agent/skills/harden/SKILL.md +9 -3
- package/.agent/skills/harness-protocol/SKILL.md +1 -0
- package/.agent/skills/i18n-localization/SKILL.md +10 -9
- package/.agent/skills/impeccable/SKILL.md +5 -0
- package/.agent/skills/improve-codebase-architecture/SKILL.md +10 -5
- package/.agent/skills/improve-ui/SKILL.md +12 -5
- package/.agent/skills/intelligent-routing/SKILL.md +7 -6
- package/.agent/skills/knowledge-graph/SKILL.md +1 -0
- package/.agent/skills/landing-page/SKILL.md +1 -0
- package/.agent/skills/lint-and-validate/SKILL.md +9 -4
- package/.agent/skills/llm-engineering/SKILL.md +55 -54
- package/.agent/skills/local-first/SKILL.md +20 -19
- package/.agent/skills/local-first-architecture/SKILL.md +6 -1
- package/.agent/skills/lottie-animation/SKILL.md +7 -3
- package/.agent/skills/marquee-loop/SKILL.md +1 -0
- package/.agent/skills/masked-reveal/SKILL.md +17 -4
- package/.agent/skills/mcp-builder/SKILL.md +13 -10
- package/.agent/skills/micro-interaction/SKILL.md +20 -5
- package/.agent/skills/mobile-design/SKILL.md +26 -15
- package/.agent/skills/monorepo-management/SKILL.md +3 -2
- package/.agent/skills/morphing-icons/SKILL.md +16 -6
- package/.agent/skills/motion-engineering/SKILL.md +19 -15
- package/.agent/skills/nextjs-react-expert/SKILL.md +26 -21
- package/.agent/skills/nodejs-best-practices/SKILL.md +89 -76
- package/.agent/skills/observability/SKILL.md +45 -44
- package/.agent/skills/opentelemetry-observability/SKILL.md +2 -1
- package/.agent/skills/page-transition-animation/SKILL.md +6 -3
- package/.agent/skills/parallel-agents/SKILL.md +7 -2
- package/.agent/skills/performance-profiling/SKILL.md +24 -13
- package/.agent/skills/plan-writing/SKILL.md +1 -0
- package/.agent/skills/platform-engineer/SKILL.md +3 -2
- package/.agent/skills/platform-engineering-opentofu/SKILL.md +1 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +3 -2
- package/.agent/skills/playwright-best-practices/SKILL.md +29 -28
- package/.agent/skills/polish/SKILL.md +13 -12
- package/.agent/skills/powershell-windows/SKILL.md +1 -0
- package/.agent/skills/pricing-page/SKILL.md +8 -3
- package/.agent/skills/product-aware-heuristics/SKILL.md +122 -72
- package/.agent/skills/progressive-blur/SKILL.md +9 -4
- package/.agent/skills/project-idioms/SKILL.md +1 -0
- package/.agent/skills/property-based-testing/SKILL.md +10 -12
- package/.agent/skills/python-patterns/SKILL.md +1 -0
- package/.agent/skills/python-pro/SKILL.md +1 -0
- package/.agent/skills/quieter/SKILL.md +6 -0
- package/.agent/skills/react-doctor/SKILL.md +6 -0
- package/.agent/skills/react-specialist/SKILL.md +32 -28
- package/.agent/skills/readme-builder/SKILL.md +1 -0
- package/.agent/skills/realtime-patterns/SKILL.md +34 -33
- package/.agent/skills/red-team-tactics/SKILL.md +1 -0
- package/.agent/skills/redesign-skill/SKILL.md +6 -0
- package/.agent/skills/review-animations/SKILL.md +5 -2
- package/.agent/skills/review-animations/STANDARDS.md +37 -23
- package/.agent/skills/rust-pro/SKILL.md +1 -0
- package/.agent/skills/seo-fundamentals/SKILL.md +4 -3
- package/.agent/skills/server-management/SKILL.md +1 -0
- package/.agent/skills/shadcn-ui-expert/SKILL.md +28 -22
- package/.agent/skills/shape/SKILL.md +9 -2
- package/.agent/skills/skill-creator/SKILL.md +1 -0
- package/.agent/skills/soft-skill/SKILL.md +6 -0
- package/.agent/skills/sounds-on-the-web/SKILL.md +1 -0
- package/.agent/skills/sql-pro/SKILL.md +1 -0
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +1 -0
- package/.agent/skills/svg-animation/SKILL.md +16 -7
- package/.agent/skills/swiftui-expert/SKILL.md +1 -0
- package/.agent/skills/swiss-design/SKILL.md +5 -0
- package/.agent/skills/system-design-pro/SKILL.md +1 -0
- package/.agent/skills/systematic-debugging/SKILL.md +1 -0
- package/.agent/skills/tailwind-patterns/SKILL.md +25 -11
- package/.agent/skills/taste-skill/SKILL.md +6 -0
- package/.agent/skills/tdd-workflow/SKILL.md +5 -0
- package/.agent/skills/test-result-analyzer/SKILL.md +1 -0
- package/.agent/skills/testing-patterns/SKILL.md +123 -115
- package/.agent/skills/thermo-nuclear-code-quality-review/SKILL.md +5 -0
- package/.agent/skills/thinking-protocol/SKILL.md +3 -0
- package/.agent/skills/to-spring-or-not-to-spring/SKILL.md +9 -8
- package/.agent/skills/transitions-dev/SKILL.md +19 -6
- package/.agent/skills/trend-researcher/SKILL.md +1 -0
- package/.agent/skills/typescript-advanced/SKILL.md +23 -18
- package/.agent/skills/typeset/SKILL.md +10 -1
- package/.agent/skills/ui-reasoning-engine/SKILL.md +67 -48
- package/.agent/skills/ui-skill-packs/SKILL.md +6 -1
- package/.agent/skills/ui-skills-root/SKILL.md +39 -38
- package/.agent/skills/ui-ux-pro-max/SKILL.md +34 -26
- package/.agent/skills/ui-ux-researcher/SKILL.md +1 -0
- package/.agent/skills/vector-search-pgvector/SKILL.md +3 -2
- package/.agent/skills/vue-expert/SKILL.md +22 -19
- package/.agent/skills/vulnerability-scanner/SKILL.md +22 -21
- package/.agent/skills/web-accessibility-auditor/SKILL.md +2 -1
- package/.agent/skills/web-design-guidelines/SKILL.md +16 -10
- package/.agent/skills/web-quality-audit/SKILL.md +5 -0
- package/.agent/skills/webapp-testing/SKILL.md +14 -13
- package/.agent/skills/webgpu-performance/SKILL.md +1 -0
- package/.agent/skills/whimsy-injector/SKILL.md +9 -5
- package/.agent/skills/workflow-optimizer/SKILL.md +1 -0
- package/.agent/skills/zero-trust-passkeys/SKILL.md +11 -6
- package/.agent/templates/DESIGN.md +119 -110
- package/.agent/templates/design-tokens.json +9 -6
- package/.agent/workflows/acf.md +1 -0
- package/.agent/workflows/api-tester.md +1 -0
- package/.agent/workflows/audit.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/changelog.md +1 -0
- package/.agent/workflows/contract.md +60 -0
- package/.agent/workflows/create.md +1 -0
- package/.agent/workflows/debug.md +1 -0
- package/.agent/workflows/deploy.md +1 -0
- package/.agent/workflows/enhance.md +1 -0
- package/.agent/workflows/fix-ci.md +89 -0
- package/.agent/workflows/fix.md +1 -0
- package/.agent/workflows/generate.md +1 -0
- package/.agent/workflows/marathon.md +1 -0
- package/.agent/workflows/migrate.md +1 -0
- package/.agent/workflows/minimal.md +9 -7
- package/.agent/workflows/orchestrate.md +1 -0
- package/.agent/workflows/performance-benchmarker.md +1 -0
- package/.agent/workflows/pipeline.md +26 -21
- package/.agent/workflows/plan.md +1 -0
- package/.agent/workflows/preview.md +1 -0
- package/.agent/workflows/refactor.md +3 -2
- package/.agent/workflows/review-ai.md +4 -3
- package/.agent/workflows/review.md +1 -0
- package/.agent/workflows/session.md +1 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/strengthen-skills.md +1 -0
- package/.agent/workflows/super-prompt.md +1 -0
- package/.agent/workflows/swarm.md +15 -3
- package/.agent/workflows/test.md +8 -7
- package/.agent/workflows/tribunal-backend.md +3 -2
- package/.agent/workflows/tribunal-cicd.md +104 -0
- package/.agent/workflows/tribunal-database.md +1 -0
- package/.agent/workflows/tribunal-frontend.md +8 -6
- package/.agent/workflows/tribunal-full.md +2 -1
- package/.agent/workflows/tribunal-mobile.md +6 -5
- package/.agent/workflows/tribunal-performance.md +1 -0
- package/.agent/workflows/tribunal-speed.md +1 -0
- package/.agent/workflows/tribunal-ui.md +29 -21
- package/.agent/workflows/ui-ux-pro-max.md +19 -15
- package/CONTRIBUTING.md +3 -3
- package/README.md +94 -44
- package/SECURITY.md +10 -10
- package/bin/mcp-server.js +385 -252
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +40 -46
- package/dist/cli.js +6 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/status.js +6 -0
- package/dist/index.d.ts +8 -1
- package/package.json +13 -12
- package/scripts/benchmark.js +62 -86
- package/scripts/changelog.js +67 -73
- package/scripts/fix-vbc.js +13 -15
- package/scripts/fix-vbc.ps1 +2 -118
- package/scripts/stress_benchmark.js +358 -0
- package/scripts/sync-version.js +71 -41
- package/scripts/validate-payload.js +23 -30
- package/scripts/visual_audit.js +23 -13
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before writing unit, integration, or component tests, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. AAA Pattern & Single Act Rule (Section 37) → Structure tests strictly as Arrange-Act-Assert; perform only 1 single action per test case
|
|
24
25
|
2. Accessibility-First Query Hierarchy (Section 343) → Query React components by `getByRole` or `getByLabelText`; ban default `getByTestId` queries
|
|
25
26
|
3. Dependency Injection Over Global Mocks (Section 268) → Prefer constructor dependency injection over global `vi.mock()` to prevent cross-test state leakage
|
|
@@ -52,10 +53,10 @@ Rules:
|
|
|
52
53
|
|
|
53
54
|
```typescript
|
|
54
55
|
// Every test follows the same structure
|
|
55
|
-
it(
|
|
56
|
+
it('calculates total with tax', () => {
|
|
56
57
|
// Arrange — set up the scenario
|
|
57
58
|
const cart = new Cart();
|
|
58
|
-
cart.addItem({ name:
|
|
59
|
+
cart.addItem({ name: 'Widget', price: 100 });
|
|
59
60
|
cart.setTaxRate(0.08);
|
|
60
61
|
|
|
61
62
|
// Act — perform the action being tested
|
|
@@ -66,12 +67,12 @@ it("calculates total with tax", () => {
|
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
// ❌ BAD: Multiple acts in one test
|
|
69
|
-
it(
|
|
70
|
-
cart.addItem({ name:
|
|
70
|
+
it('does too many things', () => {
|
|
71
|
+
cart.addItem({ name: 'A', price: 10 });
|
|
71
72
|
expect(cart.total).toBe(10); // assert
|
|
72
|
-
cart.addItem({ name:
|
|
73
|
+
cart.addItem({ name: 'B', price: 20 });
|
|
73
74
|
expect(cart.total).toBe(30); // another assert after another act
|
|
74
|
-
cart.removeItem(
|
|
75
|
+
cart.removeItem('A');
|
|
75
76
|
expect(cart.total).toBe(20); // yet another — split into 3 tests
|
|
76
77
|
});
|
|
77
78
|
```
|
|
@@ -82,18 +83,18 @@ it("does too many things", () => {
|
|
|
82
83
|
// Format: [unit] + [scenario] + [expected result]
|
|
83
84
|
|
|
84
85
|
// ✅ GOOD: Descriptive, reads like a specification
|
|
85
|
-
describe(
|
|
86
|
-
it(
|
|
87
|
-
it(
|
|
88
|
-
it(
|
|
89
|
-
it(
|
|
86
|
+
describe('calculateDiscount', () => {
|
|
87
|
+
it('returns 0% when cart total is under $50', () => {});
|
|
88
|
+
it('returns 10% when cart total is $50-$99', () => {});
|
|
89
|
+
it('returns 20% when cart total is $100+', () => {});
|
|
90
|
+
it('throws when cart is empty', () => {});
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
// ❌ BAD: Vague, implementation-focused
|
|
93
|
-
describe(
|
|
94
|
-
it(
|
|
95
|
-
it(
|
|
96
|
-
it(
|
|
94
|
+
describe('calculateDiscount', () => {
|
|
95
|
+
it('works', () => {});
|
|
96
|
+
it('test1', () => {});
|
|
97
|
+
it('should return correct value', () => {});
|
|
97
98
|
});
|
|
98
99
|
```
|
|
99
100
|
|
|
@@ -110,27 +111,27 @@ export function clamp(value: number, min: number, max: number): number {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
// utils/math.test.ts
|
|
113
|
-
import { describe, it, expect } from
|
|
114
|
-
import { clamp } from
|
|
114
|
+
import { describe, it, expect } from 'vitest';
|
|
115
|
+
import { clamp } from './math';
|
|
115
116
|
|
|
116
|
-
describe(
|
|
117
|
-
it(
|
|
117
|
+
describe('clamp', () => {
|
|
118
|
+
it('returns the value when within range', () => {
|
|
118
119
|
expect(clamp(5, 0, 10)).toBe(5);
|
|
119
120
|
});
|
|
120
121
|
|
|
121
|
-
it(
|
|
122
|
+
it('clamps to min when value is below range', () => {
|
|
122
123
|
expect(clamp(-5, 0, 10)).toBe(0);
|
|
123
124
|
});
|
|
124
125
|
|
|
125
|
-
it(
|
|
126
|
+
it('clamps to max when value is above range', () => {
|
|
126
127
|
expect(clamp(15, 0, 10)).toBe(10);
|
|
127
128
|
});
|
|
128
129
|
|
|
129
|
-
it(
|
|
130
|
+
it('handles equal min and max', () => {
|
|
130
131
|
expect(clamp(5, 3, 3)).toBe(3);
|
|
131
132
|
});
|
|
132
133
|
|
|
133
|
-
it(
|
|
134
|
+
it('handles floating point values', () => {
|
|
134
135
|
expect(clamp(0.5, 0, 1)).toBeCloseTo(0.5);
|
|
135
136
|
});
|
|
136
137
|
});
|
|
@@ -139,7 +140,7 @@ describe("clamp", () => {
|
|
|
139
140
|
### Async Testing
|
|
140
141
|
|
|
141
142
|
```typescript
|
|
142
|
-
import { describe, it, expect, vi } from
|
|
143
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
143
144
|
|
|
144
145
|
// Async function under test
|
|
145
146
|
async function fetchUser(id: string): Promise<User> {
|
|
@@ -148,23 +149,23 @@ async function fetchUser(id: string): Promise<User> {
|
|
|
148
149
|
return response.json();
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
describe(
|
|
152
|
-
it(
|
|
153
|
-
const mockUser = { id:
|
|
152
|
+
describe('fetchUser', () => {
|
|
153
|
+
it('returns user data on success', async () => {
|
|
154
|
+
const mockUser = { id: '1', name: 'Alice' };
|
|
154
155
|
global.fetch = vi.fn().mockResolvedValue({
|
|
155
156
|
ok: true,
|
|
156
157
|
json: () => Promise.resolve(mockUser),
|
|
157
158
|
});
|
|
158
159
|
|
|
159
|
-
const user = await fetchUser(
|
|
160
|
+
const user = await fetchUser('1');
|
|
160
161
|
expect(user).toEqual(mockUser);
|
|
161
|
-
expect(fetch).toHaveBeenCalledWith(
|
|
162
|
+
expect(fetch).toHaveBeenCalledWith('/api/users/1');
|
|
162
163
|
});
|
|
163
164
|
|
|
164
|
-
it(
|
|
165
|
+
it('throws on HTTP error', async () => {
|
|
165
166
|
global.fetch = vi.fn().mockResolvedValue({ ok: false, status: 404 });
|
|
166
167
|
|
|
167
|
-
await expect(fetchUser(
|
|
168
|
+
await expect(fetchUser('999')).rejects.toThrow('HTTP 404');
|
|
168
169
|
});
|
|
169
170
|
});
|
|
170
171
|
```
|
|
@@ -172,7 +173,7 @@ describe("fetchUser", () => {
|
|
|
172
173
|
### Timer & Date Mocking
|
|
173
174
|
|
|
174
175
|
```typescript
|
|
175
|
-
describe(
|
|
176
|
+
describe('debounce', () => {
|
|
176
177
|
beforeEach(() => {
|
|
177
178
|
vi.useFakeTimers();
|
|
178
179
|
});
|
|
@@ -181,7 +182,7 @@ describe("debounce", () => {
|
|
|
181
182
|
vi.useRealTimers();
|
|
182
183
|
});
|
|
183
184
|
|
|
184
|
-
it(
|
|
185
|
+
it('delays execution by specified ms', () => {
|
|
185
186
|
const fn = vi.fn();
|
|
186
187
|
const debounced = debounce(fn, 300);
|
|
187
188
|
|
|
@@ -195,7 +196,7 @@ describe("debounce", () => {
|
|
|
195
196
|
expect(fn).toHaveBeenCalledOnce(); // now
|
|
196
197
|
});
|
|
197
198
|
|
|
198
|
-
it(
|
|
199
|
+
it('resets timer on subsequent calls', () => {
|
|
199
200
|
const fn = vi.fn();
|
|
200
201
|
const debounced = debounce(fn, 300);
|
|
201
202
|
|
|
@@ -212,8 +213,8 @@ describe("debounce", () => {
|
|
|
212
213
|
|
|
213
214
|
// Date mocking
|
|
214
215
|
it("formats today's date", () => {
|
|
215
|
-
vi.setSystemTime(new Date(
|
|
216
|
-
expect(getFormattedDate()).toBe(
|
|
216
|
+
vi.setSystemTime(new Date('2024-06-15T12:00:00Z'));
|
|
217
|
+
expect(getFormattedDate()).toBe('June 15, 2024');
|
|
217
218
|
vi.useRealTimers();
|
|
218
219
|
});
|
|
219
220
|
```
|
|
@@ -225,32 +226,32 @@ it("formats today's date", () => {
|
|
|
225
226
|
### Module Mocks
|
|
226
227
|
|
|
227
228
|
```typescript
|
|
228
|
-
import { vi, describe, it, expect, beforeEach } from
|
|
229
|
-
import { sendEmail } from
|
|
230
|
-
import { createUser } from
|
|
229
|
+
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
|
230
|
+
import { sendEmail } from './email-service';
|
|
231
|
+
import { createUser } from './user-service';
|
|
231
232
|
|
|
232
233
|
// Mock an entire module
|
|
233
|
-
vi.mock(
|
|
234
|
+
vi.mock('./email-service', () => ({
|
|
234
235
|
sendEmail: vi.fn().mockResolvedValue({ sent: true }),
|
|
235
236
|
}));
|
|
236
237
|
|
|
237
|
-
describe(
|
|
238
|
+
describe('createUser', () => {
|
|
238
239
|
beforeEach(() => {
|
|
239
240
|
vi.clearAllMocks(); // reset call counts between tests
|
|
240
241
|
});
|
|
241
242
|
|
|
242
|
-
it(
|
|
243
|
-
await createUser({ name:
|
|
243
|
+
it('sends welcome email after creating user', async () => {
|
|
244
|
+
await createUser({ name: 'Alice', email: 'alice@test.com' });
|
|
244
245
|
|
|
245
246
|
expect(sendEmail).toHaveBeenCalledWith({
|
|
246
|
-
to:
|
|
247
|
-
subject:
|
|
248
|
-
body: expect.stringContaining(
|
|
247
|
+
to: 'alice@test.com',
|
|
248
|
+
subject: 'Welcome!',
|
|
249
|
+
body: expect.stringContaining('Alice'),
|
|
249
250
|
});
|
|
250
251
|
});
|
|
251
252
|
|
|
252
|
-
it(
|
|
253
|
-
await expect(createUser({ name:
|
|
253
|
+
it('does not send email on validation failure', async () => {
|
|
254
|
+
await expect(createUser({ name: '', email: '' })).rejects.toThrow();
|
|
254
255
|
expect(sendEmail).not.toHaveBeenCalled();
|
|
255
256
|
});
|
|
256
257
|
});
|
|
@@ -260,11 +261,11 @@ describe("createUser", () => {
|
|
|
260
261
|
|
|
261
262
|
```typescript
|
|
262
263
|
// Spy on an existing method (don't replace it — observe it)
|
|
263
|
-
const consoleSpy = vi.spyOn(console,
|
|
264
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
264
265
|
|
|
265
266
|
await riskyOperation();
|
|
266
267
|
|
|
267
|
-
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(
|
|
268
|
+
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('failed'), expect.any(Error));
|
|
268
269
|
|
|
269
270
|
consoleSpy.mockRestore(); // restore original
|
|
270
271
|
```
|
|
@@ -275,7 +276,7 @@ consoleSpy.mockRestore(); // restore original
|
|
|
275
276
|
// ❌ BAD: Hard-coded dependency — untestable without module mocking
|
|
276
277
|
class UserService {
|
|
277
278
|
async getUser(id: string) {
|
|
278
|
-
return await fetch(`/api/users/${id}`).then(
|
|
279
|
+
return await fetch(`/api/users/${id}`).then(r => r.json());
|
|
279
280
|
}
|
|
280
281
|
}
|
|
281
282
|
|
|
@@ -294,7 +295,7 @@ class UserService {
|
|
|
294
295
|
|
|
295
296
|
// In test:
|
|
296
297
|
const mockHttp: HttpClient = {
|
|
297
|
-
get: vi.fn().mockResolvedValue({ id:
|
|
298
|
+
get: vi.fn().mockResolvedValue({ id: '1', name: 'Alice' }),
|
|
298
299
|
};
|
|
299
300
|
const service = new UserService(mockHttp);
|
|
300
301
|
|
|
@@ -308,49 +309,49 @@ const service = new UserService(mockHttp);
|
|
|
308
309
|
## React Component Testing (Testing Library)
|
|
309
310
|
|
|
310
311
|
```tsx
|
|
311
|
-
import { render, screen, waitFor } from
|
|
312
|
-
import userEvent from
|
|
313
|
-
import { describe, it, expect, vi } from
|
|
314
|
-
import { LoginForm } from
|
|
312
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
313
|
+
import userEvent from '@testing-library/user-event';
|
|
314
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
315
|
+
import { LoginForm } from './LoginForm';
|
|
315
316
|
|
|
316
|
-
describe(
|
|
317
|
-
it(
|
|
317
|
+
describe('LoginForm', () => {
|
|
318
|
+
it('renders email and password fields', () => {
|
|
318
319
|
render(<LoginForm onSubmit={vi.fn()} />);
|
|
319
320
|
|
|
320
321
|
expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
|
|
321
322
|
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
|
|
322
|
-
expect(screen.getByRole(
|
|
323
|
+
expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument();
|
|
323
324
|
});
|
|
324
325
|
|
|
325
|
-
it(
|
|
326
|
+
it('calls onSubmit with credentials', async () => {
|
|
326
327
|
const user = userEvent.setup();
|
|
327
328
|
const onSubmit = vi.fn();
|
|
328
329
|
render(<LoginForm onSubmit={onSubmit} />);
|
|
329
330
|
|
|
330
|
-
await user.type(screen.getByLabelText(/email/i),
|
|
331
|
-
await user.type(screen.getByLabelText(/password/i),
|
|
332
|
-
await user.click(screen.getByRole(
|
|
331
|
+
await user.type(screen.getByLabelText(/email/i), 'alice@test.com');
|
|
332
|
+
await user.type(screen.getByLabelText(/password/i), 'secret123');
|
|
333
|
+
await user.click(screen.getByRole('button', { name: /sign in/i }));
|
|
333
334
|
|
|
334
335
|
expect(onSubmit).toHaveBeenCalledWith({
|
|
335
|
-
email:
|
|
336
|
-
password:
|
|
336
|
+
email: 'alice@test.com',
|
|
337
|
+
password: 'secret123',
|
|
337
338
|
});
|
|
338
339
|
});
|
|
339
340
|
|
|
340
|
-
it(
|
|
341
|
+
it('shows validation error for invalid email', async () => {
|
|
341
342
|
const user = userEvent.setup();
|
|
342
343
|
render(<LoginForm onSubmit={vi.fn()} />);
|
|
343
344
|
|
|
344
|
-
await user.type(screen.getByLabelText(/email/i),
|
|
345
|
-
await user.click(screen.getByRole(
|
|
345
|
+
await user.type(screen.getByLabelText(/email/i), 'not-an-email');
|
|
346
|
+
await user.click(screen.getByRole('button', { name: /sign in/i }));
|
|
346
347
|
|
|
347
348
|
expect(screen.getByText(/invalid email/i)).toBeInTheDocument();
|
|
348
349
|
});
|
|
349
350
|
|
|
350
|
-
it(
|
|
351
|
+
it('disables submit button while loading', async () => {
|
|
351
352
|
render(<LoginForm onSubmit={vi.fn()} isLoading={true} />);
|
|
352
353
|
|
|
353
|
-
expect(screen.getByRole(
|
|
354
|
+
expect(screen.getByRole('button', { name: /sign in/i })).toBeDisabled();
|
|
354
355
|
});
|
|
355
356
|
});
|
|
356
357
|
|
|
@@ -368,50 +369,50 @@ describe("LoginForm", () => {
|
|
|
368
369
|
## E2E Testing (Playwright)
|
|
369
370
|
|
|
370
371
|
```typescript
|
|
371
|
-
import { test, expect } from
|
|
372
|
+
import { test, expect } from '@playwright/test';
|
|
372
373
|
|
|
373
|
-
test.describe(
|
|
374
|
-
test(
|
|
375
|
-
await page.goto(
|
|
374
|
+
test.describe('Login Flow', () => {
|
|
375
|
+
test('successful login redirects to dashboard', async ({ page }) => {
|
|
376
|
+
await page.goto('/login');
|
|
376
377
|
|
|
377
|
-
await page.getByLabel(
|
|
378
|
-
await page.getByLabel(
|
|
379
|
-
await page.getByRole(
|
|
378
|
+
await page.getByLabel('Email').fill('admin@test.com');
|
|
379
|
+
await page.getByLabel('Password').fill('password123');
|
|
380
|
+
await page.getByRole('button', { name: 'Sign In' }).click();
|
|
380
381
|
|
|
381
382
|
// Wait for navigation
|
|
382
|
-
await expect(page).toHaveURL(
|
|
383
|
-
await expect(page.getByRole(
|
|
383
|
+
await expect(page).toHaveURL('/dashboard');
|
|
384
|
+
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
|
|
384
385
|
});
|
|
385
386
|
|
|
386
|
-
test(
|
|
387
|
-
await page.goto(
|
|
387
|
+
test('shows error for invalid credentials', async ({ page }) => {
|
|
388
|
+
await page.goto('/login');
|
|
388
389
|
|
|
389
|
-
await page.getByLabel(
|
|
390
|
-
await page.getByLabel(
|
|
391
|
-
await page.getByRole(
|
|
390
|
+
await page.getByLabel('Email').fill('wrong@test.com');
|
|
391
|
+
await page.getByLabel('Password').fill('wrongpassword');
|
|
392
|
+
await page.getByRole('button', { name: 'Sign In' }).click();
|
|
392
393
|
|
|
393
|
-
await expect(page.getByText(
|
|
394
|
-
await expect(page).toHaveURL(
|
|
394
|
+
await expect(page.getByText('Invalid credentials')).toBeVisible();
|
|
395
|
+
await expect(page).toHaveURL('/login'); // no redirect
|
|
395
396
|
});
|
|
396
397
|
|
|
397
|
-
test(
|
|
398
|
-
test.skip(!isMobile,
|
|
398
|
+
test('responsive: mobile menu toggles', async ({ page, isMobile }) => {
|
|
399
|
+
test.skip(!isMobile, 'Mobile only');
|
|
399
400
|
|
|
400
|
-
await page.goto(
|
|
401
|
-
await page.getByRole(
|
|
402
|
-
await expect(page.getByRole(
|
|
401
|
+
await page.goto('/');
|
|
402
|
+
await page.getByRole('button', { name: 'Menu' }).click();
|
|
403
|
+
await expect(page.getByRole('navigation')).toBeVisible();
|
|
403
404
|
});
|
|
404
405
|
});
|
|
405
406
|
|
|
406
407
|
// API testing with Playwright
|
|
407
|
-
test(
|
|
408
|
-
const response = await request.post(
|
|
409
|
-
data: { name:
|
|
408
|
+
test('API: create user returns 201', async ({ request }) => {
|
|
409
|
+
const response = await request.post('/api/users', {
|
|
410
|
+
data: { name: 'Alice', email: 'alice@test.com' },
|
|
410
411
|
});
|
|
411
412
|
|
|
412
413
|
expect(response.status()).toBe(201);
|
|
413
414
|
const body = await response.json();
|
|
414
|
-
expect(body).toMatchObject({ name:
|
|
415
|
+
expect(body).toMatchObject({ name: 'Alice', email: 'alice@test.com' });
|
|
415
416
|
});
|
|
416
417
|
```
|
|
417
418
|
|
|
@@ -419,26 +420,26 @@ test("API: create user returns 201", async ({ request }) => {
|
|
|
419
420
|
|
|
420
421
|
```typescript
|
|
421
422
|
// playwright.config.ts
|
|
422
|
-
import { defineConfig } from
|
|
423
|
+
import { defineConfig } from '@playwright/test';
|
|
423
424
|
|
|
424
425
|
export default defineConfig({
|
|
425
|
-
testDir:
|
|
426
|
+
testDir: './e2e',
|
|
426
427
|
timeout: 30000,
|
|
427
428
|
retries: process.env.CI ? 2 : 0, // retry in CI only
|
|
428
429
|
use: {
|
|
429
|
-
baseURL:
|
|
430
|
-
trace:
|
|
431
|
-
screenshot:
|
|
430
|
+
baseURL: 'http://localhost:3000',
|
|
431
|
+
trace: 'on-first-retry', // save trace on failures
|
|
432
|
+
screenshot: 'only-on-failure',
|
|
432
433
|
},
|
|
433
434
|
webServer: {
|
|
434
|
-
command:
|
|
435
|
+
command: 'npm run dev',
|
|
435
436
|
port: 3000,
|
|
436
437
|
reuseExistingServer: !process.env.CI,
|
|
437
438
|
},
|
|
438
439
|
projects: [
|
|
439
|
-
{ name:
|
|
440
|
-
{ name:
|
|
441
|
-
{ name:
|
|
440
|
+
{ name: 'chrome', use: { browserName: 'chromium' } },
|
|
441
|
+
{ name: 'firefox', use: { browserName: 'firefox' } },
|
|
442
|
+
{ name: 'mobile', use: { ...devices['iPhone 14'] } },
|
|
442
443
|
],
|
|
443
444
|
});
|
|
444
445
|
```
|
|
@@ -449,26 +450,33 @@ export default defineConfig({
|
|
|
449
450
|
|
|
450
451
|
```typescript
|
|
451
452
|
// Testing REST APIs with supertest (Express/Fastify)
|
|
452
|
-
import request from
|
|
453
|
-
import { app } from
|
|
453
|
+
import request from 'supertest';
|
|
454
|
+
import { app } from './app';
|
|
454
455
|
|
|
455
|
-
describe(
|
|
456
|
-
it(
|
|
457
|
-
const response = await request(app)
|
|
456
|
+
describe('POST /api/users', () => {
|
|
457
|
+
it('creates a user and returns 201', async () => {
|
|
458
|
+
const response = await request(app)
|
|
459
|
+
.post('/api/users')
|
|
460
|
+
.send({ name: 'Alice', email: 'alice@test.com' })
|
|
461
|
+
.expect(201)
|
|
462
|
+
.expect('Content-Type', /json/);
|
|
458
463
|
|
|
459
464
|
expect(response.body).toMatchObject({
|
|
460
465
|
id: expect.any(Number),
|
|
461
|
-
name:
|
|
462
|
-
email:
|
|
466
|
+
name: 'Alice',
|
|
467
|
+
email: 'alice@test.com',
|
|
463
468
|
});
|
|
464
469
|
});
|
|
465
470
|
|
|
466
|
-
it(
|
|
467
|
-
await request(app).post(
|
|
471
|
+
it('returns 400 for missing required fields', async () => {
|
|
472
|
+
await request(app).post('/api/users').send({ name: '' }).expect(400);
|
|
468
473
|
});
|
|
469
474
|
|
|
470
|
-
it(
|
|
471
|
-
await request(app)
|
|
475
|
+
it('returns 409 for duplicate email', async () => {
|
|
476
|
+
await request(app)
|
|
477
|
+
.post('/api/users')
|
|
478
|
+
.send({ name: 'Alice', email: 'existing@test.com' })
|
|
479
|
+
.expect(409);
|
|
472
480
|
});
|
|
473
481
|
});
|
|
474
482
|
```
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before performing ultra-strict maintainability code audits, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. File Size Hard Limit Rule (300 lines max) (Section 24) → Flag any file >300 lines for immediate module decomposition
|
|
24
25
|
2. Cyclomatic Nesting Limit (3 levels max) (Section 27) → Flag nested conditionals >3 levels deep; require early guard clause returns
|
|
25
26
|
3. Direct Dependency Coupling Ban (Section 53) → Flag domain logic directly importing vendor SDKs or DB models instead of interface adapters
|
|
@@ -33,9 +34,11 @@ Execute a ruthless, zero-tolerance code maintainability audit targeting abstract
|
|
|
33
34
|
## 5 Zero-Tolerance Audit Rules
|
|
34
35
|
|
|
35
36
|
### 1. File Size Hard Limit (Max 300 Lines)
|
|
37
|
+
|
|
36
38
|
- Flag ANY single file exceeding 300 lines of code. Demand decomposition into modular helper components or sub-packages.
|
|
37
39
|
|
|
38
40
|
### 2. Cyclomatic Complexity & Nested Conditionals (Max 3 Levels)
|
|
41
|
+
|
|
39
42
|
- Flag any function with nested conditionals deeper than 3 levels (`if -> if -> if -> for`). Require early guard clause returns.
|
|
40
43
|
|
|
41
44
|
```typescript
|
|
@@ -59,9 +62,11 @@ function processOrder(order: Order) {
|
|
|
59
62
|
```
|
|
60
63
|
|
|
61
64
|
### 3. Magic Values & String Literals
|
|
65
|
+
|
|
62
66
|
- Hardcoded status strings (`"PENDING_APPROVAL_V2"`) or raw numbers (`86400000`) outside central `const` or `enum` declarations trigger immediate failure.
|
|
63
67
|
|
|
64
68
|
### 4. Direct Dependency Coupling
|
|
69
|
+
|
|
65
70
|
- Modules importing concrete database models or vendor SDKs directly inside domain business logic instead of interface adapters are rejected.
|
|
66
71
|
|
|
67
72
|
---
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before beginning any cognitive reasoning loop, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Cognitive Boundaries (Fabel Protocol) → Verify epistemic certainty levels L1 through L5
|
|
24
25
|
2. Precision Budget → Scale tool calls to task complexity (Simple: 1 call, Medium: 3-5 calls, Deep: 5-10 calls)
|
|
25
26
|
3. Stale Context rules → Re-read files after every edit to update internal context representation
|
|
@@ -29,11 +30,13 @@ Guidelines for structural reasoning and cognitive loop execution.
|
|
|
29
30
|
## Pre-Flight Checklist
|
|
30
31
|
|
|
31
32
|
Before generating any output or proposing code modifications:
|
|
33
|
+
|
|
32
34
|
- Verify that requirements are clear and unambiguous.
|
|
33
35
|
- Ensure that the suggested approach minimizes technical debt.
|
|
34
36
|
|
|
35
37
|
## Verification-Before-Completion (VBC) Protocol
|
|
36
38
|
|
|
37
39
|
Before completing a task, confirm:
|
|
40
|
+
|
|
38
41
|
- Syntax, structure, and type safety constraints are met.
|
|
39
42
|
- Relevant tests have been run and passed successfully.
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before selecting animation model (Spring vs Cubic-Bezier), you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Spring vs Duration Decision Matrix (Section 22) → Use Spring physics ONLY for interruptible gestures, drag, toggles, and playful badges
|
|
24
25
|
2. Modal & Dropdown Rule → Use deterministic cubic-bezier curves (`cubic-bezier(0.16, 1, 0.3, 1)`) for modals, dropdowns, and route transitions
|
|
25
26
|
3. Anti-Conflict Rule (Section 46) → Never specify both `duration` AND spring `stiffness/damping` parameters together in Framer Motion
|
|
@@ -30,14 +31,14 @@ Decide when to use physics-driven spring models (Framer Motion / Reanimated) vs
|
|
|
30
31
|
|
|
31
32
|
## Spring vs Duration Decision Matrix
|
|
32
33
|
|
|
33
|
-
| Motion Scenario
|
|
34
|
-
|
|
|
35
|
-
| **Interruptible Gestures** (Drag, Swipe, Sheet pull) | ✅ **ALWAYS**
|
|
36
|
-
| **Button Press Feedback** (`:active`)
|
|
37
|
-
| **Modal / Dialog Entrance**
|
|
38
|
-
| **Badge Bouncing / Celebration**
|
|
39
|
-
| **Page / Route Transitions**
|
|
40
|
-
| **Toggle Switch Flip**
|
|
34
|
+
| Motion Scenario | Use Spring Physics? | Recommended Parameters / Curve |
|
|
35
|
+
| ---------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------- |
|
|
36
|
+
| **Interruptible Gestures** (Drag, Swipe, Sheet pull) | ✅ **ALWAYS** | `type: "spring", stiffness: 300, damping: 30` (adapts to drag velocity) |
|
|
37
|
+
| **Button Press Feedback** (`:active`) | ❌ **NO (Use Curve)** | `transition: transform 120ms cubic-bezier(0.2, 0, 0, 1)` |
|
|
38
|
+
| **Modal / Dialog Entrance** | ❌ **NO (Use Curve)** | `transition: all 220ms cubic-bezier(0.16, 1, 0.3, 1)` |
|
|
39
|
+
| **Badge Bouncing / Celebration** | ✅ **YES** | `type: "spring", stiffness: 400, damping: 15` (intentional overshoot bounce) |
|
|
40
|
+
| **Page / Route Transitions** | ❌ **NO (Use Curve)** | `transition: opacity 200ms ease-out` |
|
|
41
|
+
| **Toggle Switch Flip** | ✅ **YES** | `type: "spring", stiffness: 500, damping: 35` (crisp snap without wobble) |
|
|
41
42
|
|
|
42
43
|
---
|
|
43
44
|
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before implementing CSS transitions, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Accordion Pattern (Section 35) → Use `grid-template-rows: 0fr -> 1fr` with `overflow: hidden` on inner wrapper instead of animating `height: auto`
|
|
24
25
|
2. Modal Overlay Transitions (Section 52) → Scale modal content from `scale(0.96) translateY(8px)` with opacity
|
|
25
26
|
3. Target transition properties → Enforce explicit property transitions (`transform`, `opacity`, `box-shadow`) and ban `transition: all`
|
|
@@ -31,9 +32,13 @@ Drop-in, hardware-accelerated CSS transition utility classes for modern web comp
|
|
|
31
32
|
## 4 Production Snippets
|
|
32
33
|
|
|
33
34
|
### 1. Card Lift & Shadow Scale
|
|
35
|
+
|
|
34
36
|
```css
|
|
35
37
|
.tx-card {
|
|
36
|
-
transition:
|
|
38
|
+
transition:
|
|
39
|
+
transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
40
|
+
box-shadow 200ms ease,
|
|
41
|
+
border-color 200ms ease;
|
|
37
42
|
}
|
|
38
43
|
.tx-card:hover {
|
|
39
44
|
transform: translateY(-3px);
|
|
@@ -42,14 +47,16 @@ Drop-in, hardware-accelerated CSS transition utility classes for modern web comp
|
|
|
42
47
|
```
|
|
43
48
|
|
|
44
49
|
### 2. Accordion Expand/Collapse (`grid-template-rows`)
|
|
50
|
+
|
|
45
51
|
Animate element height smoothly without hardcoding fixed pixel heights:
|
|
52
|
+
|
|
46
53
|
```css
|
|
47
54
|
.tx-accordion-content {
|
|
48
55
|
display: grid;
|
|
49
56
|
grid-template-rows: 0fr;
|
|
50
57
|
transition: grid-template-rows 250ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
51
58
|
}
|
|
52
|
-
.tx-accordion-content[data-state=
|
|
59
|
+
.tx-accordion-content[data-state='open'] {
|
|
53
60
|
grid-template-rows: 1fr;
|
|
54
61
|
}
|
|
55
62
|
.tx-accordion-inner {
|
|
@@ -58,27 +65,33 @@ Animate element height smoothly without hardcoding fixed pixel heights:
|
|
|
58
65
|
```
|
|
59
66
|
|
|
60
67
|
### 3. Slide & Fade Modal Overlay
|
|
68
|
+
|
|
61
69
|
```css
|
|
62
70
|
.tx-modal-overlay {
|
|
63
71
|
transition: opacity 200ms ease;
|
|
64
72
|
}
|
|
65
73
|
.tx-modal-content {
|
|
66
|
-
transition:
|
|
74
|
+
transition:
|
|
75
|
+
transform 220ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
76
|
+
opacity 220ms ease;
|
|
67
77
|
}
|
|
68
|
-
.tx-modal-content[data-state=
|
|
78
|
+
.tx-modal-content[data-state='closed'] {
|
|
69
79
|
opacity: 0;
|
|
70
80
|
transform: scale(0.96) translateY(8px);
|
|
71
81
|
}
|
|
72
|
-
.tx-modal-content[data-state=
|
|
82
|
+
.tx-modal-content[data-state='open'] {
|
|
73
83
|
opacity: 1;
|
|
74
84
|
transform: scale(1) translateY(0);
|
|
75
85
|
}
|
|
76
86
|
```
|
|
77
87
|
|
|
78
88
|
### 4. Sliding Tab Highlight (`layoutId` or CSS Variables)
|
|
89
|
+
|
|
79
90
|
```css
|
|
80
91
|
.tx-tab-indicator {
|
|
81
|
-
transition:
|
|
92
|
+
transition:
|
|
93
|
+
transform 200ms cubic-bezier(0.2, 0, 0, 1),
|
|
94
|
+
width 200ms ease;
|
|
82
95
|
}
|
|
83
96
|
```
|
|
84
97
|
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before recommending design trends or visual directions, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Banned AI Cliché Rule (Section 40) → Ban purple/violet gradients, generic mesh backgrounds, and un-justified left-text/right-image hero layouts
|
|
24
25
|
2. WCAG 2.2 AA Contrast Compliance (Section 61) → Calculate HSL palette contrast ($\ge 4.5:1$ text, $\ge 3:1$ large text) before finalizing tokens
|
|
25
26
|
3. Verified Google Fonts Only (Section 175) → Ensure typography recommendations are active in Google Fonts or system defaults
|