expxagents 0.25.1 → 0.25.2
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/assets/agents/_catalog.yaml +35 -0
- package/assets/agents/accounting/accountant.agent.md +41 -0
- package/assets/agents/accounting/audit-analyst.agent.md +41 -0
- package/assets/agents/accounting/financial-reporting.agent.md +41 -0
- package/assets/agents/accounting/fiscal-analyst.agent.md +41 -0
- package/assets/agents/accounting/payroll-specialist.agent.md +41 -0
- package/assets/agents/accounting/tax-compliance.agent.md +41 -0
- package/assets/agents/administrative/document-controller.agent.md +41 -0
- package/assets/agents/administrative/office-manager.agent.md +41 -0
- package/assets/agents/administrative/process-documentation-officer.agent.md +41 -0
- package/assets/agents/administrative/procurement-specialist.agent.md +41 -0
- package/assets/agents/board/board-report-writer.agent.md +41 -0
- package/assets/agents/board/business-intelligence.agent.md +41 -0
- package/assets/agents/board/governance-officer.agent.md +41 -0
- package/assets/agents/board/okr-manager.agent.md +41 -0
- package/assets/agents/board/risk-analyst.agent.md +41 -0
- package/assets/agents/board/strategic-advisor.agent.md +41 -0
- package/assets/agents/commercial/account-executive.agent.md +41 -0
- package/assets/agents/commercial/crm-manager.agent.md +41 -0
- package/assets/agents/commercial/pricing-strategist.agent.md +41 -0
- package/assets/agents/commercial/proposal-writer.agent.md +41 -0
- package/assets/agents/commercial/sdr.agent.md +41 -0
- package/assets/agents/compliance/compliance-officer.agent.md +41 -0
- package/assets/agents/compliance/data-privacy-specialist.agent.md +41 -0
- package/assets/agents/compliance/internal-auditor.agent.md +41 -0
- package/assets/agents/compliance/regulatory-monitor.agent.md +41 -0
- package/assets/agents/customer-success/churn-prevention.agent.md +41 -0
- package/assets/agents/customer-success/csm.agent.md +41 -0
- package/assets/agents/customer-success/expansion-manager.agent.md +41 -0
- package/assets/agents/customer-success/nps-analyst.agent.md +41 -0
- package/assets/agents/customer-success/renewal-manager.agent.md +41 -0
- package/assets/agents/development/android-developer.agent.md +41 -0
- package/assets/agents/development/backend-developer.agent.md +42 -0
- package/assets/agents/development/business-analyst.agent.md +41 -0
- package/assets/agents/development/code-reviewer.agent.md +41 -0
- package/assets/agents/development/cross-platform-mobile.agent.md +41 -0
- package/assets/agents/development/dba.agent.md +41 -0
- package/assets/agents/development/desktop-developer.agent.md +41 -0
- package/assets/agents/development/devops-engineer.agent.md +41 -0
- package/assets/agents/development/frontend-developer.agent.md +103 -0
- package/assets/agents/development/ios-developer.agent.md +41 -0
- package/assets/agents/development/product-manager.agent.md +41 -0
- package/assets/agents/development/qa-engineer.agent.md +41 -0
- package/assets/agents/development/scrum-master.agent.md +41 -0
- package/assets/agents/development/security-analyst.agent.md +41 -0
- package/assets/agents/development/tech-lead.agent.md +42 -0
- package/assets/agents/development/tech-writer.agent.md +41 -0
- package/assets/agents/development/ux-design-expert.agent.md +108 -0
- package/assets/agents/development/ux-designer.agent.md +41 -0
- package/assets/agents/finance/accounts-manager.agent.md +41 -0
- package/assets/agents/finance/billing-analyst.agent.md +41 -0
- package/assets/agents/finance/budget-planner.agent.md +41 -0
- package/assets/agents/finance/financial-controller.agent.md +41 -0
- package/assets/agents/hr/benefits-manager.agent.md +41 -0
- package/assets/agents/hr/hr-onboarding.agent.md +41 -0
- package/assets/agents/hr/interview-coordinator.agent.md +41 -0
- package/assets/agents/hr/people-culture.agent.md +41 -0
- package/assets/agents/hr/performance-analyst.agent.md +41 -0
- package/assets/agents/hr/recruiter.agent.md +41 -0
- package/assets/agents/implantation/deployment-manager.agent.md +41 -0
- package/assets/agents/implantation/environment-specialist.agent.md +41 -0
- package/assets/agents/implantation/go-live-coordinator.agent.md +41 -0
- package/assets/agents/implantation/integration-specialist.agent.md +41 -0
- package/assets/agents/implantation/migration-specialist.agent.md +41 -0
- package/assets/agents/legal/contract-manager.agent.md +41 -0
- package/assets/agents/legal/ip-specialist.agent.md +41 -0
- package/assets/agents/legal/labor-attorney.agent.md +41 -0
- package/assets/agents/legal/legal-counsel.agent.md +41 -0
- package/assets/agents/marketing/brand-guardian.agent.md +40 -0
- package/assets/agents/marketing/content-creator.agent.md +41 -0
- package/assets/agents/marketing/email-marketing.agent.md +41 -0
- package/assets/agents/marketing/landing-page-builder.agent.md +138 -0
- package/assets/agents/marketing/marketing-analyst.agent.md +41 -0
- package/assets/agents/marketing/paid-ads-manager.agent.md +41 -0
- package/assets/agents/marketing/seo-specialist.agent.md +41 -0
- package/assets/agents/marketing/social-media-manager.agent.md +41 -0
- package/assets/agents/rnd/benchmark-analyst.agent.md +41 -0
- package/assets/agents/rnd/innovation-scout.agent.md +41 -0
- package/assets/agents/rnd/market-researcher.agent.md +41 -0
- package/assets/agents/rnd/product-analyst.agent.md +41 -0
- package/assets/agents/rnd/prototype-builder.agent.md +41 -0
- package/assets/agents/support/knowledge-base-manager.agent.md +41 -0
- package/assets/agents/support/l1-support.agent.md +41 -0
- package/assets/agents/support/l2-support.agent.md +41 -0
- package/assets/agents/support/l3-support.agent.md +41 -0
- package/assets/agents/support/sla-monitor.agent.md +41 -0
- package/assets/agents/training/assessment-creator.agent.md +41 -0
- package/assets/agents/training/onboarding-coach.agent.md +41 -0
- package/assets/agents/training/training-designer.agent.md +41 -0
- package/assets/agents/training/workshop-facilitator.agent.md +41 -0
- package/assets/core/best-practices/_catalog.yaml +91 -0
- package/assets/core/best-practices/api-documentation.md +137 -0
- package/assets/core/best-practices/blog-post.md +86 -0
- package/assets/core/best-practices/blog-seo.md +91 -0
- package/assets/core/best-practices/code-review.md +97 -0
- package/assets/core/best-practices/copywriting.md +75 -0
- package/assets/core/best-practices/data-analysis.md +93 -0
- package/assets/core/best-practices/deploy-checklist.md +99 -0
- package/assets/core/best-practices/email-newsletter.md +84 -0
- package/assets/core/best-practices/email-sales.md +91 -0
- package/assets/core/best-practices/fullstack-page-generation.md +936 -0
- package/assets/core/best-practices/image-design.md +78 -0
- package/assets/core/best-practices/instagram-feed.md +70 -0
- package/assets/core/best-practices/instagram-reels.md +75 -0
- package/assets/core/best-practices/instagram-stories.md +68 -0
- package/assets/core/best-practices/landing-page-react.md +2263 -0
- package/assets/core/best-practices/landing-page.md +279 -0
- package/assets/core/best-practices/linkedin-article.md +83 -0
- package/assets/core/best-practices/linkedin-post.md +84 -0
- package/assets/core/best-practices/researching.md +89 -0
- package/assets/core/best-practices/review.md +95 -0
- package/assets/core/best-practices/sprint-planning.md +91 -0
- package/assets/core/best-practices/strategist.md +95 -0
- package/assets/core/best-practices/technical-writing.md +104 -0
- package/assets/core/best-practices/twitter-post.md +75 -0
- package/assets/core/best-practices/twitter-thread.md +92 -0
- package/assets/core/best-practices/whatsapp-broadcast.md +95 -0
- package/assets/core/best-practices/youtube-script.md +80 -0
- package/assets/core/best-practices/youtube-shorts.md +76 -0
- package/assets/core/prompts/insight-hunter.prompt.md +62 -0
- package/assets/core/runner.pipeline.md +200 -0
- package/assets/core/skills.engine.md +65 -0
- package/assets/core/solution-architect.agent.md +329 -0
- package/assets/mcps/_catalog.yaml +17 -0
- package/assets/mcps/figma.mcp.yaml +35 -0
- package/assets/mcps/github.mcp.yaml +44 -0
- package/assets/mcps/linear.mcp.yaml +37 -0
- package/assets/mcps/notion.mcp.yaml +37 -0
- package/assets/mcps/pencil.mcp.yaml +32 -0
- package/assets/mcps/postgresql.mcp.yaml +39 -0
- package/assets/mcps/sentry.mcp.yaml +41 -0
- package/assets/mcps/slack.mcp.yaml +37 -0
- package/assets/mcps/vercel.mcp.yaml +39 -0
- package/assets/templates/_expxagents/_memory/company.md +25 -0
- package/assets/templates/_expxagents/_memory/preferences.md +6 -0
- package/assets/templates/squads/_memory/memories.md +16 -0
- package/dist/dashboard/assets/BufferResource-D79vaoFm.js +185 -0
- package/dist/dashboard/assets/CanvasRenderer-BUoxTNKV.js +1 -0
- package/dist/dashboard/assets/JarvisView-DSN7xWMz.js +1 -0
- package/dist/dashboard/assets/RenderTargetSystem-B7rwTXA1.js +172 -0
- package/dist/dashboard/assets/ThreeBackground-BQTdScX-.js +1 -0
- package/dist/dashboard/assets/WebGLRenderer-DgdVNsZ9.js +156 -0
- package/dist/dashboard/assets/WebGPURenderer-DnQNvjEQ.js +41 -0
- package/dist/dashboard/assets/browserAll-Cbsk7DE4.js +14 -0
- package/dist/dashboard/assets/index-CrlhoBta.js +783 -0
- package/dist/dashboard/assets/index-DtbIzZ5n.css +1 -0
- package/dist/dashboard/assets/three-BZk_I9Ly.js +4057 -0
- package/dist/dashboard/assets/webworkerAll-BLmfReEj.js +83 -0
- package/dist/dashboard/index.html +13 -0
- package/dist/server/api/__tests__/cost-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/cost-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/cost-routes.test.js +54 -0
- package/dist/server/api/__tests__/cost-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/files-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/files-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/files-routes.test.js +85 -0
- package/dist/server/api/__tests__/files-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/graph-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/graph-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/graph-routes.test.js +105 -0
- package/dist/server/api/__tests__/graph-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/health-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/health-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/health-routes.test.js +22 -0
- package/dist/server/api/__tests__/health-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/integration-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/integration-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/integration-routes.test.js +243 -0
- package/dist/server/api/__tests__/integration-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/kanban-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/kanban-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/kanban-routes.test.js +316 -0
- package/dist/server/api/__tests__/kanban-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/log-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/log-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/log-routes.test.js +35 -0
- package/dist/server/api/__tests__/log-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/orgchart-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/orgchart-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/orgchart-routes.test.js +161 -0
- package/dist/server/api/__tests__/orgchart-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/settings-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/settings-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/settings-routes.test.js +177 -0
- package/dist/server/api/__tests__/settings-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/system-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/system-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/system-routes.test.js +79 -0
- package/dist/server/api/__tests__/system-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/team-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/team-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/team-routes.test.js +116 -0
- package/dist/server/api/__tests__/team-routes.test.js.map +1 -0
- package/dist/server/api/__tests__/webhook-routes.test.d.ts +2 -0
- package/dist/server/api/__tests__/webhook-routes.test.d.ts.map +1 -0
- package/dist/server/api/__tests__/webhook-routes.test.js +111 -0
- package/dist/server/api/__tests__/webhook-routes.test.js.map +1 -0
- package/dist/server/api/activity-routes.d.ts +8 -0
- package/dist/server/api/activity-routes.d.ts.map +1 -0
- package/dist/server/api/activity-routes.js +34 -0
- package/dist/server/api/activity-routes.js.map +1 -0
- package/dist/server/api/chat-api-routes.d.ts +4 -0
- package/dist/server/api/chat-api-routes.d.ts.map +1 -0
- package/dist/server/api/chat-api-routes.js +28 -0
- package/dist/server/api/chat-api-routes.js.map +1 -0
- package/dist/server/api/cost-routes.d.ts +8 -0
- package/dist/server/api/cost-routes.d.ts.map +1 -0
- package/dist/server/api/cost-routes.js +39 -0
- package/dist/server/api/cost-routes.js.map +1 -0
- package/dist/server/api/dashboard-routes.d.ts +10 -0
- package/dist/server/api/dashboard-routes.d.ts.map +1 -0
- package/dist/server/api/dashboard-routes.js +128 -0
- package/dist/server/api/dashboard-routes.js.map +1 -0
- package/dist/server/api/files-routes.d.ts +5 -0
- package/dist/server/api/files-routes.d.ts.map +1 -0
- package/dist/server/api/files-routes.js +218 -0
- package/dist/server/api/files-routes.js.map +1 -0
- package/dist/server/api/graph-routes.d.ts +24 -0
- package/dist/server/api/graph-routes.d.ts.map +1 -0
- package/dist/server/api/graph-routes.js +208 -0
- package/dist/server/api/graph-routes.js.map +1 -0
- package/dist/server/api/health-routes.d.ts +9 -0
- package/dist/server/api/health-routes.d.ts.map +1 -0
- package/dist/server/api/health-routes.js +46 -0
- package/dist/server/api/health-routes.js.map +1 -0
- package/dist/server/api/integration-routes.d.ts +23 -0
- package/dist/server/api/integration-routes.d.ts.map +1 -0
- package/dist/server/api/integration-routes.js +326 -0
- package/dist/server/api/integration-routes.js.map +1 -0
- package/dist/server/api/kanban-routes.d.ts +8 -0
- package/dist/server/api/kanban-routes.d.ts.map +1 -0
- package/dist/server/api/kanban-routes.js +128 -0
- package/dist/server/api/kanban-routes.js.map +1 -0
- package/dist/server/api/knowledge-routes.d.ts +8 -0
- package/dist/server/api/knowledge-routes.d.ts.map +1 -0
- package/dist/server/api/knowledge-routes.js +82 -0
- package/dist/server/api/knowledge-routes.js.map +1 -0
- package/dist/server/api/log-routes.d.ts +8 -0
- package/dist/server/api/log-routes.d.ts.map +1 -0
- package/dist/server/api/log-routes.js +31 -0
- package/dist/server/api/log-routes.js.map +1 -0
- package/dist/server/api/orgchart-routes.d.ts +7 -0
- package/dist/server/api/orgchart-routes.d.ts.map +1 -0
- package/dist/server/api/orgchart-routes.js +154 -0
- package/dist/server/api/orgchart-routes.js.map +1 -0
- package/dist/server/api/permissions-routes.d.ts +8 -0
- package/dist/server/api/permissions-routes.d.ts.map +1 -0
- package/dist/server/api/permissions-routes.js +37 -0
- package/dist/server/api/permissions-routes.js.map +1 -0
- package/dist/server/api/registry-routes.d.ts +7 -0
- package/dist/server/api/registry-routes.d.ts.map +1 -0
- package/dist/server/api/registry-routes.js +51 -0
- package/dist/server/api/registry-routes.js.map +1 -0
- package/dist/server/api/settings-routes.d.ts +11 -0
- package/dist/server/api/settings-routes.d.ts.map +1 -0
- package/dist/server/api/settings-routes.js +167 -0
- package/dist/server/api/settings-routes.js.map +1 -0
- package/dist/server/api/squads-routes.d.ts +9 -0
- package/dist/server/api/squads-routes.d.ts.map +1 -0
- package/dist/server/api/squads-routes.js +171 -0
- package/dist/server/api/squads-routes.js.map +1 -0
- package/dist/server/api/system-routes.d.ts +9 -0
- package/dist/server/api/system-routes.d.ts.map +1 -0
- package/dist/server/api/system-routes.js +241 -0
- package/dist/server/api/system-routes.js.map +1 -0
- package/dist/server/api/team-routes.d.ts +8 -0
- package/dist/server/api/team-routes.d.ts.map +1 -0
- package/dist/server/api/team-routes.js +55 -0
- package/dist/server/api/team-routes.js.map +1 -0
- package/dist/server/api/users-routes.d.ts +8 -0
- package/dist/server/api/users-routes.d.ts.map +1 -0
- package/dist/server/api/users-routes.js +65 -0
- package/dist/server/api/users-routes.js.map +1 -0
- package/dist/server/api/webhook-routes.d.ts +9 -0
- package/dist/server/api/webhook-routes.d.ts.map +1 -0
- package/dist/server/api/webhook-routes.js +82 -0
- package/dist/server/api/webhook-routes.js.map +1 -0
- package/dist/server/app.d.ts +9 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/app.js +265 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/auth/auth-middleware.d.ts +13 -0
- package/dist/server/auth/auth-middleware.d.ts.map +1 -0
- package/dist/server/auth/auth-middleware.js +25 -0
- package/dist/server/auth/auth-middleware.js.map +1 -0
- package/dist/server/auth/auth-routes.d.ts +9 -0
- package/dist/server/auth/auth-routes.d.ts.map +1 -0
- package/dist/server/auth/auth-routes.js +152 -0
- package/dist/server/auth/auth-routes.js.map +1 -0
- package/dist/server/auth/jwt.d.ts +14 -0
- package/dist/server/auth/jwt.d.ts.map +1 -0
- package/dist/server/auth/jwt.js +16 -0
- package/dist/server/auth/jwt.js.map +1 -0
- package/dist/server/auth/password.d.ts +3 -0
- package/dist/server/auth/password.d.ts.map +1 -0
- package/dist/server/auth/password.js +9 -0
- package/dist/server/auth/password.js.map +1 -0
- package/dist/server/bridge/__tests__/chat-handler.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/chat-handler.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/chat-handler.test.js +143 -0
- package/dist/server/bridge/__tests__/chat-handler.test.js.map +1 -0
- package/dist/server/bridge/__tests__/chat-integration.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/chat-integration.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/chat-integration.test.js +129 -0
- package/dist/server/bridge/__tests__/chat-integration.test.js.map +1 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.js +300 -0
- package/dist/server/bridge/__tests__/claude-bridge.test.js.map +1 -0
- package/dist/server/bridge/__tests__/conversation.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/conversation.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/conversation.test.js +168 -0
- package/dist/server/bridge/__tests__/conversation.test.js.map +1 -0
- package/dist/server/bridge/__tests__/registry.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/registry.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/registry.test.js +45 -0
- package/dist/server/bridge/__tests__/registry.test.js.map +1 -0
- package/dist/server/bridge/__tests__/stream-parser.test.d.ts +2 -0
- package/dist/server/bridge/__tests__/stream-parser.test.d.ts.map +1 -0
- package/dist/server/bridge/__tests__/stream-parser.test.js +66 -0
- package/dist/server/bridge/__tests__/stream-parser.test.js.map +1 -0
- package/dist/server/bridge/chat-handler.d.ts +32 -0
- package/dist/server/bridge/chat-handler.d.ts.map +1 -0
- package/dist/server/bridge/chat-handler.js +356 -0
- package/dist/server/bridge/chat-handler.js.map +1 -0
- package/dist/server/bridge/claude-bridge.d.ts +21 -0
- package/dist/server/bridge/claude-bridge.d.ts.map +1 -0
- package/dist/server/bridge/claude-bridge.js +273 -0
- package/dist/server/bridge/claude-bridge.js.map +1 -0
- package/dist/server/bridge/conversation.d.ts +45 -0
- package/dist/server/bridge/conversation.d.ts.map +1 -0
- package/dist/server/bridge/conversation.js +78 -0
- package/dist/server/bridge/conversation.js.map +1 -0
- package/dist/server/bridge/engine-manager.d.ts +13 -0
- package/dist/server/bridge/engine-manager.d.ts.map +1 -0
- package/dist/server/bridge/engine-manager.js +54 -0
- package/dist/server/bridge/engine-manager.js.map +1 -0
- package/dist/server/bridge/engine.d.ts +37 -0
- package/dist/server/bridge/engine.d.ts.map +1 -0
- package/dist/server/bridge/engine.js +2 -0
- package/dist/server/bridge/engine.js.map +1 -0
- package/dist/server/bridge/factory.d.ts +4 -0
- package/dist/server/bridge/factory.d.ts.map +1 -0
- package/dist/server/bridge/factory.js +18 -0
- package/dist/server/bridge/factory.js.map +1 -0
- package/dist/server/bridge/opencode-bridge.d.ts +27 -0
- package/dist/server/bridge/opencode-bridge.d.ts.map +1 -0
- package/dist/server/bridge/opencode-bridge.js +163 -0
- package/dist/server/bridge/opencode-bridge.js.map +1 -0
- package/dist/server/bridge/registry.d.ts +19 -0
- package/dist/server/bridge/registry.d.ts.map +1 -0
- package/dist/server/bridge/registry.js +29 -0
- package/dist/server/bridge/registry.js.map +1 -0
- package/dist/server/bridge/session-journal.d.ts +25 -0
- package/dist/server/bridge/session-journal.d.ts.map +1 -0
- package/dist/server/bridge/session-journal.js +69 -0
- package/dist/server/bridge/session-journal.js.map +1 -0
- package/dist/server/bridge/stream-parser.d.ts +14 -0
- package/dist/server/bridge/stream-parser.d.ts.map +1 -0
- package/dist/server/bridge/stream-parser.js +26 -0
- package/dist/server/bridge/stream-parser.js.map +1 -0
- package/dist/server/config/engine-config.d.ts +4 -0
- package/dist/server/config/engine-config.d.ts.map +1 -0
- package/dist/server/config/engine-config.js +24 -0
- package/dist/server/config/engine-config.js.map +1 -0
- package/dist/server/config.d.ts +17 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +39 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/db/__tests__/chat-tables.test.d.ts +2 -0
- package/dist/server/db/__tests__/chat-tables.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/chat-tables.test.js +82 -0
- package/dist/server/db/__tests__/chat-tables.test.js.map +1 -0
- package/dist/server/db/__tests__/email-schema.test.d.ts +2 -0
- package/dist/server/db/__tests__/email-schema.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/email-schema.test.js +53 -0
- package/dist/server/db/__tests__/email-schema.test.js.map +1 -0
- package/dist/server/db/__tests__/scheduler-schema.test.d.ts +2 -0
- package/dist/server/db/__tests__/scheduler-schema.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/scheduler-schema.test.js +52 -0
- package/dist/server/db/__tests__/scheduler-schema.test.js.map +1 -0
- package/dist/server/db/connection.d.ts +4 -0
- package/dist/server/db/connection.d.ts.map +1 -0
- package/dist/server/db/connection.js +40 -0
- package/dist/server/db/connection.js.map +1 -0
- package/dist/server/db/migrations.d.ts +4 -0
- package/dist/server/db/migrations.d.ts.map +1 -0
- package/dist/server/db/migrations.js +47 -0
- package/dist/server/db/migrations.js.map +1 -0
- package/dist/server/db/schema.d.ts +2 -0
- package/dist/server/db/schema.d.ts.map +1 -0
- package/dist/server/db/schema.js +288 -0
- package/dist/server/db/schema.js.map +1 -0
- package/dist/server/email/__tests__/campaign-routes.test.d.ts +2 -0
- package/dist/server/email/__tests__/campaign-routes.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/campaign-routes.test.js +216 -0
- package/dist/server/email/__tests__/campaign-routes.test.js.map +1 -0
- package/dist/server/email/__tests__/campaign-service.test.d.ts +2 -0
- package/dist/server/email/__tests__/campaign-service.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/campaign-service.test.js +79 -0
- package/dist/server/email/__tests__/campaign-service.test.js.map +1 -0
- package/dist/server/email/__tests__/email-queue-worker.test.d.ts +2 -0
- package/dist/server/email/__tests__/email-queue-worker.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/email-queue-worker.test.js +93 -0
- package/dist/server/email/__tests__/email-queue-worker.test.js.map +1 -0
- package/dist/server/email/__tests__/email-utils.test.d.ts +2 -0
- package/dist/server/email/__tests__/email-utils.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/email-utils.test.js +36 -0
- package/dist/server/email/__tests__/email-utils.test.js.map +1 -0
- package/dist/server/email/__tests__/lead-routes.test.d.ts +2 -0
- package/dist/server/email/__tests__/lead-routes.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/lead-routes.test.js +180 -0
- package/dist/server/email/__tests__/lead-routes.test.js.map +1 -0
- package/dist/server/email/__tests__/lead-service.test.d.ts +2 -0
- package/dist/server/email/__tests__/lead-service.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/lead-service.test.js +113 -0
- package/dist/server/email/__tests__/lead-service.test.js.map +1 -0
- package/dist/server/email/__tests__/ses-client.test.d.ts +2 -0
- package/dist/server/email/__tests__/ses-client.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/ses-client.test.js +48 -0
- package/dist/server/email/__tests__/ses-client.test.js.map +1 -0
- package/dist/server/email/__tests__/sns-webhook.test.d.ts +2 -0
- package/dist/server/email/__tests__/sns-webhook.test.d.ts.map +1 -0
- package/dist/server/email/__tests__/sns-webhook.test.js +40 -0
- package/dist/server/email/__tests__/sns-webhook.test.js.map +1 -0
- package/dist/server/email/campaign-routes.d.ts +8 -0
- package/dist/server/email/campaign-routes.d.ts.map +1 -0
- package/dist/server/email/campaign-routes.js +65 -0
- package/dist/server/email/campaign-routes.js.map +1 -0
- package/dist/server/email/campaign-service.d.ts +55 -0
- package/dist/server/email/campaign-service.d.ts.map +1 -0
- package/dist/server/email/campaign-service.js +89 -0
- package/dist/server/email/campaign-service.js.map +1 -0
- package/dist/server/email/email-queue-worker.d.ts +27 -0
- package/dist/server/email/email-queue-worker.d.ts.map +1 -0
- package/dist/server/email/email-queue-worker.js +119 -0
- package/dist/server/email/email-queue-worker.js.map +1 -0
- package/dist/server/email/email-utils.d.ts +5 -0
- package/dist/server/email/email-utils.d.ts.map +1 -0
- package/dist/server/email/email-utils.js +24 -0
- package/dist/server/email/email-utils.js.map +1 -0
- package/dist/server/email/lead-routes.d.ts +8 -0
- package/dist/server/email/lead-routes.d.ts.map +1 -0
- package/dist/server/email/lead-routes.js +56 -0
- package/dist/server/email/lead-routes.js.map +1 -0
- package/dist/server/email/lead-service.d.ts +66 -0
- package/dist/server/email/lead-service.d.ts.map +1 -0
- package/dist/server/email/lead-service.js +138 -0
- package/dist/server/email/lead-service.js.map +1 -0
- package/dist/server/email/ses-client.d.ts +27 -0
- package/dist/server/email/ses-client.d.ts.map +1 -0
- package/dist/server/email/ses-client.js +44 -0
- package/dist/server/email/ses-client.js.map +1 -0
- package/dist/server/email/sns-webhook.d.ts +10 -0
- package/dist/server/email/sns-webhook.d.ts.map +1 -0
- package/dist/server/email/sns-webhook.js +73 -0
- package/dist/server/email/sns-webhook.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +36 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp/expxagents-mcp.d.ts +2 -0
- package/dist/server/mcp/expxagents-mcp.d.ts.map +1 -0
- package/dist/server/mcp/expxagents-mcp.js +230 -0
- package/dist/server/mcp/expxagents-mcp.js.map +1 -0
- package/dist/server/routes/__tests__/conversations.test.d.ts +2 -0
- package/dist/server/routes/__tests__/conversations.test.d.ts.map +1 -0
- package/dist/server/routes/__tests__/conversations.test.js +111 -0
- package/dist/server/routes/__tests__/conversations.test.js.map +1 -0
- package/dist/server/routes/conversations.d.ts +8 -0
- package/dist/server/routes/conversations.d.ts.map +1 -0
- package/dist/server/routes/conversations.js +36 -0
- package/dist/server/routes/conversations.js.map +1 -0
- package/dist/server/scheduler/__tests__/job-runner.test.d.ts +2 -0
- package/dist/server/scheduler/__tests__/job-runner.test.d.ts.map +1 -0
- package/dist/server/scheduler/__tests__/job-runner.test.js +488 -0
- package/dist/server/scheduler/__tests__/job-runner.test.js.map +1 -0
- package/dist/server/scheduler/__tests__/scheduler-routes.test.d.ts +2 -0
- package/dist/server/scheduler/__tests__/scheduler-routes.test.d.ts.map +1 -0
- package/dist/server/scheduler/__tests__/scheduler-routes.test.js +167 -0
- package/dist/server/scheduler/__tests__/scheduler-routes.test.js.map +1 -0
- package/dist/server/scheduler/__tests__/scheduler-service.test.d.ts +2 -0
- package/dist/server/scheduler/__tests__/scheduler-service.test.d.ts.map +1 -0
- package/dist/server/scheduler/__tests__/scheduler-service.test.js +207 -0
- package/dist/server/scheduler/__tests__/scheduler-service.test.js.map +1 -0
- package/dist/server/scheduler/job-runner.d.ts +73 -0
- package/dist/server/scheduler/job-runner.d.ts.map +1 -0
- package/dist/server/scheduler/job-runner.js +407 -0
- package/dist/server/scheduler/job-runner.js.map +1 -0
- package/dist/server/scheduler/scheduler-routes.d.ts +10 -0
- package/dist/server/scheduler/scheduler-routes.d.ts.map +1 -0
- package/dist/server/scheduler/scheduler-routes.js +105 -0
- package/dist/server/scheduler/scheduler-routes.js.map +1 -0
- package/dist/server/scheduler/scheduler-service.d.ts +55 -0
- package/dist/server/scheduler/scheduler-service.d.ts.map +1 -0
- package/dist/server/scheduler/scheduler-service.js +271 -0
- package/dist/server/scheduler/scheduler-service.js.map +1 -0
- package/dist/server/services/__tests__/cost-service.test.d.ts +2 -0
- package/dist/server/services/__tests__/cost-service.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/cost-service.test.js +72 -0
- package/dist/server/services/__tests__/cost-service.test.js.map +1 -0
- package/dist/server/services/__tests__/execution-log-service.test.d.ts +2 -0
- package/dist/server/services/__tests__/execution-log-service.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/execution-log-service.test.js +40 -0
- package/dist/server/services/__tests__/execution-log-service.test.js.map +1 -0
- package/dist/server/services/__tests__/integration-registry.test.d.ts +2 -0
- package/dist/server/services/__tests__/integration-registry.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/integration-registry.test.js +28 -0
- package/dist/server/services/__tests__/integration-registry.test.js.map +1 -0
- package/dist/server/services/__tests__/log-service.test.d.ts +2 -0
- package/dist/server/services/__tests__/log-service.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/log-service.test.js +49 -0
- package/dist/server/services/__tests__/log-service.test.js.map +1 -0
- package/dist/server/services/__tests__/permissions-service.test.d.ts +2 -0
- package/dist/server/services/__tests__/permissions-service.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/permissions-service.test.js +46 -0
- package/dist/server/services/__tests__/permissions-service.test.js.map +1 -0
- package/dist/server/services/__tests__/pipeline-task-service.test.d.ts +2 -0
- package/dist/server/services/__tests__/pipeline-task-service.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/pipeline-task-service.test.js +268 -0
- package/dist/server/services/__tests__/pipeline-task-service.test.js.map +1 -0
- package/dist/server/services/__tests__/state-service.test.d.ts +2 -0
- package/dist/server/services/__tests__/state-service.test.d.ts.map +1 -0
- package/dist/server/services/__tests__/state-service.test.js +136 -0
- package/dist/server/services/__tests__/state-service.test.js.map +1 -0
- package/dist/server/services/activity-service.d.ts +35 -0
- package/dist/server/services/activity-service.d.ts.map +1 -0
- package/dist/server/services/activity-service.js +92 -0
- package/dist/server/services/activity-service.js.map +1 -0
- package/dist/server/services/cost-service.d.ts +55 -0
- package/dist/server/services/cost-service.d.ts.map +1 -0
- package/dist/server/services/cost-service.js +59 -0
- package/dist/server/services/cost-service.js.map +1 -0
- package/dist/server/services/execution-log-service.d.ts +20 -0
- package/dist/server/services/execution-log-service.d.ts.map +1 -0
- package/dist/server/services/execution-log-service.js +17 -0
- package/dist/server/services/execution-log-service.js.map +1 -0
- package/dist/server/services/integration-registry.d.ts +9 -0
- package/dist/server/services/integration-registry.d.ts.map +1 -0
- package/dist/server/services/integration-registry.js +14 -0
- package/dist/server/services/integration-registry.js.map +1 -0
- package/dist/server/services/log-service.d.ts +28 -0
- package/dist/server/services/log-service.d.ts.map +1 -0
- package/dist/server/services/log-service.js +34 -0
- package/dist/server/services/log-service.js.map +1 -0
- package/dist/server/services/permissions-service.d.ts +10 -0
- package/dist/server/services/permissions-service.d.ts.map +1 -0
- package/dist/server/services/permissions-service.js +48 -0
- package/dist/server/services/permissions-service.js.map +1 -0
- package/dist/server/services/pipeline-task-service.d.ts +79 -0
- package/dist/server/services/pipeline-task-service.d.ts.map +1 -0
- package/dist/server/services/pipeline-task-service.js +122 -0
- package/dist/server/services/pipeline-task-service.js.map +1 -0
- package/dist/server/services/squad-registry.d.ts +35 -0
- package/dist/server/services/squad-registry.d.ts.map +1 -0
- package/dist/server/services/squad-registry.js +141 -0
- package/dist/server/services/squad-registry.js.map +1 -0
- package/dist/server/services/state-service.d.ts +22 -0
- package/dist/server/services/state-service.d.ts.map +1 -0
- package/dist/server/services/state-service.js +114 -0
- package/dist/server/services/state-service.js.map +1 -0
- package/dist/server/types/a2ui.d.ts +27 -0
- package/dist/server/types/a2ui.d.ts.map +1 -0
- package/dist/server/types/a2ui.js +2 -0
- package/dist/server/types/a2ui.js.map +1 -0
- package/dist/server/utils/find-free-port.d.ts +2 -0
- package/dist/server/utils/find-free-port.d.ts.map +1 -0
- package/dist/server/utils/find-free-port.js +17 -0
- package/dist/server/utils/find-free-port.js.map +1 -0
- package/dist/server/watcher/__tests__/file-watcher.test.d.ts +2 -0
- package/dist/server/watcher/__tests__/file-watcher.test.d.ts.map +1 -0
- package/dist/server/watcher/__tests__/file-watcher.test.js +81 -0
- package/dist/server/watcher/__tests__/file-watcher.test.js.map +1 -0
- package/dist/server/watcher/file-watcher.d.ts +19 -0
- package/dist/server/watcher/file-watcher.d.ts.map +1 -0
- package/dist/server/watcher/file-watcher.js +105 -0
- package/dist/server/watcher/file-watcher.js.map +1 -0
- package/dist/server/watcher/state-parser.d.ts +77 -0
- package/dist/server/watcher/state-parser.d.ts.map +1 -0
- package/dist/server/watcher/state-parser.js +78 -0
- package/dist/server/watcher/state-parser.js.map +1 -0
- package/dist/server/ws/ws-auth.d.ts +4 -0
- package/dist/server/ws/ws-auth.d.ts.map +1 -0
- package/dist/server/ws/ws-auth.js +42 -0
- package/dist/server/ws/ws-auth.js.map +1 -0
- package/dist/server/ws/ws-handler.d.ts +12 -0
- package/dist/server/ws/ws-handler.d.ts.map +1 -0
- package/dist/server/ws/ws-handler.js +171 -0
- package/dist/server/ws/ws-handler.js.map +1 -0
- package/dist/server/ws/ws-rooms.d.ts +12 -0
- package/dist/server/ws/ws-rooms.d.ts.map +1 -0
- package/dist/server/ws/ws-rooms.js +52 -0
- package/dist/server/ws/ws-rooms.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,936 @@
|
|
|
1
|
+
---
|
|
2
|
+
platform: software-house
|
|
3
|
+
format: fullstack-page-generation
|
|
4
|
+
constraints:
|
|
5
|
+
max_chars: null
|
|
6
|
+
image_ratio: null
|
|
7
|
+
max_hashtags: null
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Full-Stack Page Generation — Best Practices
|
|
11
|
+
|
|
12
|
+
## Philosophy
|
|
13
|
+
|
|
14
|
+
Unlike single-file HTML landing pages, full-stack generation creates **production-ready project structures** that integrate with existing codebases or stand alone as deployable applications. The goal is never a throwaway prototype — it is a codebase a team can maintain, extend, and deploy with confidence.
|
|
15
|
+
|
|
16
|
+
Every generated project must be:
|
|
17
|
+
|
|
18
|
+
- **Typed end-to-end** — TypeScript strict mode, no `any` escapes.
|
|
19
|
+
- **Token-driven** — Colors, spacing, typography, and radii defined once, referenced everywhere.
|
|
20
|
+
- **Component-decomposed** — Atoms, molecules, organisms. Never a monolithic single component.
|
|
21
|
+
- **Build-ready** — `npm install && npm run build` must succeed on first run.
|
|
22
|
+
- **Accessible by default** — Semantic HTML, ARIA attributes, keyboard navigation, focus management.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Supported Stacks
|
|
27
|
+
|
|
28
|
+
### 1. Next.js (Recommended for SSR/SSG)
|
|
29
|
+
|
|
30
|
+
Best for marketing sites, content platforms, and applications requiring server-side rendering or static generation.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
project/
|
|
34
|
+
├── src/
|
|
35
|
+
│ ├── app/ # App Router (Next.js 14+)
|
|
36
|
+
│ │ ├── layout.tsx # Root layout with metadata
|
|
37
|
+
│ │ ├── page.tsx # Home page
|
|
38
|
+
│ │ └── globals.css # Global resets + font imports
|
|
39
|
+
│ ├── components/
|
|
40
|
+
│ │ ├── ui/ # Atoms: Button, Badge, Input, Heading, Text
|
|
41
|
+
│ │ ├── sections/ # Organisms: Hero, Features, Pricing, Testimonials
|
|
42
|
+
│ │ └── layout/ # Layout: Container, Header, Footer, NavBar
|
|
43
|
+
│ ├── lib/
|
|
44
|
+
│ │ └── utils.ts # cn() helper, formatters, constants
|
|
45
|
+
│ └── styles/
|
|
46
|
+
│ └── tokens.css # Design tokens as CSS custom properties
|
|
47
|
+
├── public/ # Static assets (images, fonts, favicon)
|
|
48
|
+
├── package.json
|
|
49
|
+
├── tailwind.config.ts
|
|
50
|
+
├── tsconfig.json
|
|
51
|
+
└── next.config.ts
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Vite + React (Recommended for SPAs)
|
|
55
|
+
|
|
56
|
+
Best for interactive applications, dashboards, and tools that do not need server-side rendering.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
project/
|
|
60
|
+
├── src/
|
|
61
|
+
│ ├── main.tsx # Entry point — ReactDOM.createRoot
|
|
62
|
+
│ ├── App.tsx # Root component with router
|
|
63
|
+
│ ├── components/
|
|
64
|
+
│ │ ├── ui/ # Atoms: Button, Badge, Input, Heading, Text
|
|
65
|
+
│ │ ├── sections/ # Organisms: Hero, Features, Pricing
|
|
66
|
+
│ │ └── layout/ # Layout: Container, Header, Footer
|
|
67
|
+
│ ├── hooks/ # Custom hooks (useMediaQuery, useScrollPosition)
|
|
68
|
+
│ ├── lib/
|
|
69
|
+
│ │ └── utils.ts # cn() helper, formatters
|
|
70
|
+
│ └── styles/
|
|
71
|
+
│ ├── tokens.css # Design tokens
|
|
72
|
+
│ └── global.css # Resets, base styles
|
|
73
|
+
├── public/ # Static assets
|
|
74
|
+
├── index.html # HTML entry point
|
|
75
|
+
├── package.json
|
|
76
|
+
├── vite.config.ts
|
|
77
|
+
├── tailwind.config.ts
|
|
78
|
+
└── tsconfig.json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Astro (Recommended for content-heavy static sites)
|
|
82
|
+
|
|
83
|
+
Best for blogs, documentation sites, and content-driven pages where minimal JavaScript is desired.
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
project/
|
|
87
|
+
├── src/
|
|
88
|
+
│ ├── layouts/
|
|
89
|
+
│ │ └── BaseLayout.astro # Root layout with <html>, <head>, <body>
|
|
90
|
+
│ ├── pages/
|
|
91
|
+
│ │ └── index.astro # Home page
|
|
92
|
+
│ ├── components/ # .astro or .tsx components
|
|
93
|
+
│ │ ├── ui/
|
|
94
|
+
│ │ ├── sections/
|
|
95
|
+
│ │ └── layout/
|
|
96
|
+
│ └── styles/
|
|
97
|
+
│ └── tokens.css
|
|
98
|
+
├── public/
|
|
99
|
+
├── package.json
|
|
100
|
+
├── astro.config.mjs
|
|
101
|
+
├── tailwind.config.ts
|
|
102
|
+
└── tsconfig.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Generation Workflow
|
|
108
|
+
|
|
109
|
+
### Step 1: Scaffold Project
|
|
110
|
+
|
|
111
|
+
Initialize the project with all necessary tooling before writing any component code.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Next.js
|
|
115
|
+
npx create-next-app@latest project --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
|
|
116
|
+
|
|
117
|
+
# Vite + React
|
|
118
|
+
npm create vite@latest project -- --template react-ts
|
|
119
|
+
cd project && npm install tailwindcss @tailwindcss/vite
|
|
120
|
+
|
|
121
|
+
# Astro
|
|
122
|
+
npm create astro@latest project -- --template minimal --typescript strict
|
|
123
|
+
cd project && npx astro add tailwind
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
After scaffolding:
|
|
127
|
+
1. Remove boilerplate content (default pages, sample styles).
|
|
128
|
+
2. Create the `styles/tokens.css` file with the design token system.
|
|
129
|
+
3. Create the component directory structure (`ui/`, `sections/`, `layout/`).
|
|
130
|
+
4. Add the `lib/utils.ts` helper file.
|
|
131
|
+
|
|
132
|
+
### Step 2: Design Token System
|
|
133
|
+
|
|
134
|
+
All visual properties flow from a single source of truth. Define tokens as CSS custom properties and map them into Tailwind's configuration.
|
|
135
|
+
|
|
136
|
+
**`src/styles/tokens.css`**:
|
|
137
|
+
|
|
138
|
+
```css
|
|
139
|
+
:root {
|
|
140
|
+
/* === COLORS === */
|
|
141
|
+
--color-base-900: #0f172a;
|
|
142
|
+
--color-base-800: #1e293b;
|
|
143
|
+
--color-base-700: #334155;
|
|
144
|
+
--color-base-200: #e2e8f0;
|
|
145
|
+
--color-base-100: #f1f5f9;
|
|
146
|
+
--color-base-50: #f8fafc;
|
|
147
|
+
--color-white: #ffffff;
|
|
148
|
+
|
|
149
|
+
--color-accent: oklch(0.65 0.25 250);
|
|
150
|
+
--color-accent-hover: oklch(0.58 0.25 250);
|
|
151
|
+
--color-accent-subtle: oklch(0.65 0.25 250 / 0.1);
|
|
152
|
+
|
|
153
|
+
--color-surface: var(--color-white);
|
|
154
|
+
--color-surface-alt: var(--color-base-50);
|
|
155
|
+
--color-surface-dark: var(--color-base-900);
|
|
156
|
+
--color-on-surface: var(--color-base-800);
|
|
157
|
+
--color-on-surface-muted: var(--color-base-700);
|
|
158
|
+
--color-on-dark: var(--color-base-50);
|
|
159
|
+
|
|
160
|
+
/* === SPACING (4px base) === */
|
|
161
|
+
--space-1: 0.25rem;
|
|
162
|
+
--space-2: 0.5rem;
|
|
163
|
+
--space-3: 0.75rem;
|
|
164
|
+
--space-4: 1rem;
|
|
165
|
+
--space-6: 1.5rem;
|
|
166
|
+
--space-8: 2rem;
|
|
167
|
+
--space-12: 3rem;
|
|
168
|
+
--space-16: 4rem;
|
|
169
|
+
--space-20: 5rem;
|
|
170
|
+
--space-24: 6rem;
|
|
171
|
+
|
|
172
|
+
--section-py: clamp(4rem, 10vw, 8rem);
|
|
173
|
+
--container-max: 1200px;
|
|
174
|
+
--container-narrow: 720px;
|
|
175
|
+
|
|
176
|
+
/* === TYPOGRAPHY === */
|
|
177
|
+
--font-display: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
|
|
178
|
+
--font-body: 'Inter', system-ui, sans-serif;
|
|
179
|
+
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
180
|
+
|
|
181
|
+
--text-display: clamp(2.5rem, 5vw + 1rem, 4.5rem);
|
|
182
|
+
--text-h1: clamp(2rem, 4vw + 0.5rem, 3.5rem);
|
|
183
|
+
--text-h2: clamp(1.5rem, 3vw + 0.25rem, 2.25rem);
|
|
184
|
+
--text-h3: clamp(1.125rem, 2vw + 0.25rem, 1.5rem);
|
|
185
|
+
--text-body: clamp(1rem, 1vw + 0.5rem, 1.125rem);
|
|
186
|
+
--text-small: 0.875rem;
|
|
187
|
+
|
|
188
|
+
--leading-tight: 1.15;
|
|
189
|
+
--leading-normal: 1.6;
|
|
190
|
+
|
|
191
|
+
/* === RADIUS === */
|
|
192
|
+
--radius-sm: 0.375rem;
|
|
193
|
+
--radius-md: 0.75rem;
|
|
194
|
+
--radius-lg: 1rem;
|
|
195
|
+
--radius-xl: 1.5rem;
|
|
196
|
+
--radius-full: 9999px;
|
|
197
|
+
|
|
198
|
+
/* === SHADOWS === */
|
|
199
|
+
--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05);
|
|
200
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
201
|
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
202
|
+
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
203
|
+
|
|
204
|
+
/* === TRANSITIONS === */
|
|
205
|
+
--transition-fast: 150ms ease;
|
|
206
|
+
--transition-base: 250ms ease;
|
|
207
|
+
--transition-slow: 400ms ease;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Step 3: Tailwind Configuration
|
|
212
|
+
|
|
213
|
+
Map CSS tokens into Tailwind so utility classes reference the design system.
|
|
214
|
+
|
|
215
|
+
**`tailwind.config.ts`**:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import type { Config } from "tailwindcss";
|
|
219
|
+
|
|
220
|
+
const config: Config = {
|
|
221
|
+
content: ["./src/**/*.{ts,tsx,astro,mdx}"],
|
|
222
|
+
theme: {
|
|
223
|
+
extend: {
|
|
224
|
+
colors: {
|
|
225
|
+
accent: {
|
|
226
|
+
DEFAULT: "var(--color-accent)",
|
|
227
|
+
hover: "var(--color-accent-hover)",
|
|
228
|
+
subtle: "var(--color-accent-subtle)",
|
|
229
|
+
},
|
|
230
|
+
surface: {
|
|
231
|
+
DEFAULT: "var(--color-surface)",
|
|
232
|
+
alt: "var(--color-surface-alt)",
|
|
233
|
+
dark: "var(--color-surface-dark)",
|
|
234
|
+
},
|
|
235
|
+
on: {
|
|
236
|
+
surface: "var(--color-on-surface)",
|
|
237
|
+
"surface-muted": "var(--color-on-surface-muted)",
|
|
238
|
+
dark: "var(--color-on-dark)",
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
fontFamily: {
|
|
242
|
+
display: "var(--font-display)",
|
|
243
|
+
body: "var(--font-body)",
|
|
244
|
+
mono: "var(--font-mono)",
|
|
245
|
+
},
|
|
246
|
+
fontSize: {
|
|
247
|
+
display: ["var(--text-display)", { lineHeight: "var(--leading-tight)" }],
|
|
248
|
+
h1: ["var(--text-h1)", { lineHeight: "var(--leading-tight)" }],
|
|
249
|
+
h2: ["var(--text-h2)", { lineHeight: "var(--leading-tight)" }],
|
|
250
|
+
h3: ["var(--text-h3)", { lineHeight: "var(--leading-tight)" }],
|
|
251
|
+
body: ["var(--text-body)", { lineHeight: "var(--leading-normal)" }],
|
|
252
|
+
small: ["var(--text-small)", { lineHeight: "var(--leading-normal)" }],
|
|
253
|
+
},
|
|
254
|
+
borderRadius: {
|
|
255
|
+
sm: "var(--radius-sm)",
|
|
256
|
+
md: "var(--radius-md)",
|
|
257
|
+
lg: "var(--radius-lg)",
|
|
258
|
+
xl: "var(--radius-xl)",
|
|
259
|
+
},
|
|
260
|
+
boxShadow: {
|
|
261
|
+
sm: "var(--shadow-sm)",
|
|
262
|
+
md: "var(--shadow-md)",
|
|
263
|
+
lg: "var(--shadow-lg)",
|
|
264
|
+
xl: "var(--shadow-xl)",
|
|
265
|
+
},
|
|
266
|
+
maxWidth: {
|
|
267
|
+
container: "var(--container-max)",
|
|
268
|
+
narrow: "var(--container-narrow)",
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
plugins: [],
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export default config;
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Step 4: Component Library
|
|
279
|
+
|
|
280
|
+
Build components in a strict layered order: atoms first, then molecules, then organisms/sections.
|
|
281
|
+
|
|
282
|
+
#### Utility — `cn()` helper
|
|
283
|
+
|
|
284
|
+
**`src/lib/utils.ts`**:
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { type ClassValue, clsx } from "clsx";
|
|
288
|
+
import { twMerge } from "tailwind-merge";
|
|
289
|
+
|
|
290
|
+
export function cn(...inputs: ClassValue[]): string {
|
|
291
|
+
return twMerge(clsx(inputs));
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Install dependencies: `npm install clsx tailwind-merge`.
|
|
296
|
+
|
|
297
|
+
#### Atoms — Button
|
|
298
|
+
|
|
299
|
+
**`src/components/ui/Button.tsx`**:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { forwardRef, type ButtonHTMLAttributes } from "react";
|
|
303
|
+
import { cn } from "@/lib/utils";
|
|
304
|
+
|
|
305
|
+
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
306
|
+
variant?: "primary" | "secondary" | "ghost";
|
|
307
|
+
size?: "sm" | "md" | "lg";
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const variantStyles: Record<NonNullable<ButtonProps["variant"]>, string> = {
|
|
311
|
+
primary:
|
|
312
|
+
"bg-accent text-white hover:bg-accent-hover focus-visible:ring-accent/50",
|
|
313
|
+
secondary:
|
|
314
|
+
"bg-surface-alt text-on-surface border border-on-surface/10 hover:bg-surface-alt/80",
|
|
315
|
+
ghost:
|
|
316
|
+
"bg-transparent text-on-surface hover:bg-surface-alt",
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
const sizeStyles: Record<NonNullable<ButtonProps["size"]>, string> = {
|
|
320
|
+
sm: "px-3 py-1.5 text-small rounded-sm",
|
|
321
|
+
md: "px-5 py-2.5 text-body rounded-md",
|
|
322
|
+
lg: "px-8 py-3.5 text-body rounded-lg font-semibold",
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
326
|
+
({ variant = "primary", size = "md", className, children, ...props }, ref) => (
|
|
327
|
+
<button
|
|
328
|
+
ref={ref}
|
|
329
|
+
className={cn(
|
|
330
|
+
"inline-flex items-center justify-center font-medium",
|
|
331
|
+
"transition-colors duration-[var(--transition-fast)]",
|
|
332
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
333
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
334
|
+
variantStyles[variant],
|
|
335
|
+
sizeStyles[size],
|
|
336
|
+
className
|
|
337
|
+
)}
|
|
338
|
+
{...props}
|
|
339
|
+
>
|
|
340
|
+
{children}
|
|
341
|
+
</button>
|
|
342
|
+
)
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
Button.displayName = "Button";
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
#### Atoms — Heading
|
|
349
|
+
|
|
350
|
+
**`src/components/ui/Heading.tsx`**:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { type HTMLAttributes } from "react";
|
|
354
|
+
import { cn } from "@/lib/utils";
|
|
355
|
+
|
|
356
|
+
type HeadingLevel = "h1" | "h2" | "h3" | "h4";
|
|
357
|
+
|
|
358
|
+
interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
|
|
359
|
+
as?: HeadingLevel;
|
|
360
|
+
size?: "display" | "h1" | "h2" | "h3";
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const sizeClasses: Record<NonNullable<HeadingProps["size"]>, string> = {
|
|
364
|
+
display: "text-display font-display font-extrabold tracking-tight",
|
|
365
|
+
h1: "text-h1 font-display font-bold tracking-tight",
|
|
366
|
+
h2: "text-h2 font-display font-bold",
|
|
367
|
+
h3: "text-h3 font-display font-semibold",
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export function Heading({
|
|
371
|
+
as: Tag = "h2",
|
|
372
|
+
size = "h2",
|
|
373
|
+
className,
|
|
374
|
+
children,
|
|
375
|
+
...props
|
|
376
|
+
}: HeadingProps) {
|
|
377
|
+
return (
|
|
378
|
+
<Tag className={cn(sizeClasses[size], "text-on-surface", className)} {...props}>
|
|
379
|
+
{children}
|
|
380
|
+
</Tag>
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### Atoms — Badge
|
|
386
|
+
|
|
387
|
+
**`src/components/ui/Badge.tsx`**:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { type HTMLAttributes } from "react";
|
|
391
|
+
import { cn } from "@/lib/utils";
|
|
392
|
+
|
|
393
|
+
interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
|
|
394
|
+
variant?: "default" | "accent" | "outline";
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export function Badge({ variant = "default", className, children, ...props }: BadgeProps) {
|
|
398
|
+
return (
|
|
399
|
+
<span
|
|
400
|
+
className={cn(
|
|
401
|
+
"inline-flex items-center px-3 py-1 text-small font-medium rounded-full",
|
|
402
|
+
variant === "default" && "bg-surface-alt text-on-surface-muted",
|
|
403
|
+
variant === "accent" && "bg-accent-subtle text-accent",
|
|
404
|
+
variant === "outline" && "border border-on-surface/20 text-on-surface-muted",
|
|
405
|
+
className
|
|
406
|
+
)}
|
|
407
|
+
{...props}
|
|
408
|
+
>
|
|
409
|
+
{children}
|
|
410
|
+
</span>
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
#### Layout — Container
|
|
416
|
+
|
|
417
|
+
**`src/components/layout/Container.tsx`**:
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import { type HTMLAttributes } from "react";
|
|
421
|
+
import { cn } from "@/lib/utils";
|
|
422
|
+
|
|
423
|
+
interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
|
|
424
|
+
narrow?: boolean;
|
|
425
|
+
as?: "div" | "section" | "main" | "article";
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export function Container({
|
|
429
|
+
narrow = false,
|
|
430
|
+
as: Tag = "div",
|
|
431
|
+
className,
|
|
432
|
+
children,
|
|
433
|
+
...props
|
|
434
|
+
}: ContainerProps) {
|
|
435
|
+
return (
|
|
436
|
+
<Tag
|
|
437
|
+
className={cn(
|
|
438
|
+
"mx-auto w-full px-[var(--space-6)]",
|
|
439
|
+
narrow ? "max-w-narrow" : "max-w-container",
|
|
440
|
+
className
|
|
441
|
+
)}
|
|
442
|
+
{...props}
|
|
443
|
+
>
|
|
444
|
+
{children}
|
|
445
|
+
</Tag>
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
#### Molecules — Feature Card
|
|
451
|
+
|
|
452
|
+
**`src/components/ui/FeatureCard.tsx`**:
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
import { type ReactNode } from "react";
|
|
456
|
+
import { cn } from "@/lib/utils";
|
|
457
|
+
import { Heading } from "./Heading";
|
|
458
|
+
|
|
459
|
+
interface FeatureCardProps {
|
|
460
|
+
icon: ReactNode;
|
|
461
|
+
title: string;
|
|
462
|
+
description: string;
|
|
463
|
+
className?: string;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export function FeatureCard({ icon, title, description, className }: FeatureCardProps) {
|
|
467
|
+
return (
|
|
468
|
+
<div
|
|
469
|
+
className={cn(
|
|
470
|
+
"flex flex-col gap-[var(--space-4)] p-[var(--space-8)]",
|
|
471
|
+
"bg-surface rounded-lg shadow-sm",
|
|
472
|
+
"border border-on-surface/5",
|
|
473
|
+
"transition-shadow duration-[var(--transition-base)]",
|
|
474
|
+
"hover:shadow-md",
|
|
475
|
+
className
|
|
476
|
+
)}
|
|
477
|
+
>
|
|
478
|
+
<div className="flex h-12 w-12 items-center justify-center rounded-md bg-accent-subtle text-accent">
|
|
479
|
+
{icon}
|
|
480
|
+
</div>
|
|
481
|
+
<Heading as="h3" size="h3">
|
|
482
|
+
{title}
|
|
483
|
+
</Heading>
|
|
484
|
+
<p className="text-body text-on-surface-muted leading-relaxed">
|
|
485
|
+
{description}
|
|
486
|
+
</p>
|
|
487
|
+
</div>
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
#### Organisms — Hero Section
|
|
493
|
+
|
|
494
|
+
**`src/components/sections/HeroSection.tsx`**:
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
import { Container } from "@/components/layout/Container";
|
|
498
|
+
import { Badge } from "@/components/ui/Badge";
|
|
499
|
+
import { Button } from "@/components/ui/Button";
|
|
500
|
+
import { Heading } from "@/components/ui/Heading";
|
|
501
|
+
|
|
502
|
+
interface HeroSectionProps {
|
|
503
|
+
badge?: string;
|
|
504
|
+
title: string;
|
|
505
|
+
subtitle: string;
|
|
506
|
+
primaryCta: { label: string; href: string };
|
|
507
|
+
secondaryCta?: { label: string; href: string };
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export function HeroSection({
|
|
511
|
+
badge,
|
|
512
|
+
title,
|
|
513
|
+
subtitle,
|
|
514
|
+
primaryCta,
|
|
515
|
+
secondaryCta,
|
|
516
|
+
}: HeroSectionProps) {
|
|
517
|
+
return (
|
|
518
|
+
<section className="py-[var(--section-py)] bg-surface">
|
|
519
|
+
<Container narrow className="text-center">
|
|
520
|
+
<div className="flex flex-col items-center gap-[var(--space-6)]">
|
|
521
|
+
{badge && (
|
|
522
|
+
<Badge variant="accent">{badge}</Badge>
|
|
523
|
+
)}
|
|
524
|
+
|
|
525
|
+
<Heading as="h1" size="display">
|
|
526
|
+
{title}
|
|
527
|
+
</Heading>
|
|
528
|
+
|
|
529
|
+
<p className="max-w-[600px] text-body text-on-surface-muted leading-relaxed">
|
|
530
|
+
{subtitle}
|
|
531
|
+
</p>
|
|
532
|
+
|
|
533
|
+
<div className="flex flex-wrap items-center justify-center gap-[var(--space-4)] mt-[var(--space-4)]">
|
|
534
|
+
<Button size="lg" asChild>
|
|
535
|
+
<a href={primaryCta.href}>{primaryCta.label}</a>
|
|
536
|
+
</Button>
|
|
537
|
+
|
|
538
|
+
{secondaryCta && (
|
|
539
|
+
<Button variant="secondary" size="lg" asChild>
|
|
540
|
+
<a href={secondaryCta.href}>{secondaryCta.label}</a>
|
|
541
|
+
</Button>
|
|
542
|
+
)}
|
|
543
|
+
</div>
|
|
544
|
+
</div>
|
|
545
|
+
</Container>
|
|
546
|
+
</section>
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
#### Organisms — Features Grid
|
|
552
|
+
|
|
553
|
+
**`src/components/sections/FeaturesSection.tsx`**:
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
import { type ReactNode } from "react";
|
|
557
|
+
import { Container } from "@/components/layout/Container";
|
|
558
|
+
import { Heading } from "@/components/ui/Heading";
|
|
559
|
+
import { FeatureCard } from "@/components/ui/FeatureCard";
|
|
560
|
+
|
|
561
|
+
interface Feature {
|
|
562
|
+
icon: ReactNode;
|
|
563
|
+
title: string;
|
|
564
|
+
description: string;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
interface FeaturesSectionProps {
|
|
568
|
+
badge?: string;
|
|
569
|
+
title: string;
|
|
570
|
+
subtitle?: string;
|
|
571
|
+
features: Feature[];
|
|
572
|
+
columns?: 2 | 3 | 4;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const gridCols: Record<number, string> = {
|
|
576
|
+
2: "grid-cols-1 md:grid-cols-2",
|
|
577
|
+
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
|
|
578
|
+
4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
export function FeaturesSection({
|
|
582
|
+
title,
|
|
583
|
+
subtitle,
|
|
584
|
+
features,
|
|
585
|
+
columns = 3,
|
|
586
|
+
}: FeaturesSectionProps) {
|
|
587
|
+
return (
|
|
588
|
+
<section className="py-[var(--section-py)] bg-surface-alt">
|
|
589
|
+
<Container>
|
|
590
|
+
<div className="text-center mb-[var(--space-16)]">
|
|
591
|
+
<Heading as="h2" size="h2">
|
|
592
|
+
{title}
|
|
593
|
+
</Heading>
|
|
594
|
+
{subtitle && (
|
|
595
|
+
<p className="mt-[var(--space-4)] text-body text-on-surface-muted max-w-narrow mx-auto">
|
|
596
|
+
{subtitle}
|
|
597
|
+
</p>
|
|
598
|
+
)}
|
|
599
|
+
</div>
|
|
600
|
+
|
|
601
|
+
<div className={`grid ${gridCols[columns]} gap-[var(--space-8)]`}>
|
|
602
|
+
{features.map((feature) => (
|
|
603
|
+
<FeatureCard key={feature.title} {...feature} />
|
|
604
|
+
))}
|
|
605
|
+
</div>
|
|
606
|
+
</Container>
|
|
607
|
+
</section>
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Step 5: Page Assembly
|
|
613
|
+
|
|
614
|
+
Compose sections into a complete page.
|
|
615
|
+
|
|
616
|
+
**`src/app/page.tsx`** (Next.js) or **`src/App.tsx`** (Vite):
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
import { HeroSection } from "@/components/sections/HeroSection";
|
|
620
|
+
import { FeaturesSection } from "@/components/sections/FeaturesSection";
|
|
621
|
+
// Import more sections as needed
|
|
622
|
+
|
|
623
|
+
export default function HomePage() {
|
|
624
|
+
return (
|
|
625
|
+
<main>
|
|
626
|
+
<HeroSection
|
|
627
|
+
badge="Now in Beta"
|
|
628
|
+
title="Ship faster with AI-powered squads"
|
|
629
|
+
subtitle="Orchestrate teams of AI agents to design, build, and deploy production-ready applications in minutes."
|
|
630
|
+
primaryCta={{ label: "Get Started", href: "/signup" }}
|
|
631
|
+
secondaryCta={{ label: "See Demo", href: "/demo" }}
|
|
632
|
+
/>
|
|
633
|
+
|
|
634
|
+
<FeaturesSection
|
|
635
|
+
title="Everything you need"
|
|
636
|
+
subtitle="A complete platform for AI-driven development workflows."
|
|
637
|
+
columns={3}
|
|
638
|
+
features={[
|
|
639
|
+
{
|
|
640
|
+
icon: <span aria-hidden="true">⚙</span>,
|
|
641
|
+
title: "Automated Scaffolding",
|
|
642
|
+
description:
|
|
643
|
+
"Generate complete project structures with TypeScript, Tailwind, and your preferred framework.",
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
icon: <span aria-hidden="true">★</span>,
|
|
647
|
+
title: "Component Library",
|
|
648
|
+
description:
|
|
649
|
+
"Every project includes typed, accessible UI components built from your design tokens.",
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
icon: <span aria-hidden="true">⚡</span>,
|
|
653
|
+
title: "One-Command Deploy",
|
|
654
|
+
description:
|
|
655
|
+
"Build and deploy to Vercel, Netlify, or GitHub Pages with a single command.",
|
|
656
|
+
},
|
|
657
|
+
]}
|
|
658
|
+
/>
|
|
659
|
+
</main>
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### Step 6: SEO Metadata
|
|
665
|
+
|
|
666
|
+
**Next.js App Router** — export metadata from `layout.tsx` or `page.tsx`:
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
import type { Metadata } from "next";
|
|
670
|
+
|
|
671
|
+
export const metadata: Metadata = {
|
|
672
|
+
title: "Project Name — Tagline",
|
|
673
|
+
description: "A concise description for search engines (max 160 chars).",
|
|
674
|
+
openGraph: {
|
|
675
|
+
title: "Project Name — Tagline",
|
|
676
|
+
description: "A concise description for social sharing.",
|
|
677
|
+
url: "https://example.com",
|
|
678
|
+
siteName: "Project Name",
|
|
679
|
+
type: "website",
|
|
680
|
+
images: [{ url: "/og-image.png", width: 1200, height: 630 }],
|
|
681
|
+
},
|
|
682
|
+
twitter: {
|
|
683
|
+
card: "summary_large_image",
|
|
684
|
+
title: "Project Name — Tagline",
|
|
685
|
+
description: "A concise description for social sharing.",
|
|
686
|
+
images: ["/og-image.png"],
|
|
687
|
+
},
|
|
688
|
+
};
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
**Vite + React** — use `react-helmet-async`:
|
|
692
|
+
|
|
693
|
+
```typescript
|
|
694
|
+
import { Helmet } from "react-helmet-async";
|
|
695
|
+
|
|
696
|
+
export function SEO({ title, description }: { title: string; description: string }) {
|
|
697
|
+
return (
|
|
698
|
+
<Helmet>
|
|
699
|
+
<title>{title}</title>
|
|
700
|
+
<meta name="description" content={description} />
|
|
701
|
+
<meta property="og:title" content={title} />
|
|
702
|
+
<meta property="og:description" content={description} />
|
|
703
|
+
</Helmet>
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Step 7: Build and Deploy
|
|
709
|
+
|
|
710
|
+
```bash
|
|
711
|
+
# Next.js
|
|
712
|
+
npm run build # produces .next/
|
|
713
|
+
npx next export # static export to out/ (if applicable)
|
|
714
|
+
|
|
715
|
+
# Vite
|
|
716
|
+
npm run build # produces dist/
|
|
717
|
+
|
|
718
|
+
# Astro
|
|
719
|
+
npm run build # produces dist/
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
Deployment targets:
|
|
723
|
+
- **Vercel**: `npx vercel --prod` (zero-config for Next.js)
|
|
724
|
+
- **Netlify**: push to repo with `netlify.toml` or use `npx netlify deploy --prod`
|
|
725
|
+
- **GitHub Pages**: use `gh-pages` package or GitHub Actions workflow
|
|
726
|
+
|
|
727
|
+
---
|
|
728
|
+
|
|
729
|
+
## Package.json Template
|
|
730
|
+
|
|
731
|
+
```json
|
|
732
|
+
{
|
|
733
|
+
"name": "project-name",
|
|
734
|
+
"version": "0.1.0",
|
|
735
|
+
"private": true,
|
|
736
|
+
"type": "module",
|
|
737
|
+
"scripts": {
|
|
738
|
+
"dev": "next dev",
|
|
739
|
+
"build": "next build",
|
|
740
|
+
"start": "next start",
|
|
741
|
+
"lint": "next lint",
|
|
742
|
+
"type-check": "tsc --noEmit"
|
|
743
|
+
},
|
|
744
|
+
"dependencies": {
|
|
745
|
+
"next": "^14.2.0",
|
|
746
|
+
"react": "^18.3.0",
|
|
747
|
+
"react-dom": "^18.3.0",
|
|
748
|
+
"clsx": "^2.1.0",
|
|
749
|
+
"tailwind-merge": "^2.3.0"
|
|
750
|
+
},
|
|
751
|
+
"devDependencies": {
|
|
752
|
+
"@types/node": "^20.0.0",
|
|
753
|
+
"@types/react": "^18.3.0",
|
|
754
|
+
"@types/react-dom": "^18.3.0",
|
|
755
|
+
"autoprefixer": "^10.4.0",
|
|
756
|
+
"postcss": "^8.4.0",
|
|
757
|
+
"tailwindcss": "^3.4.0",
|
|
758
|
+
"typescript": "^5.5.0"
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
For **Vite + React**, replace the `scripts` and `next` dependency:
|
|
764
|
+
|
|
765
|
+
```json
|
|
766
|
+
{
|
|
767
|
+
"scripts": {
|
|
768
|
+
"dev": "vite",
|
|
769
|
+
"build": "tsc && vite build",
|
|
770
|
+
"preview": "vite preview",
|
|
771
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
772
|
+
"type-check": "tsc --noEmit"
|
|
773
|
+
},
|
|
774
|
+
"dependencies": {
|
|
775
|
+
"react": "^18.3.0",
|
|
776
|
+
"react-dom": "^18.3.0",
|
|
777
|
+
"react-router-dom": "^6.23.0",
|
|
778
|
+
"clsx": "^2.1.0",
|
|
779
|
+
"tailwind-merge": "^2.3.0"
|
|
780
|
+
},
|
|
781
|
+
"devDependencies": {
|
|
782
|
+
"@vitejs/plugin-react": "^4.3.0",
|
|
783
|
+
"vite": "^5.4.0",
|
|
784
|
+
"tailwindcss": "^3.4.0",
|
|
785
|
+
"typescript": "^5.5.0"
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
## TypeScript Configuration
|
|
793
|
+
|
|
794
|
+
**`tsconfig.json`**:
|
|
795
|
+
|
|
796
|
+
```json
|
|
797
|
+
{
|
|
798
|
+
"compilerOptions": {
|
|
799
|
+
"target": "ES2022",
|
|
800
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
801
|
+
"module": "ESNext",
|
|
802
|
+
"moduleResolution": "bundler",
|
|
803
|
+
"jsx": "react-jsx",
|
|
804
|
+
"strict": true,
|
|
805
|
+
"noUnusedLocals": true,
|
|
806
|
+
"noUnusedParameters": true,
|
|
807
|
+
"noFallthroughCasesInSwitch": true,
|
|
808
|
+
"forceConsistentCasingInFileNames": true,
|
|
809
|
+
"skipLibCheck": true,
|
|
810
|
+
"esModuleInterop": true,
|
|
811
|
+
"resolveJsonModule": true,
|
|
812
|
+
"isolatedModules": true,
|
|
813
|
+
"baseUrl": ".",
|
|
814
|
+
"paths": {
|
|
815
|
+
"@/*": ["./src/*"]
|
|
816
|
+
}
|
|
817
|
+
},
|
|
818
|
+
"include": ["src"],
|
|
819
|
+
"exclude": ["node_modules", "dist"]
|
|
820
|
+
}
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
---
|
|
824
|
+
|
|
825
|
+
## Scroll Animations
|
|
826
|
+
|
|
827
|
+
Use CSS `@keyframes` and `IntersectionObserver` for performant scroll-triggered animations. Avoid heavy animation libraries for simple reveal effects.
|
|
828
|
+
|
|
829
|
+
**`src/hooks/useInView.ts`**:
|
|
830
|
+
|
|
831
|
+
```typescript
|
|
832
|
+
import { useEffect, useRef, useState } from "react";
|
|
833
|
+
|
|
834
|
+
interface UseInViewOptions {
|
|
835
|
+
threshold?: number;
|
|
836
|
+
rootMargin?: string;
|
|
837
|
+
triggerOnce?: boolean;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
export function useInView({
|
|
841
|
+
threshold = 0.1,
|
|
842
|
+
rootMargin = "0px",
|
|
843
|
+
triggerOnce = true,
|
|
844
|
+
}: UseInViewOptions = {}) {
|
|
845
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
846
|
+
const [inView, setInView] = useState(false);
|
|
847
|
+
|
|
848
|
+
useEffect(() => {
|
|
849
|
+
const element = ref.current;
|
|
850
|
+
if (!element) return;
|
|
851
|
+
|
|
852
|
+
const observer = new IntersectionObserver(
|
|
853
|
+
([entry]) => {
|
|
854
|
+
if (entry.isIntersecting) {
|
|
855
|
+
setInView(true);
|
|
856
|
+
if (triggerOnce) observer.unobserve(element);
|
|
857
|
+
} else if (!triggerOnce) {
|
|
858
|
+
setInView(false);
|
|
859
|
+
}
|
|
860
|
+
},
|
|
861
|
+
{ threshold, rootMargin }
|
|
862
|
+
);
|
|
863
|
+
|
|
864
|
+
observer.observe(element);
|
|
865
|
+
return () => observer.disconnect();
|
|
866
|
+
}, [threshold, rootMargin, triggerOnce]);
|
|
867
|
+
|
|
868
|
+
return { ref, inView };
|
|
869
|
+
}
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
**Usage in a section component**:
|
|
873
|
+
|
|
874
|
+
```typescript
|
|
875
|
+
import { useInView } from "@/hooks/useInView";
|
|
876
|
+
import { cn } from "@/lib/utils";
|
|
877
|
+
|
|
878
|
+
export function AnimatedSection({ children }: { children: React.ReactNode }) {
|
|
879
|
+
const { ref, inView } = useInView({ threshold: 0.15 });
|
|
880
|
+
|
|
881
|
+
return (
|
|
882
|
+
<div
|
|
883
|
+
ref={ref}
|
|
884
|
+
className={cn(
|
|
885
|
+
"transition-all duration-700 ease-out",
|
|
886
|
+
inView
|
|
887
|
+
? "opacity-100 translate-y-0"
|
|
888
|
+
: "opacity-0 translate-y-8"
|
|
889
|
+
)}
|
|
890
|
+
>
|
|
891
|
+
{children}
|
|
892
|
+
</div>
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
---
|
|
898
|
+
|
|
899
|
+
## Responsive Design Rules
|
|
900
|
+
|
|
901
|
+
- **Mobile-first**: Write base styles for mobile, use `md:` and `lg:` breakpoints for larger screens.
|
|
902
|
+
- **Fluid typography**: All heading sizes use `clamp()` — no breakpoint jumps.
|
|
903
|
+
- **Fluid spacing**: Section padding uses `clamp()` for smooth scaling.
|
|
904
|
+
- **Grid to stack**: Multi-column grids collapse to single column on mobile (`grid-cols-1 md:grid-cols-2 lg:grid-cols-3`).
|
|
905
|
+
- **Touch targets**: Minimum 44x44px for all interactive elements on mobile.
|
|
906
|
+
- **No horizontal scroll**: Container always has `px-[var(--space-6)]` padding and `max-w-container`.
|
|
907
|
+
|
|
908
|
+
---
|
|
909
|
+
|
|
910
|
+
## Accessibility Checklist
|
|
911
|
+
|
|
912
|
+
- [ ] All images have `alt` text (or `alt=""` + `aria-hidden="true"` for decorative).
|
|
913
|
+
- [ ] Heading hierarchy is sequential (h1 > h2 > h3, no skipping levels).
|
|
914
|
+
- [ ] All interactive elements are keyboard-focusable with visible focus indicators.
|
|
915
|
+
- [ ] Color contrast ratio meets WCAG AA (4.5:1 for text, 3:1 for large text).
|
|
916
|
+
- [ ] Form inputs have associated `<label>` elements.
|
|
917
|
+
- [ ] Navigation landmarks use `<nav>`, `<main>`, `<header>`, `<footer>`.
|
|
918
|
+
- [ ] Decorative icons use `aria-hidden="true"`.
|
|
919
|
+
- [ ] Skip-to-content link is present for keyboard users.
|
|
920
|
+
|
|
921
|
+
---
|
|
922
|
+
|
|
923
|
+
## Anti-Patterns
|
|
924
|
+
|
|
925
|
+
| Anti-Pattern | Why It Fails | Correct Approach |
|
|
926
|
+
|---|---|---|
|
|
927
|
+
| Monolithic single component | Unmaintainable, untestable, impossible to reuse | Decompose into atoms, molecules, organisms |
|
|
928
|
+
| No TypeScript | Bugs surface at runtime, not build time | `strict: true` in tsconfig, all props typed |
|
|
929
|
+
| Hardcoded colors and spacing | Inconsistent design, painful to rebrand | Design tokens in `tokens.css`, referenced via Tailwind |
|
|
930
|
+
| CSS-in-JS with runtime overhead | Slower first paint, bundle bloat | Tailwind utilities or CSS Modules |
|
|
931
|
+
| No `package.json` / build config | Cannot install, build, or deploy | Always generate complete project scaffolding |
|
|
932
|
+
| Skipping accessibility | Excludes users, legal risk | Semantic HTML, ARIA, focus management from the start |
|
|
933
|
+
| Inline styles for layout | Hard to maintain, no responsive support | Tailwind utilities or CSS classes |
|
|
934
|
+
| No SEO metadata | Invisible to search engines and social platforms | Export metadata (Next.js) or use `<Helmet>` (Vite) |
|
|
935
|
+
| Single massive CSS file | Specificity conflicts, dead code accumulation | Component-scoped styles via Tailwind or CSS Modules |
|
|
936
|
+
| Skipping error states | Broken UX when API calls fail or content is missing | Loading, error, and empty states for every data-driven component |
|