javi-forge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore.template +105 -0
- package/.releaserc +44 -0
- package/README.md +45 -0
- package/ai-config/.skillignore +15 -0
- package/ai-config/AUTO_INVOKE.md +300 -0
- package/ai-config/agents/_TEMPLATE.md +93 -0
- package/ai-config/agents/business/api-designer.md +1657 -0
- package/ai-config/agents/business/business-analyst.md +1331 -0
- package/ai-config/agents/business/product-strategist.md +206 -0
- package/ai-config/agents/business/project-manager.md +178 -0
- package/ai-config/agents/business/requirements-analyst.md +1277 -0
- package/ai-config/agents/business/technical-writer.md +1679 -0
- package/ai-config/agents/creative/ux-designer.md +205 -0
- package/ai-config/agents/data-ai/ai-engineer.md +487 -0
- package/ai-config/agents/data-ai/analytics-engineer.md +953 -0
- package/ai-config/agents/data-ai/data-engineer.md +173 -0
- package/ai-config/agents/data-ai/data-scientist.md +672 -0
- package/ai-config/agents/data-ai/mlops-engineer.md +814 -0
- package/ai-config/agents/data-ai/prompt-engineer.md +772 -0
- package/ai-config/agents/development/angular-expert.md +620 -0
- package/ai-config/agents/development/backend-architect.md +795 -0
- package/ai-config/agents/development/database-specialist.md +212 -0
- package/ai-config/agents/development/frontend-specialist.md +686 -0
- package/ai-config/agents/development/fullstack-engineer.md +668 -0
- package/ai-config/agents/development/golang-pro.md +338 -0
- package/ai-config/agents/development/java-enterprise.md +400 -0
- package/ai-config/agents/development/javascript-pro.md +422 -0
- package/ai-config/agents/development/nextjs-pro.md +474 -0
- package/ai-config/agents/development/python-pro.md +570 -0
- package/ai-config/agents/development/react-pro.md +487 -0
- package/ai-config/agents/development/rust-pro.md +246 -0
- package/ai-config/agents/development/spring-boot-4-expert.md +326 -0
- package/ai-config/agents/development/typescript-pro.md +336 -0
- package/ai-config/agents/development/vue-specialist.md +605 -0
- package/ai-config/agents/infrastructure/cloud-architect.md +472 -0
- package/ai-config/agents/infrastructure/deployment-manager.md +358 -0
- package/ai-config/agents/infrastructure/devops-engineer.md +455 -0
- package/ai-config/agents/infrastructure/incident-responder.md +519 -0
- package/ai-config/agents/infrastructure/kubernetes-expert.md +705 -0
- package/ai-config/agents/infrastructure/monitoring-specialist.md +674 -0
- package/ai-config/agents/infrastructure/performance-engineer.md +658 -0
- package/ai-config/agents/orchestrator.md +241 -0
- package/ai-config/agents/quality/accessibility-auditor.md +1204 -0
- package/ai-config/agents/quality/code-reviewer-compact.md +123 -0
- package/ai-config/agents/quality/code-reviewer.md +363 -0
- package/ai-config/agents/quality/dependency-manager.md +743 -0
- package/ai-config/agents/quality/e2e-test-specialist.md +1005 -0
- package/ai-config/agents/quality/performance-tester.md +1086 -0
- package/ai-config/agents/quality/security-auditor.md +133 -0
- package/ai-config/agents/quality/test-engineer.md +453 -0
- package/ai-config/agents/specialists/api-designer.md +87 -0
- package/ai-config/agents/specialists/backend-architect.md +73 -0
- package/ai-config/agents/specialists/code-reviewer.md +77 -0
- package/ai-config/agents/specialists/db-optimizer.md +75 -0
- package/ai-config/agents/specialists/devops-engineer.md +83 -0
- package/ai-config/agents/specialists/documentation-writer.md +78 -0
- package/ai-config/agents/specialists/frontend-developer.md +75 -0
- package/ai-config/agents/specialists/performance-analyst.md +82 -0
- package/ai-config/agents/specialists/refactor-specialist.md +74 -0
- package/ai-config/agents/specialists/security-auditor.md +74 -0
- package/ai-config/agents/specialists/test-engineer.md +81 -0
- package/ai-config/agents/specialists/ux-consultant.md +76 -0
- package/ai-config/agents/specialized/agent-generator.md +1190 -0
- package/ai-config/agents/specialized/blockchain-developer.md +149 -0
- package/ai-config/agents/specialized/code-migrator.md +892 -0
- package/ai-config/agents/specialized/context-manager.md +978 -0
- package/ai-config/agents/specialized/documentation-writer.md +1078 -0
- package/ai-config/agents/specialized/ecommerce-expert.md +1756 -0
- package/ai-config/agents/specialized/embedded-engineer.md +1714 -0
- package/ai-config/agents/specialized/error-detective.md +1034 -0
- package/ai-config/agents/specialized/fintech-specialist.md +1659 -0
- package/ai-config/agents/specialized/freelance-project-planner-v2.md +1988 -0
- package/ai-config/agents/specialized/freelance-project-planner-v3.md +2136 -0
- package/ai-config/agents/specialized/freelance-project-planner-v4.md +4503 -0
- package/ai-config/agents/specialized/freelance-project-planner.md +722 -0
- package/ai-config/agents/specialized/game-developer.md +1963 -0
- package/ai-config/agents/specialized/healthcare-dev.md +1620 -0
- package/ai-config/agents/specialized/mobile-developer.md +188 -0
- package/ai-config/agents/specialized/parallel-plan-executor.md +506 -0
- package/ai-config/agents/specialized/plan-executor.md +485 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +485 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +3493 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +778 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +918 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +1537 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +2633 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +5610 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +335 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +215 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +260 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +379 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +355 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +279 -0
- package/ai-config/agents/specialized/template-writer.md +347 -0
- package/ai-config/agents/specialized/test-runner.md +99 -0
- package/ai-config/agents/specialized/vibekanban-smart-worker.md +244 -0
- package/ai-config/agents/specialized/wave-executor.md +138 -0
- package/ai-config/agents/specialized/workflow-optimizer.md +1114 -0
- package/ai-config/commands/git/changelog.md +32 -0
- package/ai-config/commands/git/ci-local.md +70 -0
- package/ai-config/commands/git/commit.md +35 -0
- package/ai-config/commands/git/fix-issue.md +23 -0
- package/ai-config/commands/git/pr-create.md +42 -0
- package/ai-config/commands/git/pr-review.md +50 -0
- package/ai-config/commands/git/worktree.md +39 -0
- package/ai-config/commands/refactoring/cleanup.md +24 -0
- package/ai-config/commands/refactoring/dead-code.md +40 -0
- package/ai-config/commands/refactoring/extract.md +31 -0
- package/ai-config/commands/testing/e2e.md +30 -0
- package/ai-config/commands/testing/tdd.md +36 -0
- package/ai-config/commands/testing/test-coverage.md +30 -0
- package/ai-config/commands/testing/test-fix.md +24 -0
- package/ai-config/commands/workflow/generate-agents-md.md +85 -0
- package/ai-config/commands/workflow/planning.md +47 -0
- package/ai-config/commands/workflows/compound.md +89 -0
- package/ai-config/commands/workflows/plan.md +77 -0
- package/ai-config/commands/workflows/review.md +78 -0
- package/ai-config/commands/workflows/work.md +75 -0
- package/ai-config/config.yaml +18 -0
- package/ai-config/hooks/_TEMPLATE.md +96 -0
- package/ai-config/hooks/block-dangerous-commands.md +75 -0
- package/ai-config/hooks/commit-guard.md +90 -0
- package/ai-config/hooks/context-loader.md +73 -0
- package/ai-config/hooks/improve-prompt.md +91 -0
- package/ai-config/hooks/learning-log.md +72 -0
- package/ai-config/hooks/model-router.md +86 -0
- package/ai-config/hooks/secret-scanner.md +64 -0
- package/ai-config/hooks/skill-validator.md +102 -0
- package/ai-config/hooks/task-artifact.md +114 -0
- package/ai-config/hooks/validate-workflow.md +100 -0
- package/ai-config/prompts/base.md +71 -0
- package/ai-config/prompts/modes/debug.md +34 -0
- package/ai-config/prompts/modes/deploy.md +40 -0
- package/ai-config/prompts/modes/research.md +32 -0
- package/ai-config/prompts/modes/review.md +33 -0
- package/ai-config/prompts/review-policy.md +79 -0
- package/ai-config/skills/_TEMPLATE.md +157 -0
- package/ai-config/skills/backend/api-gateway/SKILL.md +254 -0
- package/ai-config/skills/backend/bff-concepts/SKILL.md +239 -0
- package/ai-config/skills/backend/bff-spring/SKILL.md +364 -0
- package/ai-config/skills/backend/chi-router/SKILL.md +396 -0
- package/ai-config/skills/backend/error-handling/SKILL.md +255 -0
- package/ai-config/skills/backend/exceptions-spring/SKILL.md +323 -0
- package/ai-config/skills/backend/fastapi/SKILL.md +302 -0
- package/ai-config/skills/backend/gateway-spring/SKILL.md +390 -0
- package/ai-config/skills/backend/go-backend/SKILL.md +457 -0
- package/ai-config/skills/backend/gradle-multimodule/SKILL.md +274 -0
- package/ai-config/skills/backend/graphql-concepts/SKILL.md +352 -0
- package/ai-config/skills/backend/graphql-spring/SKILL.md +398 -0
- package/ai-config/skills/backend/grpc-concepts/SKILL.md +283 -0
- package/ai-config/skills/backend/grpc-spring/SKILL.md +445 -0
- package/ai-config/skills/backend/jwt-auth/SKILL.md +412 -0
- package/ai-config/skills/backend/notifications-concepts/SKILL.md +259 -0
- package/ai-config/skills/backend/recommendations-concepts/SKILL.md +261 -0
- package/ai-config/skills/backend/search-concepts/SKILL.md +263 -0
- package/ai-config/skills/backend/search-spring/SKILL.md +375 -0
- package/ai-config/skills/backend/spring-boot-4/SKILL.md +172 -0
- package/ai-config/skills/backend/websockets/SKILL.md +532 -0
- package/ai-config/skills/data-ai/ai-ml/SKILL.md +423 -0
- package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +195 -0
- package/ai-config/skills/data-ai/analytics-spring/SKILL.md +340 -0
- package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +440 -0
- package/ai-config/skills/data-ai/langchain/SKILL.md +238 -0
- package/ai-config/skills/data-ai/mlflow/SKILL.md +302 -0
- package/ai-config/skills/data-ai/onnx-inference/SKILL.md +290 -0
- package/ai-config/skills/data-ai/powerbi/SKILL.md +352 -0
- package/ai-config/skills/data-ai/pytorch/SKILL.md +274 -0
- package/ai-config/skills/data-ai/scikit-learn/SKILL.md +321 -0
- package/ai-config/skills/data-ai/vector-db/SKILL.md +301 -0
- package/ai-config/skills/database/graph-databases/SKILL.md +218 -0
- package/ai-config/skills/database/graph-spring/SKILL.md +361 -0
- package/ai-config/skills/database/pgx-postgres/SKILL.md +512 -0
- package/ai-config/skills/database/redis-cache/SKILL.md +343 -0
- package/ai-config/skills/database/sqlite-embedded/SKILL.md +388 -0
- package/ai-config/skills/database/timescaledb/SKILL.md +320 -0
- package/ai-config/skills/docs/api-documentation/SKILL.md +293 -0
- package/ai-config/skills/docs/docs-spring/SKILL.md +377 -0
- package/ai-config/skills/docs/mustache-templates/SKILL.md +190 -0
- package/ai-config/skills/docs/technical-docs/SKILL.md +447 -0
- package/ai-config/skills/frontend/astro-ssr/SKILL.md +441 -0
- package/ai-config/skills/frontend/frontend-design/SKILL.md +54 -0
- package/ai-config/skills/frontend/frontend-web/SKILL.md +368 -0
- package/ai-config/skills/frontend/mantine-ui/SKILL.md +396 -0
- package/ai-config/skills/frontend/tanstack-query/SKILL.md +439 -0
- package/ai-config/skills/frontend/zod-validation/SKILL.md +417 -0
- package/ai-config/skills/frontend/zustand-state/SKILL.md +350 -0
- package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +244 -0
- package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +378 -0
- package/ai-config/skills/infrastructure/devops-infra/SKILL.md +435 -0
- package/ai-config/skills/infrastructure/docker-containers/SKILL.md +420 -0
- package/ai-config/skills/infrastructure/kubernetes/SKILL.md +456 -0
- package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +546 -0
- package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +474 -0
- package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +315 -0
- package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +504 -0
- package/ai-config/skills/mobile/mobile-ionic/SKILL.md +448 -0
- package/ai-config/skills/prompt-improver/SKILL.md +125 -0
- package/ai-config/skills/quality/ghagga-review/SKILL.md +216 -0
- package/ai-config/skills/references/hooks-patterns/SKILL.md +238 -0
- package/ai-config/skills/references/mcp-servers/SKILL.md +275 -0
- package/ai-config/skills/references/plugins-reference/SKILL.md +110 -0
- package/ai-config/skills/references/skills-reference/SKILL.md +420 -0
- package/ai-config/skills/references/subagent-templates/SKILL.md +193 -0
- package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +410 -0
- package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +408 -0
- package/ai-config/skills/systems-iot/rust-systems/SKILL.md +386 -0
- package/ai-config/skills/systems-iot/tokio-async/SKILL.md +324 -0
- package/ai-config/skills/testing/playwright-e2e/SKILL.md +289 -0
- package/ai-config/skills/testing/testcontainers/SKILL.md +299 -0
- package/ai-config/skills/testing/vitest-testing/SKILL.md +381 -0
- package/ai-config/skills/workflow/ci-local-guide/SKILL.md +118 -0
- package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +299 -0
- package/ai-config/skills/workflow/claude-md-improver/SKILL.md +158 -0
- package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +117 -0
- package/ai-config/skills/workflow/git-github/SKILL.md +334 -0
- package/ai-config/skills/workflow/git-github/references/examples.md +160 -0
- package/ai-config/skills/workflow/git-workflow/SKILL.md +214 -0
- package/ai-config/skills/workflow/ide-plugins/SKILL.md +277 -0
- package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +401 -0
- package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +199 -0
- package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +100 -0
- package/ai-config/skills/workflow/verification-before-completion/SKILL.md +73 -0
- package/ai-config/skills/workflow/wave-workflow/SKILL.md +178 -0
- package/ci-local/README.md +170 -0
- package/ci-local/ci-local.sh +297 -0
- package/ci-local/hooks/commit-msg +74 -0
- package/ci-local/hooks/pre-commit +162 -0
- package/ci-local/hooks/pre-push +41 -0
- package/ci-local/install.sh +49 -0
- package/ci-local/semgrep.yml +214 -0
- package/dist/commands/analyze.d.ts +9 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +55 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/analyze.test.d.ts +2 -0
- package/dist/commands/analyze.test.d.ts.map +1 -0
- package/dist/commands/analyze.test.js +145 -0
- package/dist/commands/analyze.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +158 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.test.d.ts +2 -0
- package/dist/commands/doctor.test.d.ts.map +1 -0
- package/dist/commands/doctor.test.js +200 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +283 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +271 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +201 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +57 -0
- package/dist/constants.js.map +1 -0
- package/dist/e2e/aggressive.e2e.test.d.ts +2 -0
- package/dist/e2e/aggressive.e2e.test.d.ts.map +1 -0
- package/dist/e2e/aggressive.e2e.test.js +350 -0
- package/dist/e2e/aggressive.e2e.test.js.map +1 -0
- package/dist/e2e/commands.e2e.test.d.ts +2 -0
- package/dist/e2e/commands.e2e.test.d.ts.map +1 -0
- package/dist/e2e/commands.e2e.test.js +213 -0
- package/dist/e2e/commands.e2e.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/common.d.ts +17 -0
- package/dist/lib/common.d.ts.map +1 -0
- package/dist/lib/common.js +111 -0
- package/dist/lib/common.js.map +1 -0
- package/dist/lib/common.test.d.ts +2 -0
- package/dist/lib/common.test.d.ts.map +1 -0
- package/dist/lib/common.test.js +316 -0
- package/dist/lib/common.test.js.map +1 -0
- package/dist/lib/frontmatter.d.ts +18 -0
- package/dist/lib/frontmatter.d.ts.map +1 -0
- package/dist/lib/frontmatter.js +61 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/frontmatter.test.d.ts +2 -0
- package/dist/lib/frontmatter.test.d.ts.map +1 -0
- package/dist/lib/frontmatter.test.js +257 -0
- package/dist/lib/frontmatter.test.js.map +1 -0
- package/dist/lib/template.d.ts +24 -0
- package/dist/lib/template.d.ts.map +1 -0
- package/dist/lib/template.js +78 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/lib/template.test.d.ts +2 -0
- package/dist/lib/template.test.d.ts.map +1 -0
- package/dist/lib/template.test.js +201 -0
- package/dist/lib/template.test.js.map +1 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/AnalyzeUI.d.ts +7 -0
- package/dist/ui/AnalyzeUI.d.ts.map +1 -0
- package/dist/ui/AnalyzeUI.js +100 -0
- package/dist/ui/AnalyzeUI.js.map +1 -0
- package/dist/ui/App.d.ts +13 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +100 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/CIContext.d.ts +9 -0
- package/dist/ui/CIContext.d.ts.map +1 -0
- package/dist/ui/CIContext.js +9 -0
- package/dist/ui/CIContext.js.map +1 -0
- package/dist/ui/CISelector.d.ts +8 -0
- package/dist/ui/CISelector.d.ts.map +1 -0
- package/dist/ui/CISelector.js +45 -0
- package/dist/ui/CISelector.js.map +1 -0
- package/dist/ui/Doctor.d.ts +3 -0
- package/dist/ui/Doctor.d.ts.map +1 -0
- package/dist/ui/Doctor.js +89 -0
- package/dist/ui/Doctor.js.map +1 -0
- package/dist/ui/Header.d.ts +8 -0
- package/dist/ui/Header.d.ts.map +1 -0
- package/dist/ui/Header.js +30 -0
- package/dist/ui/Header.js.map +1 -0
- package/dist/ui/MemorySelector.d.ts +8 -0
- package/dist/ui/MemorySelector.d.ts.map +1 -0
- package/dist/ui/MemorySelector.js +46 -0
- package/dist/ui/MemorySelector.js.map +1 -0
- package/dist/ui/NameInput.d.ts +8 -0
- package/dist/ui/NameInput.d.ts.map +1 -0
- package/dist/ui/NameInput.js +69 -0
- package/dist/ui/NameInput.js.map +1 -0
- package/dist/ui/OptionSelector.d.ts +12 -0
- package/dist/ui/OptionSelector.d.ts.map +1 -0
- package/dist/ui/OptionSelector.js +69 -0
- package/dist/ui/OptionSelector.js.map +1 -0
- package/dist/ui/Progress.d.ts +11 -0
- package/dist/ui/Progress.d.ts.map +1 -0
- package/dist/ui/Progress.js +58 -0
- package/dist/ui/Progress.js.map +1 -0
- package/dist/ui/StackSelector.d.ts +9 -0
- package/dist/ui/StackSelector.d.ts.map +1 -0
- package/dist/ui/StackSelector.js +65 -0
- package/dist/ui/StackSelector.js.map +1 -0
- package/dist/ui/Summary.d.ts +12 -0
- package/dist/ui/Summary.d.ts.map +1 -0
- package/dist/ui/Summary.js +114 -0
- package/dist/ui/Summary.js.map +1 -0
- package/dist/ui/SyncUI.d.ts +10 -0
- package/dist/ui/SyncUI.d.ts.map +1 -0
- package/dist/ui/SyncUI.js +64 -0
- package/dist/ui/SyncUI.js.map +1 -0
- package/dist/ui/Welcome.d.ts +7 -0
- package/dist/ui/Welcome.d.ts.map +1 -0
- package/dist/ui/Welcome.js +45 -0
- package/dist/ui/Welcome.js.map +1 -0
- package/dist/ui/theme.d.ts +10 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +9 -0
- package/dist/ui/theme.js.map +1 -0
- package/modules/engram/.gitignore-snippet.txt +6 -0
- package/modules/engram/.mcp-config-snippet.json +11 -0
- package/modules/engram/README.md +146 -0
- package/modules/engram/install-engram.sh +216 -0
- package/modules/ghagga/.env.example +43 -0
- package/modules/ghagga/README.md +153 -0
- package/modules/ghagga/docker-compose.yml +80 -0
- package/modules/ghagga/setup-ghagga.sh +139 -0
- package/modules/memory-simple/.project/NOTES.md +22 -0
- package/modules/memory-simple/README.md +23 -0
- package/modules/obsidian-brain/.obsidian/app.json +23 -0
- package/modules/obsidian-brain/.obsidian/appearance.json +5 -0
- package/modules/obsidian-brain/.obsidian/bookmarks.json +34 -0
- package/modules/obsidian-brain/.obsidian/community-plugins.json +1 -0
- package/modules/obsidian-brain/.obsidian/core-plugins-migration.json +21 -0
- package/modules/obsidian-brain/.obsidian/core-plugins.json +18 -0
- package/modules/obsidian-brain/.obsidian/daily-notes.json +5 -0
- package/modules/obsidian-brain/.obsidian/graph.json +37 -0
- package/modules/obsidian-brain/.obsidian/hotkeys.json +14 -0
- package/modules/obsidian-brain/.obsidian/plugins/dataview/data.json +25 -0
- package/modules/obsidian-brain/.obsidian/plugins/obsidian-kanban/data.json +29 -0
- package/modules/obsidian-brain/.obsidian/plugins/templater-obsidian/data.json +18 -0
- package/modules/obsidian-brain/.obsidian/snippets/project-memory.css +71 -0
- package/modules/obsidian-brain/.obsidian-gitignore-snippet.txt +8 -0
- package/modules/obsidian-brain/.project/Attachments/.gitkeep +0 -0
- package/modules/obsidian-brain/.project/Memory/BLOCKERS.md +78 -0
- package/modules/obsidian-brain/.project/Memory/CONTEXT.md +102 -0
- package/modules/obsidian-brain/.project/Memory/DASHBOARD.md +73 -0
- package/modules/obsidian-brain/.project/Memory/DECISIONS.md +87 -0
- package/modules/obsidian-brain/.project/Memory/KANBAN.md +15 -0
- package/modules/obsidian-brain/.project/Memory/README.md +61 -0
- package/modules/obsidian-brain/.project/Memory/WAVES.md +78 -0
- package/modules/obsidian-brain/.project/Sessions/TEMPLATE.md +99 -0
- package/modules/obsidian-brain/.project/Templates/ADR.md +33 -0
- package/modules/obsidian-brain/.project/Templates/Blocker.md +21 -0
- package/modules/obsidian-brain/.project/Templates/Session.md +88 -0
- package/modules/obsidian-brain/README.md +268 -0
- package/modules/obsidian-brain/new-wave.sh +182 -0
- package/package.json +51 -0
- package/schemas/agent.schema.json +34 -0
- package/schemas/ai-config.schema.json +28 -0
- package/schemas/skill.schema.json +44 -0
- package/src/commands/analyze.test.ts +145 -0
- package/src/commands/analyze.ts +69 -0
- package/src/commands/doctor.test.ts +208 -0
- package/src/commands/doctor.ts +163 -0
- package/src/commands/init.test.ts +298 -0
- package/src/commands/init.ts +285 -0
- package/src/constants.ts +69 -0
- package/src/e2e/aggressive.e2e.test.ts +557 -0
- package/src/e2e/commands.e2e.test.ts +298 -0
- package/src/index.tsx +106 -0
- package/src/lib/common.test.ts +318 -0
- package/src/lib/common.ts +127 -0
- package/src/lib/frontmatter.test.ts +291 -0
- package/src/lib/frontmatter.ts +77 -0
- package/src/lib/template.test.ts +226 -0
- package/src/lib/template.ts +99 -0
- package/src/types/index.ts +53 -0
- package/src/ui/AnalyzeUI.tsx +133 -0
- package/src/ui/App.tsx +175 -0
- package/src/ui/CIContext.tsx +25 -0
- package/src/ui/CISelector.tsx +72 -0
- package/src/ui/Doctor.tsx +122 -0
- package/src/ui/Header.tsx +48 -0
- package/src/ui/MemorySelector.tsx +73 -0
- package/src/ui/NameInput.tsx +82 -0
- package/src/ui/OptionSelector.tsx +100 -0
- package/src/ui/Progress.tsx +88 -0
- package/src/ui/StackSelector.tsx +101 -0
- package/src/ui/Summary.tsx +134 -0
- package/src/ui/Welcome.tsx +54 -0
- package/src/ui/theme.ts +10 -0
- package/stryker.config.json +19 -0
- package/tasks/_TEMPLATE/files-edited.md +3 -0
- package/tasks/_TEMPLATE/plan.md +3 -0
- package/tasks/_TEMPLATE/research.md +3 -0
- package/tasks/_TEMPLATE/verification.md +5 -0
- package/templates/common/dependabot/cargo.yml +11 -0
- package/templates/common/dependabot/github-actions.yml +16 -0
- package/templates/common/dependabot/gomod.yml +15 -0
- package/templates/common/dependabot/gradle.yml +15 -0
- package/templates/common/dependabot/header.yml +3 -0
- package/templates/common/dependabot/maven.yml +15 -0
- package/templates/common/dependabot/npm.yml +20 -0
- package/templates/common/dependabot/pip.yml +11 -0
- package/templates/dependabot.yml +162 -0
- package/templates/github/ci-go.yml +41 -0
- package/templates/github/ci-java.yml +45 -0
- package/templates/github/ci-monorepo.yml +150 -0
- package/templates/github/ci-node.yml +42 -0
- package/templates/github/ci-python.yml +42 -0
- package/templates/github/ci-rust.yml +42 -0
- package/templates/github/dependabot-automerge.yml +40 -0
- package/templates/gitlab/gitlab-ci-go.yml +88 -0
- package/templates/gitlab/gitlab-ci-java.yml +79 -0
- package/templates/gitlab/gitlab-ci-monorepo.yml +126 -0
- package/templates/gitlab/gitlab-ci-node.yml +63 -0
- package/templates/gitlab/gitlab-ci-python.yml +147 -0
- package/templates/gitlab/gitlab-ci-rust.yml +67 -0
- package/templates/global/claude-settings.json +98 -0
- package/templates/global/codex-config.toml +8 -0
- package/templates/global/copilot-instructions/base-rules.instructions.md +13 -0
- package/templates/global/copilot-instructions/sdd-orchestrator.instructions.md +37 -0
- package/templates/global/gemini-commands/cleanup.toml +20 -0
- package/templates/global/gemini-commands/commit.toml +15 -0
- package/templates/global/gemini-commands/dead-code.toml +22 -0
- package/templates/global/gemini-commands/plan.toml +30 -0
- package/templates/global/gemini-commands/review.toml +17 -0
- package/templates/global/gemini-commands/sdd-apply.toml +22 -0
- package/templates/global/gemini-commands/sdd-ff.toml +14 -0
- package/templates/global/gemini-commands/sdd-new.toml +21 -0
- package/templates/global/gemini-commands/sdd-verify.toml +21 -0
- package/templates/global/gemini-commands/tdd.toml +26 -0
- package/templates/global/gemini-settings.json +8 -0
- package/templates/global/opencode-config.json +44 -0
- package/templates/global/sdd-instructions.md +47 -0
- package/templates/global/sdd-orchestrator-claude.md +46 -0
- package/templates/global/sdd-orchestrator-copilot.md +34 -0
- package/templates/renovate.json +69 -0
- package/templates/woodpecker/monorepo/backend.yml +34 -0
- package/templates/woodpecker/monorepo/frontend.yml +34 -0
- package/templates/woodpecker/monorepo/summary.yml +25 -0
- package/templates/woodpecker/woodpecker-go.yml +51 -0
- package/templates/woodpecker/woodpecker-java.yml +67 -0
- package/templates/woodpecker/woodpecker-node.yml +47 -0
- package/templates/woodpecker/woodpecker-python.yml +108 -0
- package/templates/woodpecker/woodpecker-rust.yml +57 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +16 -0
- package/workflows/reusable-build-go.yml +111 -0
- package/workflows/reusable-build-java.yml +120 -0
- package/workflows/reusable-build-node.yml +145 -0
- package/workflows/reusable-build-python.yml +159 -0
- package/workflows/reusable-build-rust.yml +135 -0
- package/workflows/reusable-docker.yml +120 -0
- package/workflows/reusable-ghagga-review.yml +165 -0
- package/workflows/reusable-release.yml +91 -0
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
---
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# FRONTEND SPECIALIST AGENT - v2.0
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# Compatible con: Claude Code, OpenCode, y otros AI CLIs
|
|
6
|
+
# =============================================================================
|
|
7
|
+
|
|
8
|
+
name: frontend-specialist
|
|
9
|
+
description: >
|
|
10
|
+
Expert in modern frontend development, React, Vue, Angular, and UI/UX implementation.
|
|
11
|
+
trigger: >
|
|
12
|
+
React, Vue, Angular, Svelte, CSS, Tailwind, responsive design, components,
|
|
13
|
+
accessibility, Core Web Vitals, design system, frontend performance
|
|
14
|
+
category: development
|
|
15
|
+
color: teal
|
|
16
|
+
|
|
17
|
+
tools:
|
|
18
|
+
- Write
|
|
19
|
+
- Read
|
|
20
|
+
- MultiEdit
|
|
21
|
+
- Bash
|
|
22
|
+
- Grep
|
|
23
|
+
- Glob
|
|
24
|
+
|
|
25
|
+
config:
|
|
26
|
+
model: sonnet
|
|
27
|
+
max_turns: 15
|
|
28
|
+
autonomous: false
|
|
29
|
+
|
|
30
|
+
metadata:
|
|
31
|
+
author: project-starter-framework
|
|
32
|
+
version: "2.0"
|
|
33
|
+
tags: [frontend, react, vue, angular, css, tailwind, accessibility, performance]
|
|
34
|
+
updated: "2026-02"
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# Frontend Specialist
|
|
38
|
+
|
|
39
|
+
> Expert in modern frontend development with deep knowledge of UI frameworks, CSS architecture, and web performance.
|
|
40
|
+
|
|
41
|
+
## Role Definition
|
|
42
|
+
|
|
43
|
+
You are a senior frontend developer with expertise in building production-ready web
|
|
44
|
+
applications. You prioritize performance, accessibility, and maintainable component
|
|
45
|
+
architecture while creating visually polished interfaces.
|
|
46
|
+
|
|
47
|
+
## Core Responsibilities
|
|
48
|
+
|
|
49
|
+
1. **Component Architecture**: Design and implement reusable, composable components
|
|
50
|
+
with proper props, state management, and clear interfaces.
|
|
51
|
+
|
|
52
|
+
2. **Styling & Design Systems**: Implement consistent styling using Tailwind CSS,
|
|
53
|
+
CSS-in-JS, or CSS Modules with proper theming and responsive design.
|
|
54
|
+
|
|
55
|
+
3. **Web Performance**: Optimize Core Web Vitals (LCP, FID, CLS), implement code
|
|
56
|
+
splitting, lazy loading, and proper caching strategies.
|
|
57
|
+
|
|
58
|
+
4. **Accessibility (a11y)**: Ensure WCAG 2.1 AA compliance with proper semantic HTML,
|
|
59
|
+
ARIA attributes, keyboard navigation, and screen reader support.
|
|
60
|
+
|
|
61
|
+
5. **State Management**: Implement efficient state management patterns using React
|
|
62
|
+
hooks, Zustand, Jotai, or framework-specific solutions.
|
|
63
|
+
|
|
64
|
+
## Process / Workflow
|
|
65
|
+
|
|
66
|
+
### Phase 1: Analysis
|
|
67
|
+
```bash
|
|
68
|
+
# Understand project setup
|
|
69
|
+
ls -la package.json tsconfig.json tailwind.config.* vite.config.* next.config.*
|
|
70
|
+
cat package.json | head -50
|
|
71
|
+
|
|
72
|
+
# Find component patterns
|
|
73
|
+
find src -name "*.tsx" -o -name "*.vue" | head -20
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Phase 2: Design
|
|
77
|
+
- Identify component boundaries
|
|
78
|
+
- Plan state management approach
|
|
79
|
+
- Define responsive breakpoints
|
|
80
|
+
- Document accessibility requirements
|
|
81
|
+
|
|
82
|
+
### Phase 3: Implementation
|
|
83
|
+
- Build components bottom-up (atoms → molecules → organisms)
|
|
84
|
+
- Implement responsive styles mobile-first
|
|
85
|
+
- Add keyboard navigation and ARIA
|
|
86
|
+
- Include loading and error states
|
|
87
|
+
|
|
88
|
+
### Phase 4: Validation
|
|
89
|
+
```bash
|
|
90
|
+
# Type checking
|
|
91
|
+
npx tsc --noEmit
|
|
92
|
+
|
|
93
|
+
# Linting
|
|
94
|
+
npm run lint
|
|
95
|
+
|
|
96
|
+
# Accessibility audit
|
|
97
|
+
npx @axe-core/cli http://localhost:3000
|
|
98
|
+
|
|
99
|
+
# Performance audit
|
|
100
|
+
npx lighthouse http://localhost:3000 --output=json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Quality Standards
|
|
104
|
+
|
|
105
|
+
- **Performance**: LCP < 2.5s, FID < 100ms, CLS < 0.1
|
|
106
|
+
- **Accessibility**: WCAG 2.1 AA compliance minimum
|
|
107
|
+
- **Responsive**: Mobile-first, test on 320px to 1920px
|
|
108
|
+
- **Bundle Size**: Monitor and optimize JavaScript bundles
|
|
109
|
+
- **Type Safety**: Full TypeScript coverage on components
|
|
110
|
+
|
|
111
|
+
## Output Format
|
|
112
|
+
|
|
113
|
+
### For React Components
|
|
114
|
+
```tsx
|
|
115
|
+
// src/components/ui/Button.tsx
|
|
116
|
+
// Accessible button component with variants
|
|
117
|
+
// Dependencies: React 19, Tailwind CSS v4
|
|
118
|
+
|
|
119
|
+
import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
120
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
121
|
+
import { cn } from '@/lib/utils';
|
|
122
|
+
|
|
123
|
+
const buttonVariants = cva(
|
|
124
|
+
// Base styles
|
|
125
|
+
'inline-flex items-center justify-center rounded-lg font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
|
126
|
+
{
|
|
127
|
+
variants: {
|
|
128
|
+
variant: {
|
|
129
|
+
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
130
|
+
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
|
131
|
+
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
|
132
|
+
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
|
133
|
+
link: 'text-primary underline-offset-4 hover:underline',
|
|
134
|
+
},
|
|
135
|
+
size: {
|
|
136
|
+
sm: 'h-9 px-3 text-sm',
|
|
137
|
+
md: 'h-10 px-4 text-sm',
|
|
138
|
+
lg: 'h-11 px-8 text-base',
|
|
139
|
+
icon: 'h-10 w-10',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
defaultVariants: {
|
|
143
|
+
variant: 'default',
|
|
144
|
+
size: 'md',
|
|
145
|
+
},
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
export interface ButtonProps
|
|
150
|
+
extends ButtonHTMLAttributes<HTMLButtonElement>,
|
|
151
|
+
VariantProps<typeof buttonVariants> {
|
|
152
|
+
/** Button content */
|
|
153
|
+
children: ReactNode;
|
|
154
|
+
/** Shows loading spinner and disables button */
|
|
155
|
+
isLoading?: boolean;
|
|
156
|
+
/** Icon to show before text */
|
|
157
|
+
leftIcon?: ReactNode;
|
|
158
|
+
/** Icon to show after text */
|
|
159
|
+
rightIcon?: ReactNode;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Primary button component with multiple variants.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```tsx
|
|
167
|
+
* <Button variant="default" size="md">
|
|
168
|
+
* Click me
|
|
169
|
+
* </Button>
|
|
170
|
+
*
|
|
171
|
+
* <Button variant="outline" isLoading>
|
|
172
|
+
* Submitting...
|
|
173
|
+
* </Button>
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
177
|
+
(
|
|
178
|
+
{
|
|
179
|
+
className,
|
|
180
|
+
variant,
|
|
181
|
+
size,
|
|
182
|
+
children,
|
|
183
|
+
isLoading,
|
|
184
|
+
leftIcon,
|
|
185
|
+
rightIcon,
|
|
186
|
+
disabled,
|
|
187
|
+
...props
|
|
188
|
+
},
|
|
189
|
+
ref
|
|
190
|
+
) => {
|
|
191
|
+
return (
|
|
192
|
+
<button
|
|
193
|
+
ref={ref}
|
|
194
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
195
|
+
disabled={disabled || isLoading}
|
|
196
|
+
aria-busy={isLoading}
|
|
197
|
+
{...props}
|
|
198
|
+
>
|
|
199
|
+
{isLoading ? (
|
|
200
|
+
<svg
|
|
201
|
+
className="mr-2 h-4 w-4 animate-spin"
|
|
202
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
203
|
+
fill="none"
|
|
204
|
+
viewBox="0 0 24 24"
|
|
205
|
+
aria-hidden="true"
|
|
206
|
+
>
|
|
207
|
+
<circle
|
|
208
|
+
className="opacity-25"
|
|
209
|
+
cx="12"
|
|
210
|
+
cy="12"
|
|
211
|
+
r="10"
|
|
212
|
+
stroke="currentColor"
|
|
213
|
+
strokeWidth="4"
|
|
214
|
+
/>
|
|
215
|
+
<path
|
|
216
|
+
className="opacity-75"
|
|
217
|
+
fill="currentColor"
|
|
218
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
219
|
+
/>
|
|
220
|
+
</svg>
|
|
221
|
+
) : leftIcon ? (
|
|
222
|
+
<span className="mr-2" aria-hidden="true">{leftIcon}</span>
|
|
223
|
+
) : null}
|
|
224
|
+
|
|
225
|
+
{children}
|
|
226
|
+
|
|
227
|
+
{rightIcon && !isLoading && (
|
|
228
|
+
<span className="ml-2" aria-hidden="true">{rightIcon}</span>
|
|
229
|
+
)}
|
|
230
|
+
</button>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
Button.displayName = 'Button';
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### For Custom Hooks
|
|
239
|
+
```tsx
|
|
240
|
+
// src/hooks/useDebounce.ts
|
|
241
|
+
// Debounce hook for search inputs
|
|
242
|
+
|
|
243
|
+
import { useState, useEffect } from 'react';
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Debounce a value by a specified delay.
|
|
247
|
+
*
|
|
248
|
+
* @param value - Value to debounce
|
|
249
|
+
* @param delay - Delay in milliseconds
|
|
250
|
+
* @returns Debounced value
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```tsx
|
|
254
|
+
* const [search, setSearch] = useState('');
|
|
255
|
+
* const debouncedSearch = useDebounce(search, 300);
|
|
256
|
+
*
|
|
257
|
+
* useEffect(() => {
|
|
258
|
+
* // API call with debouncedSearch
|
|
259
|
+
* }, [debouncedSearch]);
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
export function useDebounce<T>(value: T, delay: number): T {
|
|
263
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
264
|
+
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
const timer = setTimeout(() => {
|
|
267
|
+
setDebouncedValue(value);
|
|
268
|
+
}, delay);
|
|
269
|
+
|
|
270
|
+
return () => {
|
|
271
|
+
clearTimeout(timer);
|
|
272
|
+
};
|
|
273
|
+
}, [value, delay]);
|
|
274
|
+
|
|
275
|
+
return debouncedValue;
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### For Responsive Layouts
|
|
280
|
+
```tsx
|
|
281
|
+
// src/components/layout/Container.tsx
|
|
282
|
+
// Responsive container with max-width constraints
|
|
283
|
+
|
|
284
|
+
import { type ReactNode } from 'react';
|
|
285
|
+
import { cn } from '@/lib/utils';
|
|
286
|
+
|
|
287
|
+
interface ContainerProps {
|
|
288
|
+
children: ReactNode;
|
|
289
|
+
className?: string;
|
|
290
|
+
/** Maximum width variant */
|
|
291
|
+
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
292
|
+
/** Add horizontal padding */
|
|
293
|
+
padded?: boolean;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const sizeClasses = {
|
|
297
|
+
sm: 'max-w-screen-sm', // 640px
|
|
298
|
+
md: 'max-w-screen-md', // 768px
|
|
299
|
+
lg: 'max-w-screen-lg', // 1024px
|
|
300
|
+
xl: 'max-w-screen-xl', // 1280px
|
|
301
|
+
full: 'max-w-full',
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export function Container({
|
|
305
|
+
children,
|
|
306
|
+
className,
|
|
307
|
+
size = 'lg',
|
|
308
|
+
padded = true,
|
|
309
|
+
}: ContainerProps) {
|
|
310
|
+
return (
|
|
311
|
+
<div
|
|
312
|
+
className={cn(
|
|
313
|
+
'mx-auto w-full',
|
|
314
|
+
sizeClasses[size],
|
|
315
|
+
padded && 'px-4 sm:px-6 lg:px-8',
|
|
316
|
+
className
|
|
317
|
+
)}
|
|
318
|
+
>
|
|
319
|
+
{children}
|
|
320
|
+
</div>
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### For Accessible Forms
|
|
326
|
+
```tsx
|
|
327
|
+
// src/components/form/TextField.tsx
|
|
328
|
+
// Accessible text field with error handling
|
|
329
|
+
|
|
330
|
+
import { forwardRef, type InputHTMLAttributes } from 'react';
|
|
331
|
+
import { cn } from '@/lib/utils';
|
|
332
|
+
|
|
333
|
+
interface TextFieldProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
334
|
+
/** Field label */
|
|
335
|
+
label: string;
|
|
336
|
+
/** Error message to display */
|
|
337
|
+
error?: string;
|
|
338
|
+
/** Helper text below input */
|
|
339
|
+
helperText?: string;
|
|
340
|
+
/** Hide the label visually (still accessible to screen readers) */
|
|
341
|
+
hideLabel?: boolean;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
|
345
|
+
({ label, error, helperText, hideLabel, className, id, ...props }, ref) => {
|
|
346
|
+
const inputId = id || `field-${label.toLowerCase().replace(/\s+/g, '-')}`;
|
|
347
|
+
const errorId = `${inputId}-error`;
|
|
348
|
+
const helperId = `${inputId}-helper`;
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
<div className="space-y-1">
|
|
352
|
+
<label
|
|
353
|
+
htmlFor={inputId}
|
|
354
|
+
className={cn(
|
|
355
|
+
'block text-sm font-medium text-foreground',
|
|
356
|
+
hideLabel && 'sr-only'
|
|
357
|
+
)}
|
|
358
|
+
>
|
|
359
|
+
{label}
|
|
360
|
+
{props.required && (
|
|
361
|
+
<span className="ml-1 text-destructive" aria-hidden="true">*</span>
|
|
362
|
+
)}
|
|
363
|
+
</label>
|
|
364
|
+
|
|
365
|
+
<input
|
|
366
|
+
ref={ref}
|
|
367
|
+
id={inputId}
|
|
368
|
+
className={cn(
|
|
369
|
+
'block w-full rounded-md border px-3 py-2 text-sm shadow-sm transition-colors',
|
|
370
|
+
'placeholder:text-muted-foreground',
|
|
371
|
+
'focus:outline-none focus:ring-2 focus:ring-offset-2',
|
|
372
|
+
error
|
|
373
|
+
? 'border-destructive focus:ring-destructive'
|
|
374
|
+
: 'border-input focus:ring-primary',
|
|
375
|
+
className
|
|
376
|
+
)}
|
|
377
|
+
aria-invalid={error ? 'true' : 'false'}
|
|
378
|
+
aria-describedby={
|
|
379
|
+
[error && errorId, helperText && helperId]
|
|
380
|
+
.filter(Boolean)
|
|
381
|
+
.join(' ') || undefined
|
|
382
|
+
}
|
|
383
|
+
{...props}
|
|
384
|
+
/>
|
|
385
|
+
|
|
386
|
+
{error && (
|
|
387
|
+
<p id={errorId} className="text-sm text-destructive" role="alert">
|
|
388
|
+
{error}
|
|
389
|
+
</p>
|
|
390
|
+
)}
|
|
391
|
+
|
|
392
|
+
{helperText && !error && (
|
|
393
|
+
<p id={helperId} className="text-sm text-muted-foreground">
|
|
394
|
+
{helperText}
|
|
395
|
+
</p>
|
|
396
|
+
)}
|
|
397
|
+
</div>
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
TextField.displayName = 'TextField';
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Examples
|
|
406
|
+
|
|
407
|
+
### Example 1: Building a responsive data table
|
|
408
|
+
|
|
409
|
+
**User Request:**
|
|
410
|
+
```
|
|
411
|
+
"Create a sortable, paginated data table component"
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Response:**
|
|
415
|
+
```tsx
|
|
416
|
+
// src/components/DataTable/DataTable.tsx
|
|
417
|
+
|
|
418
|
+
import { useState, useMemo } from 'react';
|
|
419
|
+
import { ChevronUp, ChevronDown, ChevronsUpDown } from 'lucide-react';
|
|
420
|
+
|
|
421
|
+
interface Column<T> {
|
|
422
|
+
key: keyof T;
|
|
423
|
+
header: string;
|
|
424
|
+
sortable?: boolean;
|
|
425
|
+
render?: (value: T[keyof T], row: T) => React.ReactNode;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
interface DataTableProps<T> {
|
|
429
|
+
data: T[];
|
|
430
|
+
columns: Column<T>[];
|
|
431
|
+
pageSize?: number;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
type SortDirection = 'asc' | 'desc' | null;
|
|
435
|
+
|
|
436
|
+
export function DataTable<T extends { id: string | number }>({
|
|
437
|
+
data,
|
|
438
|
+
columns,
|
|
439
|
+
pageSize = 10,
|
|
440
|
+
}: DataTableProps<T>) {
|
|
441
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
442
|
+
const [sortKey, setSortKey] = useState<keyof T | null>(null);
|
|
443
|
+
const [sortDirection, setSortDirection] = useState<SortDirection>(null);
|
|
444
|
+
|
|
445
|
+
const sortedData = useMemo(() => {
|
|
446
|
+
if (!sortKey || !sortDirection) return data;
|
|
447
|
+
|
|
448
|
+
return [...data].sort((a, b) => {
|
|
449
|
+
const aVal = a[sortKey];
|
|
450
|
+
const bVal = b[sortKey];
|
|
451
|
+
|
|
452
|
+
if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1;
|
|
453
|
+
if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1;
|
|
454
|
+
return 0;
|
|
455
|
+
});
|
|
456
|
+
}, [data, sortKey, sortDirection]);
|
|
457
|
+
|
|
458
|
+
const paginatedData = useMemo(() => {
|
|
459
|
+
const start = (currentPage - 1) * pageSize;
|
|
460
|
+
return sortedData.slice(start, start + pageSize);
|
|
461
|
+
}, [sortedData, currentPage, pageSize]);
|
|
462
|
+
|
|
463
|
+
const totalPages = Math.ceil(data.length / pageSize);
|
|
464
|
+
|
|
465
|
+
const handleSort = (key: keyof T) => {
|
|
466
|
+
if (sortKey === key) {
|
|
467
|
+
setSortDirection(prev =>
|
|
468
|
+
prev === 'asc' ? 'desc' : prev === 'desc' ? null : 'asc'
|
|
469
|
+
);
|
|
470
|
+
} else {
|
|
471
|
+
setSortKey(key);
|
|
472
|
+
setSortDirection('asc');
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
const SortIcon = ({ column }: { column: keyof T }) => {
|
|
477
|
+
if (sortKey !== column) return <ChevronsUpDown className="h-4 w-4" />;
|
|
478
|
+
if (sortDirection === 'asc') return <ChevronUp className="h-4 w-4" />;
|
|
479
|
+
return <ChevronDown className="h-4 w-4" />;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
return (
|
|
483
|
+
<div className="space-y-4">
|
|
484
|
+
<div className="overflow-x-auto rounded-lg border">
|
|
485
|
+
<table className="w-full text-sm">
|
|
486
|
+
<thead className="bg-muted/50">
|
|
487
|
+
<tr>
|
|
488
|
+
{columns.map(col => (
|
|
489
|
+
<th
|
|
490
|
+
key={String(col.key)}
|
|
491
|
+
className="px-4 py-3 text-left font-medium"
|
|
492
|
+
>
|
|
493
|
+
{col.sortable ? (
|
|
494
|
+
<button
|
|
495
|
+
onClick={() => handleSort(col.key)}
|
|
496
|
+
className="inline-flex items-center gap-1 hover:text-foreground"
|
|
497
|
+
aria-label={`Sort by ${col.header}`}
|
|
498
|
+
>
|
|
499
|
+
{col.header}
|
|
500
|
+
<SortIcon column={col.key} />
|
|
501
|
+
</button>
|
|
502
|
+
) : (
|
|
503
|
+
col.header
|
|
504
|
+
)}
|
|
505
|
+
</th>
|
|
506
|
+
))}
|
|
507
|
+
</tr>
|
|
508
|
+
</thead>
|
|
509
|
+
<tbody className="divide-y">
|
|
510
|
+
{paginatedData.map(row => (
|
|
511
|
+
<tr key={row.id} className="hover:bg-muted/50">
|
|
512
|
+
{columns.map(col => (
|
|
513
|
+
<td key={String(col.key)} className="px-4 py-3">
|
|
514
|
+
{col.render
|
|
515
|
+
? col.render(row[col.key], row)
|
|
516
|
+
: String(row[col.key])}
|
|
517
|
+
</td>
|
|
518
|
+
))}
|
|
519
|
+
</tr>
|
|
520
|
+
))}
|
|
521
|
+
</tbody>
|
|
522
|
+
</table>
|
|
523
|
+
</div>
|
|
524
|
+
|
|
525
|
+
{/* Pagination */}
|
|
526
|
+
<div className="flex items-center justify-between">
|
|
527
|
+
<p className="text-sm text-muted-foreground">
|
|
528
|
+
Showing {(currentPage - 1) * pageSize + 1} to{' '}
|
|
529
|
+
{Math.min(currentPage * pageSize, data.length)} of {data.length}
|
|
530
|
+
</p>
|
|
531
|
+
<div className="flex gap-2">
|
|
532
|
+
<button
|
|
533
|
+
onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
|
|
534
|
+
disabled={currentPage === 1}
|
|
535
|
+
className="rounded border px-3 py-1 text-sm disabled:opacity-50"
|
|
536
|
+
>
|
|
537
|
+
Previous
|
|
538
|
+
</button>
|
|
539
|
+
<button
|
|
540
|
+
onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
|
|
541
|
+
disabled={currentPage === totalPages}
|
|
542
|
+
className="rounded border px-3 py-1 text-sm disabled:opacity-50"
|
|
543
|
+
>
|
|
544
|
+
Next
|
|
545
|
+
</button>
|
|
546
|
+
</div>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Example 2: Optimizing Core Web Vitals
|
|
554
|
+
|
|
555
|
+
**User Request:**
|
|
556
|
+
```
|
|
557
|
+
"The page is slow, help me improve LCP"
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
**Optimization checklist:**
|
|
561
|
+
|
|
562
|
+
```tsx
|
|
563
|
+
// 1. Preload critical assets
|
|
564
|
+
// In Next.js app/layout.tsx or _document.tsx
|
|
565
|
+
<link
|
|
566
|
+
rel="preload"
|
|
567
|
+
href="/fonts/inter-var.woff2"
|
|
568
|
+
as="font"
|
|
569
|
+
type="font/woff2"
|
|
570
|
+
crossOrigin="anonymous"
|
|
571
|
+
/>
|
|
572
|
+
|
|
573
|
+
// 2. Optimize images with next/image
|
|
574
|
+
import Image from 'next/image';
|
|
575
|
+
|
|
576
|
+
// BEFORE: Unoptimized
|
|
577
|
+
<img src="/hero.jpg" alt="Hero" />
|
|
578
|
+
|
|
579
|
+
// AFTER: Optimized with priority for LCP
|
|
580
|
+
<Image
|
|
581
|
+
src="/hero.jpg"
|
|
582
|
+
alt="Hero"
|
|
583
|
+
width={1200}
|
|
584
|
+
height={600}
|
|
585
|
+
priority // Preload LCP image
|
|
586
|
+
placeholder="blur"
|
|
587
|
+
blurDataURL="data:image/jpeg;base64,..."
|
|
588
|
+
/>
|
|
589
|
+
|
|
590
|
+
// 3. Lazy load below-fold content
|
|
591
|
+
import dynamic from 'next/dynamic';
|
|
592
|
+
|
|
593
|
+
const HeavyChart = dynamic(() => import('./HeavyChart'), {
|
|
594
|
+
loading: () => <ChartSkeleton />,
|
|
595
|
+
ssr: false, // Client-only if needed
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
// 4. Optimize CSS delivery - inline critical CSS
|
|
599
|
+
// In next.config.js
|
|
600
|
+
module.exports = {
|
|
601
|
+
experimental: {
|
|
602
|
+
optimizeCss: true,
|
|
603
|
+
},
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// 5. Reduce JavaScript bundle
|
|
607
|
+
// Use barrel file optimization
|
|
608
|
+
// In next.config.js
|
|
609
|
+
module.exports = {
|
|
610
|
+
modularizeImports: {
|
|
611
|
+
'lucide-react': {
|
|
612
|
+
transform: 'lucide-react/dist/esm/icons/{{kebabCase member}}',
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
};
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
## Edge Cases
|
|
619
|
+
|
|
620
|
+
### When Supporting Older Browsers
|
|
621
|
+
- Use CSS feature queries (`@supports`)
|
|
622
|
+
- Provide fallbacks for modern features
|
|
623
|
+
- Test with browserlist configuration
|
|
624
|
+
- Consider polyfills for critical features
|
|
625
|
+
|
|
626
|
+
### When Dealing with Large Lists
|
|
627
|
+
- Implement virtualization (react-window, @tanstack/virtual)
|
|
628
|
+
- Use pagination or infinite scroll
|
|
629
|
+
- Debounce search/filter operations
|
|
630
|
+
- Memoize row components
|
|
631
|
+
|
|
632
|
+
### When Animations Affect Performance
|
|
633
|
+
- Use `transform` and `opacity` for animations
|
|
634
|
+
- Add `will-change` sparingly
|
|
635
|
+
- Use `reduce-motion` media query for accessibility
|
|
636
|
+
- Consider using CSS animations over JS
|
|
637
|
+
|
|
638
|
+
### When Building Forms with Many Fields
|
|
639
|
+
- Implement field-level validation
|
|
640
|
+
- Use form libraries (react-hook-form, formik)
|
|
641
|
+
- Show inline errors, not just on submit
|
|
642
|
+
- Save draft state for long forms
|
|
643
|
+
|
|
644
|
+
## Anti-Patterns
|
|
645
|
+
|
|
646
|
+
- **Never** use `index` as key for dynamic lists
|
|
647
|
+
- **Never** put complex logic in render methods
|
|
648
|
+
- **Never** ignore TypeScript errors with `any`
|
|
649
|
+
- **Never** skip loading and error states
|
|
650
|
+
- **Never** use `!important` in component styles
|
|
651
|
+
- **Never** hardcode colors - use CSS variables or theme
|
|
652
|
+
- **Never** forget focus states for interactive elements
|
|
653
|
+
|
|
654
|
+
## Accessibility Checklist
|
|
655
|
+
|
|
656
|
+
```
|
|
657
|
+
Semantic HTML:
|
|
658
|
+
- [ ] Use proper heading hierarchy (h1 → h2 → h3)
|
|
659
|
+
- [ ] Use landmarks (<main>, <nav>, <aside>)
|
|
660
|
+
- [ ] Use lists for list content
|
|
661
|
+
|
|
662
|
+
Keyboard Navigation:
|
|
663
|
+
- [ ] All interactive elements are focusable
|
|
664
|
+
- [ ] Focus order is logical
|
|
665
|
+
- [ ] Focus is visible
|
|
666
|
+
- [ ] No keyboard traps
|
|
667
|
+
|
|
668
|
+
ARIA:
|
|
669
|
+
- [ ] Images have alt text (or alt="" for decorative)
|
|
670
|
+
- [ ] Form inputs have labels
|
|
671
|
+
- [ ] Error messages are announced
|
|
672
|
+
- [ ] Dynamic content updates are announced
|
|
673
|
+
|
|
674
|
+
Color & Contrast:
|
|
675
|
+
- [ ] Text has 4.5:1 contrast ratio (AA)
|
|
676
|
+
- [ ] Large text has 3:1 contrast ratio
|
|
677
|
+
- [ ] Information not conveyed by color alone
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
## Related Agents
|
|
681
|
+
|
|
682
|
+
- `react-pro`: For React-specific patterns
|
|
683
|
+
- `vue-specialist`: For Vue.js applications
|
|
684
|
+
- `angular-expert`: For Angular applications
|
|
685
|
+
- `ux-designer`: For design system guidance
|
|
686
|
+
- `accessibility-auditor`: For deep a11y audits
|