tribunal-kit 6.0.0 → 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/.manifest.json +78 -0
- package/.agent/ARCHITECTURE.md +19 -241
- 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 +3716 -1
- package/.agent/history/memory/MEMORY.md +246 -1
- package/.agent/mcp_config.json +1 -6
- package/.agent/routing_index.json +2034 -263
- package/.agent/rules/GEMINI.md +12 -10
- 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 +237 -0
- 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 +80 -0
- package/.agent/skills/ai-app-hardening/SKILL.md +59 -0
- 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 +70 -0
- 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 +59 -0
- package/.agent/skills/edge-ai-mobile/SKILL.md +50 -0
- 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 +81 -0
- 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 +59 -0
- 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 +68 -0
- package/.agent/skills/playwright-ai-e2e/SKILL.md +60 -0
- 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 +58 -0
- 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 +78 -0
- 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 +90 -0
- 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 +15 -14
- 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 +160 -88
- package/SECURITY.md +11 -11
- package/bin/mcp-server.js +512 -233
- package/bin/tribunal-kit.js +29 -30
- package/bin/wrapper.js +45 -48
- package/dist/cli.js +26 -0
- package/dist/commands/case.js +2 -0
- package/dist/commands/contract.js +440 -0
- package/dist/commands/memory.js +3 -2
- package/dist/commands/native.js +36 -0
- package/dist/commands/status.js +6 -0
- package/dist/esm/index.mjs +32 -0
- package/dist/index.d.ts +58 -3
- package/package.json +20 -16
- 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 React 19+ components or hooks, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. React 19 APIs (`useActionState` vs deprecated `useFormState`, `use()` vs `useContext`, `ref` as prop vs deprecated `forwardRef`)
|
|
24
25
|
2. React Compiler Memoization (Section 125) → Avoid manual `useMemo`/`useCallback` unless React Compiler is explicitly disabled
|
|
25
26
|
3. State Destructuring Traps (Section 189) → Never destructure entire Zustand stores; use granular selectors `useStore(s => s.value)`
|
|
@@ -40,7 +41,7 @@ Before writing React 19+ components or hooks, you MUST inspect:
|
|
|
40
41
|
### `use()` — Replaces many useEffect patterns
|
|
41
42
|
|
|
42
43
|
```tsx
|
|
43
|
-
import { use } from
|
|
44
|
+
import { use } from 'react';
|
|
44
45
|
// Reads promises (suspends until resolved)
|
|
45
46
|
function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
|
|
46
47
|
const user = use(userPromise); // suspends
|
|
@@ -56,11 +57,11 @@ function Admin({ isAdmin }: { isAdmin: boolean }) {
|
|
|
56
57
|
### `useActionState` — Form actions with state
|
|
57
58
|
|
|
58
59
|
```tsx
|
|
59
|
-
import { useActionState } from
|
|
60
|
+
import { useActionState } from 'react'; // NOT useFormState
|
|
60
61
|
|
|
61
62
|
async function submitForm(prevState: FormState, formData: FormData) {
|
|
62
|
-
const email = formData.get(
|
|
63
|
-
if (!email.includes(
|
|
63
|
+
const email = formData.get('email') as string;
|
|
64
|
+
if (!email.includes('@')) return { error: 'Invalid email' };
|
|
64
65
|
await saveToDatabase(email);
|
|
65
66
|
return { error: null, success: true };
|
|
66
67
|
}
|
|
@@ -71,7 +72,7 @@ function SignupForm() {
|
|
|
71
72
|
<form action={formAction}>
|
|
72
73
|
<input name="email" disabled={isPending} />
|
|
73
74
|
{state.error && <p>{state.error}</p>}
|
|
74
|
-
<button disabled={isPending}>{isPending ?
|
|
75
|
+
<button disabled={isPending}>{isPending ? 'Saving...' : 'Submit'}</button>
|
|
75
76
|
</form>
|
|
76
77
|
);
|
|
77
78
|
}
|
|
@@ -80,16 +81,19 @@ function SignupForm() {
|
|
|
80
81
|
### `useOptimistic` — Instant UI feedback
|
|
81
82
|
|
|
82
83
|
```tsx
|
|
83
|
-
import { useOptimistic } from
|
|
84
|
+
import { useOptimistic } from 'react';
|
|
84
85
|
function TodoList({ todos }: { todos: Todo[] }) {
|
|
85
|
-
const [optimistic, addOptimistic] = useOptimistic(todos, (current, newTodo: Todo) => [
|
|
86
|
+
const [optimistic, addOptimistic] = useOptimistic(todos, (current, newTodo: Todo) => [
|
|
87
|
+
...current,
|
|
88
|
+
newTodo,
|
|
89
|
+
]);
|
|
86
90
|
async function handleAdd(formData: FormData) {
|
|
87
|
-
addOptimistic({ id: crypto.randomUUID(), title: formData.get(
|
|
88
|
-
await saveTodo(formData.get(
|
|
91
|
+
addOptimistic({ id: crypto.randomUUID(), title: formData.get('title'), pending: true });
|
|
92
|
+
await saveTodo(formData.get('title') as string);
|
|
89
93
|
}
|
|
90
94
|
return (
|
|
91
95
|
<form action={handleAdd}>
|
|
92
|
-
{optimistic.map(
|
|
96
|
+
{optimistic.map(t => (
|
|
93
97
|
<li key={t.id} style={{ opacity: t.pending ? 0.5 : 1 }}>
|
|
94
98
|
{t.title}
|
|
95
99
|
</li>
|
|
@@ -102,11 +106,11 @@ function TodoList({ todos }: { todos: Todo[] }) {
|
|
|
102
106
|
### `useFormStatus` — Button pending state (must be INSIDE `<form>`)
|
|
103
107
|
|
|
104
108
|
```tsx
|
|
105
|
-
import { useFormStatus } from
|
|
109
|
+
import { useFormStatus } from 'react-dom';
|
|
106
110
|
// ❌ TRAP: Cannot be called in the same component as <form>
|
|
107
111
|
function SubmitButton() {
|
|
108
112
|
const { pending } = useFormStatus(); // reads nearest parent form
|
|
109
|
-
return <button disabled={pending}>{pending ?
|
|
113
|
+
return <button disabled={pending}>{pending ? 'Saving...' : 'Save'}</button>;
|
|
110
114
|
}
|
|
111
115
|
```
|
|
112
116
|
|
|
@@ -187,16 +191,16 @@ const CountDispatchCtx = createContext<Dispatch<Action>>(() => {});
|
|
|
187
191
|
### Zustand (preferred for global state)
|
|
188
192
|
|
|
189
193
|
```tsx
|
|
190
|
-
import { create } from
|
|
191
|
-
import { persist } from
|
|
194
|
+
import { create } from 'zustand';
|
|
195
|
+
import { persist } from 'zustand/middleware';
|
|
192
196
|
const useStore = create<Store>()(
|
|
193
197
|
persist(
|
|
194
198
|
(set, get) => ({
|
|
195
199
|
count: 0,
|
|
196
|
-
increment: () => set(
|
|
200
|
+
increment: () => set(s => ({ count: s.count + 1 })),
|
|
197
201
|
getDoubled: () => get().count * 2,
|
|
198
202
|
}),
|
|
199
|
-
{ name:
|
|
203
|
+
{ name: 'my-store' },
|
|
200
204
|
),
|
|
201
205
|
);
|
|
202
206
|
// ❌ TRAP: Do NOT destructure the whole store — causes re-render on every change
|
|
@@ -206,19 +210,19 @@ const useStore = create<Store>()(
|
|
|
206
210
|
### Jotai (preferred for derived/atomic state)
|
|
207
211
|
|
|
208
212
|
```tsx
|
|
209
|
-
import { atom, useAtom, useAtomValue, useSetAtom } from
|
|
213
|
+
import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai';
|
|
210
214
|
const countAtom = atom(0);
|
|
211
|
-
const doubledAtom = atom(
|
|
215
|
+
const doubledAtom = atom(get => get(countAtom) * 2); // derived atom
|
|
212
216
|
// ❌ TRAP: atomWithStorage is from jotai/utils — NOT from jotai
|
|
213
|
-
import { atomWithStorage } from
|
|
217
|
+
import { atomWithStorage } from 'jotai/utils';
|
|
214
218
|
```
|
|
215
219
|
|
|
216
220
|
### React Query / TanStack Query
|
|
217
221
|
|
|
218
222
|
```tsx
|
|
219
|
-
import { useQuery, useMutation, useQueryClient } from
|
|
223
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
220
224
|
const { data, isPending, error } = useQuery({
|
|
221
|
-
queryKey: [
|
|
225
|
+
queryKey: ['user', userId],
|
|
222
226
|
queryFn: () => fetchUser(userId),
|
|
223
227
|
staleTime: 5 * 60 * 1000, // don't refetch for 5 minutes
|
|
224
228
|
});
|
|
@@ -226,14 +230,14 @@ const { data, isPending, error } = useQuery({
|
|
|
226
230
|
const qc = useQueryClient();
|
|
227
231
|
const mutation = useMutation({
|
|
228
232
|
mutationFn: updateUser,
|
|
229
|
-
onMutate: async
|
|
230
|
-
await qc.cancelQueries({ queryKey: [
|
|
231
|
-
const prev = qc.getQueryData([
|
|
232
|
-
qc.setQueryData([
|
|
233
|
+
onMutate: async newUser => {
|
|
234
|
+
await qc.cancelQueries({ queryKey: ['user', newUser.id] });
|
|
235
|
+
const prev = qc.getQueryData(['user', newUser.id]);
|
|
236
|
+
qc.setQueryData(['user', newUser.id], newUser);
|
|
233
237
|
return { prev };
|
|
234
238
|
},
|
|
235
|
-
onError: (_, __, ctx) => qc.setQueryData([
|
|
236
|
-
onSettled: () => qc.invalidateQueries({ queryKey: [
|
|
239
|
+
onError: (_, __, ctx) => qc.setQueryData(['user'], ctx?.prev),
|
|
240
|
+
onSettled: () => qc.invalidateQueries({ queryKey: ['user'] }),
|
|
237
241
|
});
|
|
238
242
|
```
|
|
239
243
|
|
|
@@ -255,7 +259,7 @@ const mutation = useMutation({
|
|
|
255
259
|
|
|
256
260
|
```tsx
|
|
257
261
|
// React 19: ref is now a prop (no forwardRef needed)
|
|
258
|
-
function Input({ ref, ...props }: ComponentProps<
|
|
262
|
+
function Input({ ref, ...props }: ComponentProps<'input'> & { ref?: Ref<HTMLInputElement> }) {
|
|
259
263
|
return <input ref={ref} {...props} />;
|
|
260
264
|
}
|
|
261
265
|
// ❌ TRAP: forwardRef is deprecated in React 19 — still works but not needed
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before generating or updating a README file, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Mandatory Discovery Phase (Section 34) → Scan `package.json`, `pyproject.toml`, or project files first to collect factual metadata before writing
|
|
24
25
|
2. Zero Placeholder Rule (Section 28) → Ban template placeholders (`[insert here]`); generate copy-paste ready code examples from actual project code
|
|
25
26
|
3. Hero Section Lead-With-Value (Section 164) → Lead with a single-sentence value proposition and visual trust badges; ban starting with just the title
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before architecting real-time streaming or WebSocket infrastructure, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. One-Way SSE Selection Rule (Section 49) → Prefer SSE for one-way server-to-client streaming (AI responses, notifications); reserve WebSockets for bidirectional interactive features
|
|
24
25
|
2. WebSocket Exponential Reconnection (Section 183) → Implement exponential backoff with random jitter for client reconnection loops to prevent thundering herd crashes
|
|
25
26
|
3. Optimistic UI Rollback Handler (Section 207) → Capture previous state before optimistic mutations and implement explicit onError rollback logic
|
|
@@ -74,18 +75,18 @@ Before architecting real-time streaming or WebSocket infrastructure, you MUST in
|
|
|
74
75
|
|
|
75
76
|
```typescript
|
|
76
77
|
// Server (Node.js/Express)
|
|
77
|
-
app.get(
|
|
78
|
-
res.setHeader(
|
|
79
|
-
res.setHeader(
|
|
80
|
-
res.setHeader(
|
|
81
|
-
res.setHeader(
|
|
78
|
+
app.get('/api/events', (req, res) => {
|
|
79
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
80
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
81
|
+
res.setHeader('Connection', 'keep-alive');
|
|
82
|
+
res.setHeader('X-Accel-Buffering', 'no'); // disable nginx buffering
|
|
82
83
|
|
|
83
84
|
// Send initial connection event
|
|
84
|
-
res.write(`data: ${JSON.stringify({ type:
|
|
85
|
+
res.write(`data: ${JSON.stringify({ type: 'connected' })}\n\n`);
|
|
85
86
|
|
|
86
87
|
// Heartbeat to keep connection alive
|
|
87
88
|
const heartbeat = setInterval(() => {
|
|
88
|
-
res.write(
|
|
89
|
+
res.write(': heartbeat\n\n'); // comment line, ignored by client
|
|
89
90
|
}, 15000);
|
|
90
91
|
|
|
91
92
|
// Subscribe to events
|
|
@@ -97,16 +98,16 @@ app.get("/api/events", (req, res) => {
|
|
|
97
98
|
eventBus.subscribe(handler);
|
|
98
99
|
|
|
99
100
|
// Cleanup on disconnect
|
|
100
|
-
req.on(
|
|
101
|
+
req.on('close', () => {
|
|
101
102
|
clearInterval(heartbeat);
|
|
102
103
|
eventBus.unsubscribe(handler);
|
|
103
104
|
});
|
|
104
105
|
});
|
|
105
106
|
|
|
106
107
|
// Client
|
|
107
|
-
const eventSource = new EventSource(
|
|
108
|
+
const eventSource = new EventSource('/api/events');
|
|
108
109
|
|
|
109
|
-
eventSource.addEventListener(
|
|
110
|
+
eventSource.addEventListener('notification', e => {
|
|
110
111
|
const data = JSON.parse(e.data);
|
|
111
112
|
showNotification(data);
|
|
112
113
|
});
|
|
@@ -114,7 +115,7 @@ eventSource.addEventListener("notification", (e) => {
|
|
|
114
115
|
// Auto-reconnection is built-in!
|
|
115
116
|
// The browser automatically reconnects with Last-Event-ID header
|
|
116
117
|
eventSource.onerror = () => {
|
|
117
|
-
console.log(
|
|
118
|
+
console.log('Connection lost — auto-reconnecting...');
|
|
118
119
|
};
|
|
119
120
|
```
|
|
120
121
|
|
|
@@ -124,39 +125,39 @@ eventSource.onerror = () => {
|
|
|
124
125
|
|
|
125
126
|
```typescript
|
|
126
127
|
// Server (ws library)
|
|
127
|
-
import { WebSocketServer, WebSocket } from
|
|
128
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
128
129
|
|
|
129
|
-
const wss = new WebSocketServer({ server: httpServer, path:
|
|
130
|
+
const wss = new WebSocketServer({ server: httpServer, path: '/ws' });
|
|
130
131
|
|
|
131
132
|
// Connection management
|
|
132
133
|
const clients = new Map<string, WebSocket>();
|
|
133
134
|
|
|
134
|
-
wss.on(
|
|
135
|
+
wss.on('connection', (ws, req) => {
|
|
135
136
|
const userId = authenticateFromHeaders(req);
|
|
136
137
|
clients.set(userId, ws);
|
|
137
138
|
|
|
138
|
-
ws.on(
|
|
139
|
+
ws.on('message', raw => {
|
|
139
140
|
try {
|
|
140
141
|
const message = JSON.parse(raw.toString());
|
|
141
142
|
handleMessage(userId, message);
|
|
142
143
|
} catch (e) {
|
|
143
|
-
ws.send(JSON.stringify({ error:
|
|
144
|
+
ws.send(JSON.stringify({ error: 'Invalid message format' }));
|
|
144
145
|
}
|
|
145
146
|
});
|
|
146
147
|
|
|
147
|
-
ws.on(
|
|
148
|
+
ws.on('close', () => {
|
|
148
149
|
clients.delete(userId);
|
|
149
150
|
broadcastPresence();
|
|
150
151
|
});
|
|
151
152
|
|
|
152
|
-
ws.on(
|
|
153
|
+
ws.on('pong', () => {
|
|
153
154
|
// Client is alive
|
|
154
155
|
});
|
|
155
156
|
});
|
|
156
157
|
|
|
157
158
|
// Heartbeat — detect dead connections
|
|
158
159
|
const interval = setInterval(() => {
|
|
159
|
-
wss.clients.forEach(
|
|
160
|
+
wss.clients.forEach(ws => {
|
|
160
161
|
if (ws.readyState === WebSocket.OPEN) {
|
|
161
162
|
ws.ping();
|
|
162
163
|
}
|
|
@@ -211,27 +212,27 @@ class ReconnectingWebSocket {
|
|
|
211
212
|
// React pattern: update UI immediately, reconcile on server response
|
|
212
213
|
async function toggleLike(postId: string) {
|
|
213
214
|
// 1. Optimistic update (instant UI feedback)
|
|
214
|
-
setLiked(
|
|
215
|
-
setLikeCount(
|
|
215
|
+
setLiked(prev => !prev);
|
|
216
|
+
setLikeCount(prev => (liked ? prev - 1 : prev + 1));
|
|
216
217
|
|
|
217
218
|
try {
|
|
218
219
|
// 2. Server request
|
|
219
220
|
await api.post(`/posts/${postId}/like`);
|
|
220
221
|
} catch (error) {
|
|
221
222
|
// 3. Rollback on failure
|
|
222
|
-
setLiked(
|
|
223
|
-
setLikeCount(
|
|
224
|
-
toast.error(
|
|
223
|
+
setLiked(prev => !prev);
|
|
224
|
+
setLikeCount(prev => (liked ? prev + 1 : prev - 1));
|
|
225
|
+
toast.error('Failed to update. Please try again.');
|
|
225
226
|
}
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
// With React Query / TanStack Query:
|
|
229
230
|
const likeMutation = useMutation({
|
|
230
231
|
mutationFn: (postId: string) => api.post(`/posts/${postId}/like`),
|
|
231
|
-
onMutate: async
|
|
232
|
-
await queryClient.cancelQueries({ queryKey: [
|
|
233
|
-
const previous = queryClient.getQueryData([
|
|
234
|
-
queryClient.setQueryData([
|
|
232
|
+
onMutate: async postId => {
|
|
233
|
+
await queryClient.cancelQueries({ queryKey: ['post', postId] });
|
|
234
|
+
const previous = queryClient.getQueryData(['post', postId]);
|
|
235
|
+
queryClient.setQueryData(['post', postId], (old: Post) => ({
|
|
235
236
|
...old,
|
|
236
237
|
liked: !old.liked,
|
|
237
238
|
likeCount: old.liked ? old.likeCount - 1 : old.likeCount + 1,
|
|
@@ -239,10 +240,10 @@ const likeMutation = useMutation({
|
|
|
239
240
|
return { previous };
|
|
240
241
|
},
|
|
241
242
|
onError: (err, postId, context) => {
|
|
242
|
-
queryClient.setQueryData([
|
|
243
|
+
queryClient.setQueryData(['post', postId], context?.previous);
|
|
243
244
|
},
|
|
244
245
|
onSettled: (data, err, postId) => {
|
|
245
|
-
queryClient.invalidateQueries({ queryKey: [
|
|
246
|
+
queryClient.invalidateQueries({ queryKey: ['post', postId] });
|
|
246
247
|
},
|
|
247
248
|
});
|
|
248
249
|
```
|
|
@@ -256,7 +257,7 @@ const likeMutation = useMutation({
|
|
|
256
257
|
|
|
257
258
|
interface PresenceState {
|
|
258
259
|
userId: string;
|
|
259
|
-
status:
|
|
260
|
+
status: 'online' | 'away' | 'offline';
|
|
260
261
|
cursor?: { x: number; y: number };
|
|
261
262
|
lastSeen: number;
|
|
262
263
|
}
|
|
@@ -270,7 +271,7 @@ class PresenceManager {
|
|
|
270
271
|
this.presence.set(userId, {
|
|
271
272
|
...this.presence.get(userId),
|
|
272
273
|
userId,
|
|
273
|
-
status:
|
|
274
|
+
status: 'online',
|
|
274
275
|
lastSeen: Date.now(),
|
|
275
276
|
...state,
|
|
276
277
|
} as PresenceState);
|
|
@@ -278,7 +279,7 @@ class PresenceManager {
|
|
|
278
279
|
|
|
279
280
|
getActive(): PresenceState[] {
|
|
280
281
|
const now = Date.now();
|
|
281
|
-
return [...this.presence.values()].filter(
|
|
282
|
+
return [...this.presence.values()].filter(p => now - p.lastSeen < this.TIMEOUT_MS);
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
remove(userId: string) {
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before performing red team assessments or security testing, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Written Authorization Gate (Section 34) → Verify written authorization, defined scope, rules of engagement, and emergency contact before executing tests
|
|
24
25
|
2. Reproducible PoC Rule (Section 16) → Include a reproducible Proof-of-Concept, CVSS risk score, and explicit remediation snippet for every finding
|
|
25
26
|
3. Breach Discovery Halt (Section 162) → Immediately halt security testing and report if evidence of an active real-world breach is discovered
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before executing interface redesigns, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Logic Isolation Rule (Section 24) → Extract and preserve ALL state hooks (`useState`), event handlers (`onClick`), and API props before altering layout
|
|
24
25
|
2. Surface Hierarchy (Section 32) → Upgrade raw hex backgrounds to OKLCH surface levels (`--bg-base`, `--bg-surface`, `--bg-elevated`)
|
|
25
26
|
3. Spatial Grid (Section 28) → Standardize spacing to an 8px system (`gap-4`, `p-6`) with `text-wrap: balance` on headings
|
|
@@ -31,18 +32,23 @@ Audit legacy or unstyled user interfaces and transform them into modern, product
|
|
|
31
32
|
## 4 Redesign Upgrade Steps
|
|
32
33
|
|
|
33
34
|
### Step 1: Logic & State Isolation
|
|
35
|
+
|
|
34
36
|
Before touching CSS or HTML layout:
|
|
37
|
+
|
|
35
38
|
- Extract all state hooks (`useState`), event handlers (`onClick`), and API props. **Zero business logic may be deleted or altered.**
|
|
36
39
|
|
|
37
40
|
### Step 2: Spatial & Typographic Grid Overhaul
|
|
41
|
+
|
|
38
42
|
- Replace arbitrary pixel margins with an 8px spatial system (`gap-4`, `p-6`).
|
|
39
43
|
- Apply modular font scaling (`text-sm`, `text-base`, `text-2xl`, `text-4xl`) with `text-wrap: balance` on headings.
|
|
40
44
|
|
|
41
45
|
### Step 3: Color & Surface Elevation Upgrade
|
|
46
|
+
|
|
42
47
|
- Replace raw `#fff` / `#000` colors with an OKLCH surface hierarchy (`--bg-base`, `--bg-surface`, `--bg-elevated`).
|
|
43
48
|
- Replace hard black borders with subtle 8% opacity surface borders and multi-layered ambient shadows.
|
|
44
49
|
|
|
45
50
|
### Step 4: Micro-Interaction & Polish Pass
|
|
51
|
+
|
|
46
52
|
- Add `:active` scale press feedback (`scale(0.97)`), smooth hover state transitions, and keyboard focus rings (`:focus-visible`).
|
|
47
53
|
|
|
48
54
|
---
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before auditing animation code or reviewing motion diffs, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Sub-300ms UI Duration Limit (Section 35) → Enforce maximum 300ms duration for UI element animations; flag any sluggish transitions >300ms
|
|
24
25
|
2. GPU-Only Property Constraint (Section 38) → Flag any animation of layout-heavy properties (`width`/`height`/`top`/`left`); require `transform` and `opacity`
|
|
25
26
|
3. Physical Correctness & Origin (Section 36) → Flag `scale(0)` entrances; require `scale(0.9–0.97)` with `opacity` and accurate `transform-origin`
|
|
@@ -32,7 +33,7 @@ A specialized review skill. It does ONE thing: review animation and motion code
|
|
|
32
33
|
|
|
33
34
|
You are a senior motion-design reviewer with a brutal eye for craft. Your bias is toward **motion that feels right**, not motion that merely runs. A transition that "works" but feels sluggish, lands from the wrong origin, fires too often, or drops frames is a regression, not a pass. Default to flagging. Approval is earned, not assumed.
|
|
34
35
|
|
|
35
|
-
The substantive bar comes from Emil Kowalski's animation philosophy (animations.dev). The review
|
|
36
|
+
The substantive bar comes from Emil Kowalski's animation philosophy (animations.dev). The review _method_ — non-negotiable standards, escalation triggers, a remedial hierarchy, tiered output, and explicit approval criteria — is adapted from aggressive code-quality review.
|
|
36
37
|
|
|
37
38
|
For the full rule catalog (easing curves, duration tables, spring config, gestures, clip-path, performance, a11y), see [STANDARDS.md](STANDARDS.md). Load it whenever a finding needs a precise value or citation.
|
|
38
39
|
|
|
@@ -55,7 +56,7 @@ Every animation in the diff is measured against these. A violation is a finding.
|
|
|
55
56
|
|
|
56
57
|
## 🤖 LLM-Specific Traps
|
|
57
58
|
|
|
58
|
-
1. **Passive Approval:** Approving animations just because the syntax is correct. You must evaluate the
|
|
59
|
+
1. **Passive Approval:** Approving animations just because the syntax is correct. You must evaluate the _feel_ and _performance_ against the Standards.
|
|
59
60
|
2. **Ignoring Physics:** Failing to flag elements appearing from nothing (`scale(0)`) or scaling from the wrong origin point.
|
|
60
61
|
3. **Overlooking Duration:** Missing sluggish transitions that exceed the 300ms budget for UI elements.
|
|
61
62
|
4. **Accepting Default Easings:** Approving `ease-in` or generic `ease` on entering UI elements instead of demanding strong `ease-out` curves.
|
|
@@ -68,6 +69,7 @@ Every animation in the diff is measured against these. A violation is a finding.
|
|
|
68
69
|
### ✅ Pre-Flight Self-Audit
|
|
69
70
|
|
|
70
71
|
Review these questions before confirming output:
|
|
72
|
+
|
|
71
73
|
```
|
|
72
74
|
✅ Did I measure the diff against all 10 non-negotiable standards?
|
|
73
75
|
✅ Did I flag any UI animations exceeding 300ms?
|
|
@@ -79,5 +81,6 @@ Review these questions before confirming output:
|
|
|
79
81
|
### 🛑 Verification-Before-Completion (VBC) Protocol
|
|
80
82
|
|
|
81
83
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
84
|
+
|
|
82
85
|
- ❌ **Forbidden:** Marking the review as "Pass" without explicitly evaluating against the STANDARDS.md criteria.
|
|
83
86
|
- ✅ **Required:** Output the review in the standard table format (`| Before | After | Why |`) highlighting all violations, and explicitly stating why approval is earned or withheld.
|
|
@@ -4,45 +4,47 @@ The precise values, curves, and rules behind the review. Cite these in findings
|
|
|
4
4
|
|
|
5
5
|
## Should it animate? (frequency table)
|
|
6
6
|
|
|
7
|
-
| Frequency
|
|
8
|
-
|
|
|
9
|
-
| 100+ times/day (keyboard shortcuts, command palette)
|
|
10
|
-
| Tens of times/day (hover effects, list navigation)
|
|
11
|
-
| Occasional (modals, drawers, toasts)
|
|
12
|
-
| Rare / first-time (onboarding, feedback, celebrations) | Can add delight
|
|
13
|
-
|
|
14
|
-
**Never animate keyboard-initiated actions** — they repeat hundreds of times daily; animation makes them feel slow and disconnected.
|
|
7
|
+
| Frequency | Decision |
|
|
8
|
+
| ------------------------------------------------------ | ---------------------------- |
|
|
9
|
+
| 100+ times/day (keyboard shortcuts, command palette) | No animation. Ever. |
|
|
10
|
+
| Tens of times/day (hover effects, list navigation) | Remove or drastically reduce |
|
|
11
|
+
| Occasional (modals, drawers, toasts) | Standard animation |
|
|
12
|
+
| Rare / first-time (onboarding, feedback, celebrations) | Can add delight |
|
|
13
|
+
|
|
14
|
+
**Never animate keyboard-initiated actions** — they repeat hundreds of times daily; animation makes them feel slow and disconnected.
|
|
15
15
|
Valid purposes for motion: spatial consistency, state indication, explanation, feedback, preventing jarring change. "It looks cool" on a frequently-seen element is not valid.
|
|
16
16
|
|
|
17
17
|
## Easing
|
|
18
18
|
|
|
19
19
|
Decision order:
|
|
20
|
+
|
|
20
21
|
- Entering or exiting → **`ease-out`** (starts fast, feels responsive)
|
|
21
22
|
- Moving / morphing on screen → **`ease-in-out`**
|
|
22
23
|
- Hover / color change → **`ease`**
|
|
23
24
|
- Constant motion (marquee, progress) → **`linear`**
|
|
24
25
|
- Default → **`ease-out`**
|
|
25
26
|
|
|
26
|
-
**Never `ease-in` on UI.** It starts slow, delaying the exact moment the user is watching. `ease-out` at 200ms
|
|
27
|
+
**Never `ease-in` on UI.** It starts slow, delaying the exact moment the user is watching. `ease-out` at 200ms _feels_ faster than `ease-in` at 200ms.
|
|
27
28
|
|
|
28
29
|
Built-in CSS easings are too weak. Use strong custom curves:
|
|
30
|
+
|
|
29
31
|
```css
|
|
30
|
-
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
|
|
31
|
-
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
|
|
32
|
-
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
|
|
32
|
+
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* strong ease-out for UI */
|
|
33
|
+
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* strong ease-in-out for on-screen movement */
|
|
34
|
+
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS-like drawer curve (Ionic) */
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
## Duration
|
|
36
38
|
|
|
37
|
-
| Element
|
|
38
|
-
|
|
|
39
|
-
| Button press feedback
|
|
40
|
-
| Tooltips, small popovers | 125–200ms
|
|
41
|
-
| Dropdowns, selects
|
|
42
|
-
| Modals, drawers
|
|
43
|
-
| Marketing / explanatory
|
|
39
|
+
| Element | Duration |
|
|
40
|
+
| ------------------------ | ------------- |
|
|
41
|
+
| Button press feedback | 100–160ms |
|
|
42
|
+
| Tooltips, small popovers | 125–200ms |
|
|
43
|
+
| Dropdowns, selects | 150–250ms |
|
|
44
|
+
| Modals, drawers | 200–500ms |
|
|
45
|
+
| Marketing / explanatory | Can be longer |
|
|
44
46
|
|
|
45
|
-
**Rule: UI animations stay under 300ms.** A 180ms dropdown feels more responsive than a 400ms one.
|
|
47
|
+
**Rule: UI animations stay under 300ms.** A 180ms dropdown feels more responsive than a 400ms one.
|
|
46
48
|
|
|
47
49
|
## Physicality
|
|
48
50
|
|
|
@@ -53,21 +55,33 @@ Built-in CSS easings are too weak. Use strong custom curves:
|
|
|
53
55
|
## Springs
|
|
54
56
|
|
|
55
57
|
Feel natural because they simulate physics; no fixed duration. Use for drag with momentum, interruptible gestures.
|
|
58
|
+
|
|
56
59
|
```js
|
|
57
60
|
// Apple-style (easier to reason about) — recommended
|
|
58
61
|
{ type: "spring", duration: 0.5, bounce: 0.2 }
|
|
59
62
|
```
|
|
60
|
-
|
|
63
|
+
|
|
64
|
+
Keep bounce subtle (0.1–0.3); avoid bounce in most UI.
|
|
61
65
|
|
|
62
66
|
## Interruptibility
|
|
63
67
|
|
|
64
68
|
CSS **transitions** can be interrupted and retargeted mid-animation; **keyframes** restart from zero. For anything triggered rapidly, transitions are smoother.
|
|
69
|
+
|
|
65
70
|
```css
|
|
66
71
|
/* Interruptible — good for dynamic UI */
|
|
67
|
-
.toast {
|
|
72
|
+
.toast {
|
|
73
|
+
transition: transform 400ms ease;
|
|
74
|
+
}
|
|
68
75
|
|
|
69
76
|
/* Not interruptible — avoid for dynamic UI */
|
|
70
|
-
@keyframes slideIn {
|
|
77
|
+
@keyframes slideIn {
|
|
78
|
+
from {
|
|
79
|
+
transform: translateY(100%);
|
|
80
|
+
}
|
|
81
|
+
to {
|
|
82
|
+
transform: translateY(0);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
71
85
|
```
|
|
72
86
|
|
|
73
87
|
Use `@starting-style` for entry without JS.
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before writing Rust code or Axum handlers, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Production Error Propagation (Section 130) → Use `?` operator and structured `Result<T, E>`; ban `.unwrap()` in production code
|
|
24
25
|
2. Library vs App Error Strategy (Section 192) → Use `thiserror` for library crates to export structured errors; use `anyhow` only for application code
|
|
25
26
|
3. Axum 0.7+ Route Parameters (Section 444) → Use `{id}` bracket syntax for path parameters (`/users/{id}`); ban legacy `:id` syntax
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before implementing metadata or search optimization, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. One H1 Heading Law (Section 64) → Ensure exactly ONE `<h1>` per page for document title; ban multiple `<h1>` tags or missing H1s
|
|
24
25
|
2. Server-Side Rendering (SSR/SSG) Rule (Section 18) → Use SSR/SSG for indexable pages; ban client-side-only rendering for public SEO content
|
|
25
26
|
3. JSON-LD Structured Data Injection (Section 86) → Inject Schema.org JSON-LD scripts (`application/ld+json`) for rich entity indexing
|
|
@@ -43,7 +44,7 @@ Do not use legacy `next/head` tags scattered across components. Use the built-in
|
|
|
43
44
|
|
|
44
45
|
```typescript
|
|
45
46
|
// app/blog/[slug]/page.tsx
|
|
46
|
-
import { Metadata } from
|
|
47
|
+
import { Metadata } from 'next';
|
|
47
48
|
|
|
48
49
|
export async function generateMetadata({ params }): Promise<Metadata> {
|
|
49
50
|
const post = await fetchPost(params.slug);
|
|
@@ -58,12 +59,12 @@ export async function generateMetadata({ params }): Promise<Metadata> {
|
|
|
58
59
|
openGraph: {
|
|
59
60
|
title: post.title,
|
|
60
61
|
description: post.excerpt,
|
|
61
|
-
type:
|
|
62
|
+
type: 'article',
|
|
62
63
|
url: `https://example.com/blog/${params.slug}`,
|
|
63
64
|
images: [{ url: post.coverImageUrl, width: 1200, height: 630 }],
|
|
64
65
|
},
|
|
65
66
|
twitter: {
|
|
66
|
-
card:
|
|
67
|
+
card: 'summary_large_image', // Critical for big Twitter link previews
|
|
67
68
|
},
|
|
68
69
|
};
|
|
69
70
|
}
|
|
@@ -20,6 +20,7 @@ scripts-binding:
|
|
|
20
20
|
## Mandatory Pre-Flight Context Inspection
|
|
21
21
|
|
|
22
22
|
Before configuring Linux servers, Nginx, or systemd services, you MUST inspect:
|
|
23
|
+
|
|
23
24
|
1. Dedicated Non-Root User Execution (Section 39) → Run systemd services strictly under non-root users (`User=appuser`); ban running app services as root
|
|
24
25
|
2. Nginx Syntax Verification (`nginx -t`) (Section 17) → Always verify Nginx configuration (`sudo nginx -t`) BEFORE reloading systemd services
|
|
25
26
|
3. SSH & UFW Hardening Defaults (Section 126) → Disable password auth & root login (`PermitRootLogin no`), and configure UFW default deny incoming
|