cfsa-antigravity 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/bin/cli.mjs +324 -0
  2. package/package.json +34 -0
  3. package/template/.agent/instructions/commands.md +48 -0
  4. package/template/.agent/instructions/patterns.md +61 -0
  5. package/template/.agent/instructions/structure.md +29 -0
  6. package/template/.agent/instructions/tech-stack.md +43 -0
  7. package/template/.agent/instructions/workflow.md +41 -0
  8. package/template/.agent/kit-sync.md +15 -0
  9. package/template/.agent/rules/boundary-not-placeholder.md +146 -0
  10. package/template/.agent/rules/completion-checklist.md +48 -0
  11. package/template/.agent/rules/decision-classification.md +103 -0
  12. package/template/.agent/rules/extensibility.md +47 -0
  13. package/template/.agent/rules/question-vs-command.md +81 -0
  14. package/template/.agent/rules/security-first.md +43 -0
  15. package/template/.agent/rules/specificity-standards.md +54 -0
  16. package/template/.agent/rules/tdd-contract-first.md +57 -0
  17. package/template/.agent/rules/vertical-slices.md +42 -0
  18. package/template/.agent/skill-library/MANIFEST.md +480 -0
  19. package/template/.agent/skill-library/README.md +38 -0
  20. package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
  21. package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
  22. package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
  23. package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
  24. package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
  25. package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
  26. package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
  27. package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
  28. package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
  29. package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
  30. package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
  31. package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
  32. package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
  33. package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
  34. package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
  35. package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
  36. package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
  37. package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
  38. package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
  39. package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
  40. package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
  41. package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
  42. package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
  43. package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
  44. package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
  45. package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
  46. package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
  47. package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
  48. package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
  49. package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
  50. package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
  51. package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
  52. package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
  53. package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
  54. package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
  55. package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
  56. package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
  57. package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
  58. package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
  59. package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
  60. package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
  61. package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
  62. package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
  63. package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
  64. package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
  65. package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
  66. package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
  67. package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
  68. package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
  69. package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
  70. package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
  71. package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
  72. package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
  73. package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
  74. package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
  75. package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
  76. package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
  77. package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
  78. package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
  79. package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
  80. package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
  81. package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
  82. package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
  83. package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
  84. package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
  85. package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
  86. package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
  87. package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
  88. package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
  89. package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
  90. package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
  91. package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
  92. package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
  93. package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
  94. package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
  95. package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
  96. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
  97. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
  98. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
  99. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
  100. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
  101. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
  102. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
  103. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
  104. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
  105. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
  106. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
  107. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
  108. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
  109. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
  110. package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
  111. package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
  112. package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
  113. package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
  114. package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
  115. package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
  116. package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
  117. package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
  118. package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
  119. package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
  120. package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
  121. package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
  122. package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
  123. package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
  124. package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
  125. package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
  126. package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
  127. package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
  128. package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
  129. package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
  130. package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
  131. package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
  132. package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
  133. package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
  134. package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
  135. package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
  136. package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
  137. package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
  138. package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
  139. package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
  140. package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
  141. package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
  142. package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
  143. package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
  144. package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
  145. package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
  146. package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
  147. package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
  148. package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
  149. package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
  150. package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
  151. package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
  152. package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
  153. package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
  154. package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
  155. package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
  156. package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
  157. package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
  158. package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
  159. package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
  160. package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
  161. package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
  162. package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
  163. package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
  164. package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
  165. package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
  166. package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
  167. package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
  168. package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
  169. package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
  170. package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
  171. package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
  172. package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
  173. package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
  174. package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
  175. package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
  176. package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
  177. package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
  178. package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
  179. package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
  180. package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
  181. package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
  182. package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
  183. package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
  184. package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
  185. package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
  186. package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
  187. package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
  188. package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
  189. package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
  190. package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
  191. package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
  192. package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
  193. package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
  194. package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
  195. package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
  196. package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
  197. package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
  198. package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
  199. package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
  200. package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
  201. package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
  202. package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
  203. package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
  204. package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
  205. package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
  206. package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
  207. package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
  208. package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
  209. package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
  210. package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
  211. package/template/.agent/skills/accessibility/SKILL.md +522 -0
  212. package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
  213. package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
  214. package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
  215. package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
  216. package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
  217. package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  218. package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
  219. package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
  220. package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
  221. package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
  222. package/template/.agent/skills/api-versioning/SKILL.md +420 -0
  223. package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
  224. package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
  225. package/template/.agent/skills/brainstorming/SKILL.md +236 -0
  226. package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
  227. package/template/.agent/skills/clean-code/SKILL.md +94 -0
  228. package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
  229. package/template/.agent/skills/concise-planning/SKILL.md +68 -0
  230. package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
  231. package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
  232. package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
  233. package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
  234. package/template/.agent/skills/design-direction/SKILL.md +45 -0
  235. package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
  236. package/template/.agent/skills/find-skills/SKILL.md +145 -0
  237. package/template/.agent/skills/git-advanced/SKILL.md +972 -0
  238. package/template/.agent/skills/git-workflow/SKILL.md +420 -0
  239. package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
  240. package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
  241. package/template/.agent/skills/migration-management/SKILL.md +384 -0
  242. package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
  243. package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
  244. package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
  245. package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
  246. package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
  247. package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
  248. package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
  249. package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
  250. package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
  251. package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
  252. package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
  253. package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
  254. package/template/.agent/skills/prd-templates/SKILL.md +88 -0
  255. package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
  256. package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
  257. package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
  258. package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
  259. package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
  260. package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
  261. package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
  262. package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
  263. package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
  264. package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
  265. package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
  266. package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
  267. package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
  268. package/template/.agent/skills/prompt-engineer/README.md +659 -0
  269. package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
  270. package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
  271. package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
  272. package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
  273. package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
  274. package/template/.agent/skills/session-continuity/SKILL.md +730 -0
  275. package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
  276. package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
  277. package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
  278. package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
  279. package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
  280. package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
  281. package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
  282. package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
  283. package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
  284. package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
  285. package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
  286. package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
  287. package/template/.agent/skills/skill-creator/README.md +270 -0
  288. package/template/.agent/skills/skill-creator/SKILL.md +590 -0
  289. package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
  290. package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
  291. package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
  292. package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
  293. package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
  294. package/template/.agent/skills/spec-writing/SKILL.md +110 -0
  295. package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
  296. package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
  297. package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  298. package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
  299. package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
  300. package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
  301. package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
  302. package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
  303. package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
  304. package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
  305. package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
  306. package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
  307. package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
  308. package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
  309. package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
  310. package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
  311. package/template/.agent/skills/technical-writer/SKILL.md +242 -0
  312. package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
  313. package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
  314. package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
  315. package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
  316. package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
  317. package/template/.agent/workflows/audit-ambiguity.md +64 -0
  318. package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
  319. package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
  320. package/template/.agent/workflows/bootstrap-agents.md +66 -0
  321. package/template/.agent/workflows/create-prd-architecture.md +119 -0
  322. package/template/.agent/workflows/create-prd-compile.md +138 -0
  323. package/template/.agent/workflows/create-prd-design-system.md +135 -0
  324. package/template/.agent/workflows/create-prd-security.md +113 -0
  325. package/template/.agent/workflows/create-prd-stack.md +91 -0
  326. package/template/.agent/workflows/create-prd.md +168 -0
  327. package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
  328. package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
  329. package/template/.agent/workflows/decompose-architecture.md +111 -0
  330. package/template/.agent/workflows/evolve-contract.md +98 -0
  331. package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
  332. package/template/.agent/workflows/evolve-feature-classify.md +116 -0
  333. package/template/.agent/workflows/evolve-feature.md +56 -0
  334. package/template/.agent/workflows/ideate-discover.md +144 -0
  335. package/template/.agent/workflows/ideate-extract.md +129 -0
  336. package/template/.agent/workflows/ideate-validate.md +117 -0
  337. package/template/.agent/workflows/ideate.md +113 -0
  338. package/template/.agent/workflows/implement-slice-setup.md +113 -0
  339. package/template/.agent/workflows/implement-slice-tdd.md +198 -0
  340. package/template/.agent/workflows/implement-slice.md +50 -0
  341. package/template/.agent/workflows/plan-phase.md +202 -0
  342. package/template/.agent/workflows/propagate-decision-apply.md +135 -0
  343. package/template/.agent/workflows/propagate-decision-scan.md +147 -0
  344. package/template/.agent/workflows/propagate-decision.md +56 -0
  345. package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
  346. package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
  347. package/template/.agent/workflows/remediate-pipeline.md +55 -0
  348. package/template/.agent/workflows/resolve-ambiguity.md +82 -0
  349. package/template/.agent/workflows/sync-kit.md +209 -0
  350. package/template/.agent/workflows/update-architecture-map.md +74 -0
  351. package/template/.agent/workflows/validate-phase.md +219 -0
  352. package/template/.agent/workflows/verify-infrastructure.md +207 -0
  353. package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
  354. package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
  355. package/template/.agent/workflows/write-architecture-spec.md +63 -0
  356. package/template/.agent/workflows/write-be-spec-classify.md +165 -0
  357. package/template/.agent/workflows/write-be-spec-write.md +98 -0
  358. package/template/.agent/workflows/write-be-spec.md +76 -0
  359. package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
  360. package/template/.agent/workflows/write-fe-spec-write.md +94 -0
  361. package/template/.agent/workflows/write-fe-spec.md +71 -0
  362. package/template/AGENTS.md +176 -0
  363. package/template/GEMINI.md +177 -0
  364. package/template/docs/README.md +187 -0
  365. package/template/docs/audits/.gitkeep +0 -0
  366. package/template/docs/audits/README.md +10 -0
  367. package/template/docs/plans/.gitkeep +0 -0
  368. package/template/docs/plans/README.md +21 -0
  369. package/template/docs/plans/be/.gitkeep +0 -0
  370. package/template/docs/plans/be/README.md +11 -0
  371. package/template/docs/plans/fe/.gitkeep +0 -0
  372. package/template/docs/plans/fe/README.md +11 -0
  373. package/template/docs/plans/ia/.gitkeep +0 -0
  374. package/template/docs/plans/ia/README.md +17 -0
  375. package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
  376. package/template/docs/plans/ia/deep-dives/README.md +5 -0
  377. package/template/docs/plans/phases/.gitkeep +0 -0
  378. package/template/docs/plans/phases/README.md +11 -0
@@ -0,0 +1,1061 @@
1
+ ---
2
+ name: graphql
3
+ description: "Comprehensive GraphQL development guide covering schema design, resolvers, the N+1 problem with DataLoader, code-first vs schema-first approaches, Apollo Server and Client, error handling, pagination, authentication and authorization, file uploads, subscriptions, caching strategies, federation, input validation, depth limiting, query complexity analysis, testing, and codegen. Use when building or consuming GraphQL APIs, designing schemas, or optimizing GraphQL performance."
4
+ version: 1.0.0
5
+ ---
6
+
7
+ # GraphQL
8
+
9
+ ## 1. Philosophy
10
+
11
+ GraphQL is a **query language for APIs** that gives clients the power to ask for exactly the data they need. Unlike REST, where the server dictates the response shape, GraphQL lets the client define it.
12
+
13
+ **Key principles**:
14
+ - The schema is the contract. Every field, type, and relationship is explicitly defined.
15
+ - Clients ask for what they need. No over-fetching, no under-fetching.
16
+ - One endpoint, many queries. No URL-per-resource pattern.
17
+ - Strong typing. Every field has a type. The schema is self-documenting.
18
+ - The N+1 problem is your responsibility. GraphQL does not solve it -- DataLoader does.
19
+
20
+ ---
21
+
22
+ ## 2. Schema Design
23
+
24
+ ### Types
25
+
26
+ ```graphql
27
+ # Object types
28
+ type User {
29
+ id: ID!
30
+ email: String!
31
+ name: String!
32
+ avatar: String
33
+ role: UserRole!
34
+ posts(first: Int, after: String): PostConnection!
35
+ createdAt: DateTime!
36
+ updatedAt: DateTime!
37
+ }
38
+
39
+ # Enum types
40
+ enum UserRole {
41
+ ADMIN
42
+ MODERATOR
43
+ USER
44
+ }
45
+
46
+ # Custom scalars
47
+ scalar DateTime
48
+ scalar EmailAddress
49
+
50
+ # Interface types
51
+ interface Node {
52
+ id: ID!
53
+ }
54
+
55
+ interface Timestamped {
56
+ createdAt: DateTime!
57
+ updatedAt: DateTime!
58
+ }
59
+
60
+ # Union types
61
+ union SearchResult = User | Post | Comment
62
+
63
+ type Post implements Node & Timestamped {
64
+ id: ID!
65
+ title: String!
66
+ content: String!
67
+ author: User!
68
+ tags: [String!]!
69
+ status: PostStatus!
70
+ createdAt: DateTime!
71
+ updatedAt: DateTime!
72
+ }
73
+ ```
74
+
75
+ ### Queries
76
+
77
+ ```graphql
78
+ type Query {
79
+ # Single resource by ID
80
+ user(id: ID!): User
81
+ post(id: ID!): Post
82
+
83
+ # List with pagination and filtering
84
+ users(
85
+ first: Int
86
+ after: String
87
+ filter: UserFilter
88
+ orderBy: UserOrderBy
89
+ ): UserConnection!
90
+
91
+ posts(
92
+ first: Int
93
+ after: String
94
+ filter: PostFilter
95
+ ): PostConnection!
96
+
97
+ # Search across multiple types
98
+ search(query: String!, types: [SearchType!]): [SearchResult!]!
99
+
100
+ # Current authenticated user
101
+ me: User
102
+ }
103
+ ```
104
+
105
+ ### Mutations
106
+
107
+ ```graphql
108
+ type Mutation {
109
+ # Create
110
+ createPost(input: CreatePostInput!): CreatePostPayload!
111
+
112
+ # Update
113
+ updatePost(id: ID!, input: UpdatePostInput!): UpdatePostPayload!
114
+
115
+ # Delete
116
+ deletePost(id: ID!): DeletePostPayload!
117
+
118
+ # Authentication
119
+ signIn(input: SignInInput!): AuthPayload!
120
+ signUp(input: SignUpInput!): AuthPayload!
121
+ }
122
+
123
+ # Input types -- always use input types for mutation arguments
124
+ input CreatePostInput {
125
+ title: String!
126
+ content: String!
127
+ tags: [String!]
128
+ status: PostStatus
129
+ }
130
+
131
+ input UpdatePostInput {
132
+ title: String
133
+ content: String
134
+ tags: [String!]
135
+ status: PostStatus
136
+ }
137
+
138
+ # Payload types -- always return a payload, not the raw type
139
+ type CreatePostPayload {
140
+ post: Post
141
+ errors: [UserError!]!
142
+ }
143
+
144
+ type UserError {
145
+ field: String
146
+ message: String!
147
+ code: ErrorCode!
148
+ }
149
+ ```
150
+
151
+ ### Subscriptions
152
+
153
+ ```graphql
154
+ type Subscription {
155
+ postCreated: Post!
156
+ postUpdated(id: ID!): Post!
157
+ commentAdded(postId: ID!): Comment!
158
+ }
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 3. Resolvers
164
+
165
+ ### Basic Resolver Structure
166
+
167
+ ```typescript
168
+ // resolvers/user.ts
169
+ import type { Resolvers } from "../generated/graphql";
170
+
171
+ export const userResolvers: Resolvers = {
172
+ Query: {
173
+ user: async (_parent, { id }, context) => {
174
+ return context.dataSources.users.findById(id);
175
+ },
176
+
177
+ me: async (_parent, _args, context) => {
178
+ if (!context.currentUser) return null;
179
+ return context.dataSources.users.findById(context.currentUser.id);
180
+ },
181
+
182
+ users: async (_parent, { first, after, filter }, context) => {
183
+ return context.dataSources.users.findMany({ first, after, filter });
184
+ },
185
+ },
186
+
187
+ User: {
188
+ // Field resolver -- called for each User object
189
+ posts: async (parent, { first, after }, context) => {
190
+ return context.dataSources.posts.findByAuthorId(parent.id, { first, after });
191
+ },
192
+
193
+ // Computed field
194
+ avatar: (parent) => {
195
+ return parent.avatar || `https://api.dicebear.com/7.x/initials/svg?seed=${parent.name}`;
196
+ },
197
+ },
198
+
199
+ Mutation: {
200
+ createPost: async (_parent, { input }, context) => {
201
+ if (!context.currentUser) {
202
+ return {
203
+ post: null,
204
+ errors: [{ message: "Authentication required", code: "UNAUTHENTICATED" }],
205
+ };
206
+ }
207
+
208
+ const post = await context.dataSources.posts.create({
209
+ ...input,
210
+ authorId: context.currentUser.id,
211
+ });
212
+
213
+ return { post, errors: [] };
214
+ },
215
+ },
216
+ };
217
+ ```
218
+
219
+ ---
220
+
221
+ ## 4. The N+1 Problem and DataLoader
222
+
223
+ ### The Problem
224
+
225
+ ```graphql
226
+ # This query causes N+1 database queries:
227
+ query {
228
+ posts(first: 10) { # 1 query: SELECT * FROM posts LIMIT 10
229
+ edges {
230
+ node {
231
+ title
232
+ author { # 10 queries: SELECT * FROM users WHERE id = ?
233
+ name # (one for each post)
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }
239
+ ```
240
+
241
+ ### The Solution: DataLoader
242
+
243
+ DataLoader batches and deduplicates data fetching within a single request.
244
+
245
+ ```typescript
246
+ // dataloaders/user-loader.ts
247
+ import DataLoader from "dataloader";
248
+ import type { User } from "../types";
249
+
250
+ export function createUserLoader(db: Database) {
251
+ return new DataLoader<string, User | null>(async (userIds) => {
252
+ // Single batch query instead of N individual queries
253
+ const users = await db.query(
254
+ "SELECT * FROM users WHERE id = ANY($1)",
255
+ [userIds as string[]]
256
+ );
257
+
258
+ // DataLoader requires results in the same order as the input keys
259
+ const userMap = new Map(users.map((u) => [u.id, u]));
260
+ return userIds.map((id) => userMap.get(id) || null);
261
+ });
262
+ }
263
+
264
+ // context.ts -- create a new DataLoader per request
265
+ export function createContext({ req }: { req: Request }) {
266
+ return {
267
+ currentUser: getUserFromToken(req),
268
+ loaders: {
269
+ user: createUserLoader(db),
270
+ post: createPostLoader(db),
271
+ },
272
+ };
273
+ }
274
+
275
+ // resolvers -- use the loader instead of direct DB queries
276
+ const resolvers = {
277
+ Post: {
278
+ author: (parent, _args, context) => {
279
+ // Batched: all author lookups in this request are combined
280
+ return context.loaders.user.load(parent.authorId);
281
+ },
282
+ },
283
+ };
284
+ ```
285
+
286
+ ### DataLoader Rules
287
+
288
+ | Rule | Why |
289
+ |------|-----|
290
+ | Create a new instance per request | DataLoader caches results -- reusing across requests serves stale data |
291
+ | Return results in input order | DataLoader maps results by position, not by key |
292
+ | Return null for missing items | Do not throw -- return null and let the resolver handle it |
293
+ | Keep batch functions focused | One DataLoader per entity type |
294
+
295
+ ---
296
+
297
+ ## 5. Code-First vs Schema-First
298
+
299
+ ### Schema-First
300
+
301
+ Write the schema in SDL (Schema Definition Language), then implement resolvers.
302
+
303
+ ```graphql
304
+ # schema.graphql -- the source of truth
305
+ type Query {
306
+ user(id: ID!): User
307
+ }
308
+
309
+ type User {
310
+ id: ID!
311
+ name: String!
312
+ email: String!
313
+ }
314
+ ```
315
+
316
+ ```typescript
317
+ // resolvers.ts -- must match the schema exactly
318
+ const resolvers = {
319
+ Query: {
320
+ user: (_, { id }) => db.users.findById(id),
321
+ },
322
+ };
323
+ ```
324
+
325
+ **Pros**: Schema is readable, serves as documentation, frontend can work from the schema before resolvers exist.
326
+
327
+ **Cons**: Schema and resolvers can drift. No type safety between them without codegen.
328
+
329
+ ### Code-First
330
+
331
+ Define the schema programmatically with a library like Pothos, Nexus, or TypeGraphQL.
332
+
333
+ ```typescript
334
+ // schema.ts -- types and resolvers in one place
335
+ import SchemaBuilder from "@pothos/core";
336
+
337
+ const builder = new SchemaBuilder({});
338
+
339
+ builder.objectType("User", {
340
+ fields: (t) => ({
341
+ id: t.exposeID("id"),
342
+ name: t.exposeString("name"),
343
+ email: t.exposeString("email"),
344
+ posts: t.field({
345
+ type: [Post],
346
+ resolve: (user, _args, context) =>
347
+ context.loaders.postsByAuthor.load(user.id),
348
+ }),
349
+ }),
350
+ });
351
+
352
+ builder.queryType({
353
+ fields: (t) => ({
354
+ user: t.field({
355
+ type: "User",
356
+ nullable: true,
357
+ args: { id: t.arg.id({ required: true }) },
358
+ resolve: (_root, { id }, context) => context.loaders.user.load(id),
359
+ }),
360
+ }),
361
+ });
362
+
363
+ export const schema = builder.toSchema();
364
+ ```
365
+
366
+ **Pros**: Full type safety, no drift between schema and resolvers, refactoring support from IDE.
367
+
368
+ **Cons**: Schema is harder to read at a glance, steeper learning curve.
369
+
370
+ ### Recommendation
371
+
372
+ Use **schema-first with codegen** for teams where the schema serves as a contract between frontend and backend. Use **code-first** when a single team owns both and wants maximum type safety.
373
+
374
+ ---
375
+
376
+ ## 6. Apollo Server Setup
377
+
378
+ ```typescript
379
+ // server.ts
380
+ import { ApolloServer } from "@apollo/server";
381
+ import { expressMiddleware } from "@apollo/server/express4";
382
+ import { readFileSync } from "fs";
383
+ import express from "express";
384
+ import { resolvers } from "./resolvers";
385
+ import { createContext } from "./context";
386
+
387
+ const typeDefs = readFileSync("./schema.graphql", "utf-8");
388
+
389
+ const server = new ApolloServer({
390
+ typeDefs,
391
+ resolvers,
392
+ plugins: [
393
+ // Disable introspection in production
394
+ process.env.NODE_ENV === "production"
395
+ ? { requestDidStart: async () => ({}) }
396
+ : undefined,
397
+ ].filter(Boolean),
398
+ });
399
+
400
+ await server.start();
401
+
402
+ const app = express();
403
+ app.use(
404
+ "/graphql",
405
+ express.json(),
406
+ expressMiddleware(server, {
407
+ context: createContext,
408
+ })
409
+ );
410
+
411
+ app.listen(4000);
412
+ ```
413
+
414
+ ---
415
+
416
+ ## 7. Error Handling
417
+
418
+ ### User Errors vs System Errors
419
+
420
+ ```typescript
421
+ // User errors: expected, part of business logic
422
+ // Return them in the payload, not as GraphQL errors
423
+
424
+ type CreatePostPayload {
425
+ post: Post
426
+ errors: [UserError!]!
427
+ }
428
+
429
+ // System errors: unexpected, infrastructure failures
430
+ // Throw them as GraphQL errors
431
+
432
+ import { GraphQLError } from "graphql";
433
+
434
+ function requireAuth(context: Context) {
435
+ if (!context.currentUser) {
436
+ throw new GraphQLError("Authentication required", {
437
+ extensions: { code: "UNAUTHENTICATED" },
438
+ });
439
+ }
440
+ return context.currentUser;
441
+ }
442
+
443
+ // In resolvers
444
+ const resolvers = {
445
+ Mutation: {
446
+ createPost: async (_, { input }, context) => {
447
+ const user = requireAuth(context);
448
+
449
+ // Validation -- return as user error
450
+ if (input.title.length < 3) {
451
+ return {
452
+ post: null,
453
+ errors: [
454
+ { field: "title", message: "Title must be at least 3 characters", code: "VALIDATION" },
455
+ ],
456
+ };
457
+ }
458
+
459
+ const post = await context.dataSources.posts.create({
460
+ ...input,
461
+ authorId: user.id,
462
+ });
463
+
464
+ return { post, errors: [] };
465
+ },
466
+ },
467
+ };
468
+ ```
469
+
470
+ ### Error Formatting
471
+
472
+ ```typescript
473
+ const server = new ApolloServer({
474
+ typeDefs,
475
+ resolvers,
476
+ formatError: (formattedError, error) => {
477
+ // Never expose internal errors to clients
478
+ if (formattedError.extensions?.code === "INTERNAL_SERVER_ERROR") {
479
+ console.error("Internal error:", error);
480
+ return {
481
+ message: "An unexpected error occurred",
482
+ extensions: { code: "INTERNAL_SERVER_ERROR" },
483
+ };
484
+ }
485
+
486
+ // Strip stack traces in production
487
+ if (process.env.NODE_ENV === "production") {
488
+ delete formattedError.extensions?.stacktrace;
489
+ }
490
+
491
+ return formattedError;
492
+ },
493
+ });
494
+ ```
495
+
496
+ ---
497
+
498
+ ## 8. Pagination
499
+
500
+ ### Cursor-Based Pagination (Relay Spec)
501
+
502
+ ```graphql
503
+ # Connection type
504
+ type PostConnection {
505
+ edges: [PostEdge!]!
506
+ pageInfo: PageInfo!
507
+ totalCount: Int!
508
+ }
509
+
510
+ type PostEdge {
511
+ node: Post!
512
+ cursor: String!
513
+ }
514
+
515
+ type PageInfo {
516
+ hasNextPage: Boolean!
517
+ hasPreviousPage: Boolean!
518
+ startCursor: String
519
+ endCursor: String
520
+ }
521
+ ```
522
+
523
+ ```typescript
524
+ // Resolver implementation
525
+ async function paginatePosts(
526
+ { first = 20, after, filter }: PaginationArgs,
527
+ db: Database
528
+ ): Promise<PostConnection> {
529
+ const limit = Math.min(first, 100); // Cap at 100
530
+
531
+ // Decode cursor (base64 encoded ID or offset)
532
+ const cursorId = after ? Buffer.from(after, "base64").toString("utf-8") : null;
533
+
534
+ const whereClause = cursorId
535
+ ? { id: { gt: cursorId }, ...filter }
536
+ : { ...filter };
537
+
538
+ const posts = await db.post.findMany({
539
+ where: whereClause,
540
+ take: limit + 1, // Fetch one extra to determine hasNextPage
541
+ orderBy: { id: "asc" },
542
+ });
543
+
544
+ const hasNextPage = posts.length > limit;
545
+ const edges = posts.slice(0, limit).map((post) => ({
546
+ node: post,
547
+ cursor: Buffer.from(post.id).toString("base64"),
548
+ }));
549
+
550
+ return {
551
+ edges,
552
+ pageInfo: {
553
+ hasNextPage,
554
+ hasPreviousPage: !!after,
555
+ startCursor: edges[0]?.cursor ?? null,
556
+ endCursor: edges[edges.length - 1]?.cursor ?? null,
557
+ },
558
+ totalCount: await db.post.count({ where: filter }),
559
+ };
560
+ }
561
+ ```
562
+
563
+ ---
564
+
565
+ ## 9. Authentication and Authorization
566
+
567
+ ### Context-Based Auth
568
+
569
+ ```typescript
570
+ // context.ts
571
+ import { GraphQLError } from "graphql";
572
+ import { verifyToken } from "./auth";
573
+
574
+ export async function createContext({ req }: { req: Request }) {
575
+ const token = req.headers.authorization?.replace("Bearer ", "");
576
+ let currentUser = null;
577
+
578
+ if (token) {
579
+ try {
580
+ const payload = await verifyToken(token);
581
+ currentUser = await db.user.findById(payload.userId);
582
+ } catch {
583
+ // Invalid token -- continue as unauthenticated
584
+ }
585
+ }
586
+
587
+ return {
588
+ currentUser,
589
+ loaders: createLoaders(),
590
+ };
591
+ }
592
+ ```
593
+
594
+ ### Directive-Based Authorization
595
+
596
+ ```graphql
597
+ # Schema directives
598
+ directive @auth(requires: UserRole = USER) on FIELD_DEFINITION
599
+ directive @owner on FIELD_DEFINITION
600
+
601
+ type Query {
602
+ users: [User!]! @auth(requires: ADMIN)
603
+ me: User @auth
604
+ }
605
+
606
+ type Mutation {
607
+ updateUser(id: ID!, input: UpdateUserInput!): User @auth @owner
608
+ deleteUser(id: ID!): Boolean @auth(requires: ADMIN)
609
+ }
610
+ ```
611
+
612
+ ```typescript
613
+ // Auth directive transformer
614
+ import { mapSchema, MapperKind, getDirective } from "@graphql-tools/utils";
615
+
616
+ function authDirectiveTransformer(schema: GraphQLSchema) {
617
+ return mapSchema(schema, {
618
+ [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
619
+ const authDirective = getDirective(schema, fieldConfig, "auth")?.[0];
620
+ if (!authDirective) return fieldConfig;
621
+
622
+ const requiredRole = authDirective.requires || "USER";
623
+ const originalResolve = fieldConfig.resolve;
624
+
625
+ fieldConfig.resolve = async (source, args, context, info) => {
626
+ if (!context.currentUser) {
627
+ throw new GraphQLError("Authentication required", {
628
+ extensions: { code: "UNAUTHENTICATED" },
629
+ });
630
+ }
631
+
632
+ if (!hasRole(context.currentUser, requiredRole)) {
633
+ throw new GraphQLError("Insufficient permissions", {
634
+ extensions: { code: "FORBIDDEN" },
635
+ });
636
+ }
637
+
638
+ return originalResolve?.(source, args, context, info);
639
+ };
640
+
641
+ return fieldConfig;
642
+ },
643
+ });
644
+ }
645
+ ```
646
+
647
+ ---
648
+
649
+ ## 10. Caching Strategies
650
+
651
+ ### Apollo Client Normalized Cache
652
+
653
+ ```typescript
654
+ import { ApolloClient, InMemoryCache } from "@apollo/client";
655
+
656
+ const client = new ApolloClient({
657
+ uri: "/graphql",
658
+ cache: new InMemoryCache({
659
+ typePolicies: {
660
+ Query: {
661
+ fields: {
662
+ posts: {
663
+ // Merge paginated results
664
+ keyArgs: ["filter"],
665
+ merge(existing, incoming, { args }) {
666
+ if (!args?.after) return incoming;
667
+ return {
668
+ ...incoming,
669
+ edges: [...(existing?.edges || []), ...incoming.edges],
670
+ };
671
+ },
672
+ },
673
+ },
674
+ },
675
+ User: {
676
+ // Custom cache key
677
+ keyFields: ["id"],
678
+ },
679
+ Post: {
680
+ keyFields: ["id"],
681
+ fields: {
682
+ // Field-level read policy
683
+ createdAt: {
684
+ read(value: string) {
685
+ return new Date(value);
686
+ },
687
+ },
688
+ },
689
+ },
690
+ },
691
+ }),
692
+ });
693
+ ```
694
+
695
+ ### Server-Side Caching
696
+
697
+ ```typescript
698
+ // Cache hints in resolvers
699
+ const resolvers = {
700
+ Query: {
701
+ posts: async (_parent, args, context, info) => {
702
+ // Cache for 60 seconds, shared across users
703
+ info.cacheControl.setCacheHint({ maxAge: 60, scope: "PUBLIC" });
704
+ return context.dataSources.posts.findMany(args);
705
+ },
706
+
707
+ me: async (_parent, _args, context, info) => {
708
+ // User-specific data -- private cache
709
+ info.cacheControl.setCacheHint({ maxAge: 30, scope: "PRIVATE" });
710
+ return context.dataSources.users.findById(context.currentUser.id);
711
+ },
712
+ },
713
+ };
714
+ ```
715
+
716
+ ---
717
+
718
+ ## 11. Schema Federation
719
+
720
+ Federation splits a monolithic GraphQL schema across multiple services.
721
+
722
+ ```graphql
723
+ # User Service
724
+ type User @key(fields: "id") {
725
+ id: ID!
726
+ name: String!
727
+ email: String!
728
+ }
729
+
730
+ type Query {
731
+ me: User
732
+ }
733
+
734
+ # Post Service -- extends User from another service
735
+ type User @key(fields: "id") {
736
+ id: ID!
737
+ posts: [Post!]!
738
+ }
739
+
740
+ type Post @key(fields: "id") {
741
+ id: ID!
742
+ title: String!
743
+ content: String!
744
+ author: User!
745
+ }
746
+
747
+ type Query {
748
+ post(id: ID!): Post
749
+ }
750
+ ```
751
+
752
+ ```typescript
753
+ // Post Service resolver -- resolve the User reference
754
+ const resolvers = {
755
+ User: {
756
+ __resolveReference: async (user, context) => {
757
+ // Only need to resolve the fields this service owns
758
+ return { id: user.id }; // id comes from the reference
759
+ },
760
+ posts: async (user, _args, context) => {
761
+ return context.dataSources.posts.findByAuthorId(user.id);
762
+ },
763
+ },
764
+ };
765
+ ```
766
+
767
+ ---
768
+
769
+ ## 12. Security: Depth and Complexity Limiting
770
+
771
+ ### Depth Limiting
772
+
773
+ Prevent deeply nested queries that could cause exponential resolver execution.
774
+
775
+ ```typescript
776
+ import depthLimit from "graphql-depth-limit";
777
+
778
+ const server = new ApolloServer({
779
+ typeDefs,
780
+ resolvers,
781
+ validationRules: [depthLimit(7)], // Max 7 levels deep
782
+ });
783
+ ```
784
+
785
+ ### Query Complexity Analysis
786
+
787
+ ```typescript
788
+ import { createComplexityLimitRule } from "graphql-validation-complexity";
789
+
790
+ const ComplexityLimit = createComplexityLimitRule(1000, {
791
+ scalarCost: 1,
792
+ objectCost: 2,
793
+ listFactor: 10,
794
+
795
+ onCost: (cost) => {
796
+ console.log("Query complexity:", cost);
797
+ },
798
+
799
+ formatErrorMessage: (cost) =>
800
+ `Query complexity ${cost} exceeds maximum allowed complexity of 1000`,
801
+ });
802
+
803
+ const server = new ApolloServer({
804
+ typeDefs,
805
+ resolvers,
806
+ validationRules: [depthLimit(7), ComplexityLimit],
807
+ });
808
+ ```
809
+
810
+ ### Persisted Queries
811
+
812
+ Lock down the API to only allow pre-registered queries in production.
813
+
814
+ ```typescript
815
+ import { ApolloServerPluginPersistedQueries } from "@apollo/server";
816
+
817
+ const server = new ApolloServer({
818
+ typeDefs,
819
+ resolvers,
820
+ plugins: [
821
+ ApolloServerPluginPersistedQueries({
822
+ // Only allow persisted queries in production
823
+ ...(process.env.NODE_ENV === "production" && {
824
+ rejectUnpersistedQueries: true,
825
+ }),
826
+ }),
827
+ ],
828
+ });
829
+ ```
830
+
831
+ ---
832
+
833
+ ## 13. Testing
834
+
835
+ ### Resolver Unit Tests
836
+
837
+ ```typescript
838
+ import { describe, it, expect, vi } from "vitest";
839
+ import { resolvers } from "./resolvers";
840
+
841
+ describe("Query.user", () => {
842
+ it("returns user by ID", async () => {
843
+ const mockUser = { id: "1", name: "Alice", email: "alice@example.com" };
844
+ const context = {
845
+ dataSources: {
846
+ users: { findById: vi.fn().mockResolvedValue(mockUser) },
847
+ },
848
+ };
849
+
850
+ const result = await resolvers.Query.user(null, { id: "1" }, context, {} as any);
851
+ expect(result).toEqual(mockUser);
852
+ expect(context.dataSources.users.findById).toHaveBeenCalledWith("1");
853
+ });
854
+
855
+ it("returns null for non-existent user", async () => {
856
+ const context = {
857
+ dataSources: {
858
+ users: { findById: vi.fn().mockResolvedValue(null) },
859
+ },
860
+ };
861
+
862
+ const result = await resolvers.Query.user(null, { id: "999" }, context, {} as any);
863
+ expect(result).toBeNull();
864
+ });
865
+ });
866
+ ```
867
+
868
+ ### Integration Tests with Apollo Server
869
+
870
+ ```typescript
871
+ import { ApolloServer } from "@apollo/server";
872
+ import { describe, it, expect, beforeAll } from "vitest";
873
+
874
+ describe("GraphQL API", () => {
875
+ let server: ApolloServer;
876
+
877
+ beforeAll(async () => {
878
+ server = new ApolloServer({ typeDefs, resolvers });
879
+ await server.start();
880
+ });
881
+
882
+ it("fetches a user with posts", async () => {
883
+ const response = await server.executeOperation({
884
+ query: `
885
+ query GetUser($id: ID!) {
886
+ user(id: $id) {
887
+ id
888
+ name
889
+ posts(first: 5) {
890
+ edges {
891
+ node {
892
+ title
893
+ }
894
+ }
895
+ }
896
+ }
897
+ }
898
+ `,
899
+ variables: { id: "1" },
900
+ });
901
+
902
+ expect(response.body.kind).toBe("single");
903
+ if (response.body.kind === "single") {
904
+ expect(response.body.singleResult.errors).toBeUndefined();
905
+ expect(response.body.singleResult.data?.user?.name).toBeDefined();
906
+ }
907
+ });
908
+
909
+ it("returns error for unauthenticated mutation", async () => {
910
+ const response = await server.executeOperation({
911
+ query: `
912
+ mutation {
913
+ createPost(input: { title: "Test", content: "Body" }) {
914
+ post { id }
915
+ errors { message code }
916
+ }
917
+ }
918
+ `,
919
+ });
920
+
921
+ if (response.body.kind === "single") {
922
+ const payload = response.body.singleResult.data?.createPost;
923
+ expect(payload.post).toBeNull();
924
+ expect(payload.errors[0].code).toBe("UNAUTHENTICATED");
925
+ }
926
+ });
927
+ });
928
+ ```
929
+
930
+ ---
931
+
932
+ ## 14. Code Generation
933
+
934
+ ### graphql-codegen Setup
935
+
936
+ ```yaml
937
+ # codegen.ts
938
+ import type { CodegenConfig } from "@graphql-codegen/cli";
939
+
940
+ const config: CodegenConfig = {
941
+ schema: "./src/schema.graphql",
942
+ documents: "./src/**/*.graphql",
943
+ generates: {
944
+ # Server-side types
945
+ "./src/generated/graphql.ts": {
946
+ plugins: [
947
+ "typescript",
948
+ "typescript-resolvers",
949
+ ],
950
+ config: {
951
+ contextType: "../context#Context",
952
+ mapperTypeSuffix: "Model",
953
+ mappers: {
954
+ User: "../models/user#UserModel",
955
+ Post: "../models/post#PostModel",
956
+ },
957
+ },
958
+ },
959
+ # Client-side types and hooks
960
+ "./src/generated/client.ts": {
961
+ plugins: [
962
+ "typescript",
963
+ "typescript-operations",
964
+ "typescript-react-apollo",
965
+ ],
966
+ config: {
967
+ withHooks: true,
968
+ withComponent: false,
969
+ },
970
+ },
971
+ },
972
+ };
973
+
974
+ export default config;
975
+ ```
976
+
977
+ ```bash
978
+ # Run codegen
979
+ npx graphql-codegen
980
+
981
+ # Watch mode
982
+ npx graphql-codegen --watch
983
+ ```
984
+
985
+ ### Using Generated Types
986
+
987
+ ```typescript
988
+ // Server -- resolvers are fully typed
989
+ import type { Resolvers } from "./generated/graphql";
990
+
991
+ const resolvers: Resolvers = {
992
+ Query: {
993
+ // TypeScript enforces correct return types and argument types
994
+ user: async (_parent, { id }, context) => {
995
+ return context.dataSources.users.findById(id);
996
+ },
997
+ },
998
+ };
999
+
1000
+ // Client -- hooks are fully typed
1001
+ import { useGetUserQuery } from "./generated/client";
1002
+
1003
+ function UserProfile({ userId }: { userId: string }) {
1004
+ // data is typed as GetUserQuery
1005
+ const { data, loading, error } = useGetUserQuery({
1006
+ variables: { id: userId },
1007
+ });
1008
+
1009
+ if (loading) return <Spinner />;
1010
+ if (error) return <Error message={error.message} />;
1011
+ // data.user is fully typed
1012
+ return <div>{data?.user?.name}</div>;
1013
+ }
1014
+ ```
1015
+
1016
+ ---
1017
+
1018
+ ## 15. Anti-Patterns
1019
+
1020
+ ### NEVER
1021
+
1022
+ - Expose database models directly as GraphQL types -- create separate GraphQL types
1023
+ - Return raw database errors to clients -- wrap them in user-friendly messages
1024
+ - Skip DataLoader -- every relationship resolver must use batching
1025
+ - Allow unlimited query depth or complexity -- enforce limits
1026
+ - Use REST-style naming (`getUser`, `listPosts`) -- use `user`, `posts`
1027
+ - Put business logic in resolvers -- resolvers orchestrate, services compute
1028
+ - Ignore nullability -- every field should be explicitly nullable or non-nullable
1029
+ - Use `ID` type for non-identifier fields -- `ID` is for unique identifiers only
1030
+ - Return different shapes for the same error in different mutations
1031
+ - Skip input validation because "the schema handles types"
1032
+
1033
+ ### ALWAYS
1034
+
1035
+ - Use input types for mutation arguments
1036
+ - Return payload types from mutations (not raw entities)
1037
+ - Implement cursor-based pagination for list fields
1038
+ - Use DataLoader for all relationship fields
1039
+ - Generate TypeScript types from the schema
1040
+ - Version your API through schema evolution, not URL versioning
1041
+ - Document deprecated fields with `@deprecated(reason: "...")` before removal
1042
+ - Set cache hints on resolvers that return public data
1043
+ - Test both happy paths and error paths in resolver tests
1044
+ - Validate inputs beyond what the schema enforces (string length, format, business rules)
1045
+
1046
+ ---
1047
+
1048
+ ## 16. Schema Design Checklist
1049
+
1050
+ Before shipping a new type or field:
1051
+
1052
+ - [ ] All fields have explicit nullability (`!` for non-nullable)
1053
+ - [ ] List fields use pagination (not unbounded arrays)
1054
+ - [ ] Mutations return payload types with an `errors` field
1055
+ - [ ] Input types are used for all mutation arguments
1056
+ - [ ] Relationships use DataLoader in resolvers
1057
+ - [ ] Depth and complexity limits are configured
1058
+ - [ ] Generated types are up to date
1059
+ - [ ] Resolver tests cover happy path, error path, and auth
1060
+ - [ ] Schema documentation is written with descriptions
1061
+ - [ ] Deprecated fields have migration paths documented