@caddis/cli 0.1.0 → 0.2.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 (364) hide show
  1. package/README.md +29 -16
  2. package/bundles/antigravity-plugin-extras/plugin.json +5 -0
  3. package/bundles/antigravity-plugin-extras/skills/_registry.md +154 -0
  4. package/bundles/antigravity-plugin-extras/skills/agent-md-refactor/SKILL.md +356 -0
  5. package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +517 -0
  6. package/bundles/antigravity-plugin-extras/skills/algorithmic-art/SKILL.md +293 -0
  7. package/bundles/antigravity-plugin-extras/skills/anchor-review/SKILL.md +135 -0
  8. package/bundles/antigravity-plugin-extras/skills/api-client-patterns/SKILL.md +367 -0
  9. package/bundles/antigravity-plugin-extras/skills/architecture-design/SKILL.md +244 -0
  10. package/bundles/antigravity-plugin-extras/skills/architecture-diagram/SKILL.md +156 -0
  11. package/bundles/antigravity-plugin-extras/skills/architecture-document/SKILL.md +321 -0
  12. package/bundles/antigravity-plugin-extras/skills/artifacts-builder/LICENSE.txt +202 -0
  13. package/bundles/antigravity-plugin-extras/skills/artifacts-builder/SKILL.md +74 -0
  14. package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  15. package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
  16. package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  17. package/bundles/antigravity-plugin-extras/skills/ascii-art/SKILL.md +144 -0
  18. package/bundles/antigravity-plugin-extras/skills/asking-questions/SKILL.md +81 -0
  19. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/SKILL.md +118 -0
  20. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/cross-service/credential-management.md +450 -0
  21. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/browser/README.md +363 -0
  22. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/code-interpreter/README.md +232 -0
  23. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/README.md +100 -0
  24. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/deploy-template.sh +117 -0
  25. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/deployment-strategies.md +416 -0
  26. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/troubleshooting-guide.md +384 -0
  27. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/validate-deployment.sh +186 -0
  28. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/identity/README.md +186 -0
  29. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/memory/README.md +253 -0
  30. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/observability/README.md +517 -0
  31. package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/runtime/README.md +215 -0
  32. package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/SKILL.md +279 -0
  33. package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/references/cdk-patterns.md +431 -0
  34. package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/scripts/validate-stack.sh +240 -0
  35. package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/SKILL.md +318 -0
  36. package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/references/cloudwatch-alarms.md +567 -0
  37. package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/references/operations-patterns.md +394 -0
  38. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/SKILL.md +758 -0
  39. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/deployment-best-practices.md +830 -0
  40. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/eda-patterns.md +1002 -0
  41. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/observability-best-practices.md +770 -0
  42. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/performance-optimization.md +671 -0
  43. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/security-best-practices.md +625 -0
  44. package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/serverless-patterns.md +838 -0
  45. package/bundles/antigravity-plugin-extras/skills/backend-to-frontend-handoff/SKILL.md +139 -0
  46. package/bundles/antigravity-plugin-extras/skills/banner-design/SKILL.md +188 -0
  47. package/bundles/antigravity-plugin-extras/skills/brand-design/SKILL.md +298 -0
  48. package/bundles/antigravity-plugin-extras/skills/brand-guidelines/LICENSE.txt +202 -0
  49. package/bundles/antigravity-plugin-extras/skills/brand-guidelines/SKILL.md +118 -0
  50. package/bundles/antigravity-plugin-extras/skills/brand-voice/SKILL.md +93 -0
  51. package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/SKILL.md +392 -0
  52. package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/agent-patterns.md +461 -0
  53. package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/examples.md +188 -0
  54. package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/state-patterns.md +360 -0
  55. package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/troubleshooting.md +362 -0
  56. package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/SKILL.md +266 -0
  57. package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/examples.md +115 -0
  58. package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/oauth-setup.md +338 -0
  59. package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/troubleshooting.md +317 -0
  60. package/bundles/antigravity-plugin-extras/skills/caching-patterns/SKILL.md +385 -0
  61. package/bundles/antigravity-plugin-extras/skills/canvas-design/LICENSE.txt +202 -0
  62. package/bundles/antigravity-plugin-extras/skills/canvas-design/SKILL.md +91 -0
  63. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  64. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  65. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  66. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
  67. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  68. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
  69. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  70. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  71. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  72. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  73. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  74. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  75. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  76. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  77. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
  78. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  79. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
  80. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  81. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  82. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
  83. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  84. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
  85. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  86. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  87. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  88. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  89. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  90. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  91. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  92. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  93. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  94. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  95. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  96. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  97. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  98. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  99. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  100. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
  101. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  102. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  103. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  104. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  105. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  106. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  107. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
  108. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  109. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  110. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  111. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  112. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  113. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
  114. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  115. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  116. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
  117. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  118. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  119. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  120. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  121. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
  122. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  123. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  124. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
  125. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
  126. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  127. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  128. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
  129. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  130. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
  131. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  132. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  133. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
  134. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  135. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
  136. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  137. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  138. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  139. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  140. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
  141. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  142. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
  143. package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  144. package/bundles/antigravity-plugin-extras/skills/changelog-generator/SKILL.md +105 -0
  145. package/bundles/antigravity-plugin-extras/skills/code-explainer/SKILL.md +91 -0
  146. package/bundles/antigravity-plugin-extras/skills/competitive-ads-extractor/SKILL.md +294 -0
  147. package/bundles/antigravity-plugin-extras/skills/component-testing/SKILL.md +310 -0
  148. package/bundles/antigravity-plugin-extras/skills/content-research-writer/SKILL.md +539 -0
  149. package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +51 -0
  150. package/bundles/antigravity-plugin-extras/skills/data-analysis/SKILL.md +111 -0
  151. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/README.md +248 -0
  152. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/SKILL.md +203 -0
  153. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/adapter.py.template +44 -0
  154. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/api-router.py.template +43 -0
  155. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/contract-test.py.template +384 -0
  156. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/display-dto.py.template +39 -0
  157. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/frontend-service.ts.template +46 -0
  158. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/frontend-types.ts.template +38 -0
  159. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/ingestion-model.py.template +42 -0
  160. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/mapping-doc.md.template +46 -0
  161. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/normalizer.py.template +48 -0
  162. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/extract_requirements.md +36 -0
  163. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/extract_ui_demand.md +35 -0
  164. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/reconcile_mapping.md +66 -0
  165. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/query-catalog.md.template +62 -0
  166. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/consumer-driven-contracts.md +131 -0
  167. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/drift-check-catalog.md +305 -0
  168. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/layer-responsibilities.md +333 -0
  169. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/discover_connections.py +170 -0
  170. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/discover_sources.py +161 -0
  171. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/drift_check.py +171 -0
  172. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/extract_schema.py +1363 -0
  173. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/generate_gap_report.py +81 -0
  174. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/generate_mapping_doc.py +294 -0
  175. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/ts_dto_compare.py +214 -0
  176. package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/validate_lineage.py +51 -0
  177. package/bundles/antigravity-plugin-extras/skills/data-loader/SKILL.md +753 -0
  178. package/bundles/antigravity-plugin-extras/skills/data-validation/SKILL.md +220 -0
  179. package/bundles/antigravity-plugin-extras/skills/db-testing/SKILL.md +117 -0
  180. package/bundles/antigravity-plugin-extras/skills/deploy-local/SKILL.md +259 -0
  181. package/bundles/antigravity-plugin-extras/skills/design-md/SKILL.md +167 -0
  182. package/bundles/antigravity-plugin-extras/skills/design-system-tokens/SKILL.md +240 -0
  183. package/bundles/antigravity-plugin-extras/skills/design-system-tokens/references/DESIGN-SYSTEM-TEMPLATE.md +577 -0
  184. package/bundles/antigravity-plugin-extras/skills/developer-growth-analysis/SKILL.md +323 -0
  185. package/bundles/antigravity-plugin-extras/skills/doc-coauthoring/SKILL.md +378 -0
  186. package/bundles/antigravity-plugin-extras/skills/documentation-analyzer/SKILL.md +78 -0
  187. package/bundles/antigravity-plugin-extras/skills/domain-name-brainstormer/SKILL.md +213 -0
  188. package/bundles/antigravity-plugin-extras/skills/enterprise-dashboard-aesthetic-system/SKILL.md +120 -0
  189. package/bundles/antigravity-plugin-extras/skills/excalidraw/SKILL.md +193 -0
  190. package/bundles/antigravity-plugin-extras/skills/excalidraw/references/element-types.md +497 -0
  191. package/bundles/antigravity-plugin-extras/skills/excalidraw/references/excalidraw-schema.md +356 -0
  192. package/bundles/antigravity-plugin-extras/skills/excalidraw/references/reliable-diagrams.md +115 -0
  193. package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/README.md +60 -0
  194. package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/add-arrow.py +354 -0
  195. package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/add-icon-to-diagram.py +412 -0
  196. package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/split-excalidraw-library.py +183 -0
  197. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/business-flow-swimlane-template.excalidraw +334 -0
  198. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/class-diagram-template.excalidraw +558 -0
  199. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/data-flow-diagram-template.excalidraw +279 -0
  200. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/er-diagram-template.excalidraw +662 -0
  201. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/flowchart-template.excalidraw +179 -0
  202. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/mindmap-template.excalidraw +244 -0
  203. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/relationship-template.excalidraw +145 -0
  204. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/reliable-flowchart.excalidraw +1 -0
  205. package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/sequence-diagram-template.excalidraw +509 -0
  206. package/bundles/antigravity-plugin-extras/skills/file-organizer/SKILL.md +434 -0
  207. package/bundles/antigravity-plugin-extras/skills/game-changing-features/README.md +221 -0
  208. package/bundles/antigravity-plugin-extras/skills/game-changing-features/SKILL.md +265 -0
  209. package/bundles/antigravity-plugin-extras/skills/github-issues/SKILL.md +359 -0
  210. package/bundles/antigravity-plugin-extras/skills/github-issues/references/templates.md +90 -0
  211. package/bundles/antigravity-plugin-extras/skills/golden-nuggets/SKILL.md +192 -0
  212. package/bundles/antigravity-plugin-extras/skills/humanizer/SKILL.md +194 -0
  213. package/bundles/antigravity-plugin-extras/skills/image-enhancer/SKILL.md +100 -0
  214. package/bundles/antigravity-plugin-extras/skills/intent-writer/SKILL.md +201 -0
  215. package/bundles/antigravity-plugin-extras/skills/internal-comms/LICENSE.txt +202 -0
  216. package/bundles/antigravity-plugin-extras/skills/internal-comms/SKILL.md +124 -0
  217. package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/3p-updates.md +47 -0
  218. package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/company-newsletter.md +65 -0
  219. package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/faq-answers.md +30 -0
  220. package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/general-comms.md +16 -0
  221. package/bundles/antigravity-plugin-extras/skills/invoice-organizer/SKILL.md +447 -0
  222. package/bundles/antigravity-plugin-extras/skills/jira-issues/SKILL.md +182 -0
  223. package/bundles/antigravity-plugin-extras/skills/job-application/SKILL.md +188 -0
  224. package/bundles/antigravity-plugin-extras/skills/lead-research-assistant/SKILL.md +200 -0
  225. package/bundles/antigravity-plugin-extras/skills/llm-application-dev/SKILL.md +217 -0
  226. package/bundles/antigravity-plugin-extras/skills/mcp-builder/LICENSE.txt +202 -0
  227. package/bundles/antigravity-plugin-extras/skills/mcp-builder/SKILL.md +100 -0
  228. package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/evaluation.md +602 -0
  229. package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/mcp_best_practices.md +915 -0
  230. package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/node_mcp_server.md +916 -0
  231. package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/python_mcp_server.md +752 -0
  232. package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/connections.py +151 -0
  233. package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/evaluation.py +373 -0
  234. package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  235. package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/requirements.txt +2 -0
  236. package/bundles/antigravity-plugin-extras/skills/meeting-insights-analyzer/SKILL.md +328 -0
  237. package/bundles/antigravity-plugin-extras/skills/monorepo/SKILL.md +267 -0
  238. package/bundles/antigravity-plugin-extras/skills/naming-analyzer/SKILL.md +376 -0
  239. package/bundles/antigravity-plugin-extras/skills/nextjs-app-router/SKILL.md +271 -0
  240. package/bundles/antigravity-plugin-extras/skills/notebooklm/AUTHENTICATION.md +154 -0
  241. package/bundles/antigravity-plugin-extras/skills/notebooklm/SKILL.md +270 -0
  242. package/bundles/antigravity-plugin-extras/skills/notebooklm/references/api_reference.md +309 -0
  243. package/bundles/antigravity-plugin-extras/skills/notebooklm/references/troubleshooting.md +376 -0
  244. package/bundles/antigravity-plugin-extras/skills/notebooklm/references/usage_patterns.md +338 -0
  245. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/__init__.py +81 -0
  246. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/ask_question.py +256 -0
  247. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/auth_manager.py +358 -0
  248. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/browser_session.py +255 -0
  249. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/browser_utils.py +107 -0
  250. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/cleanup_manager.py +302 -0
  251. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/config.py +44 -0
  252. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/notebook_manager.py +410 -0
  253. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/run.py +102 -0
  254. package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/setup_environment.py +204 -0
  255. package/bundles/antigravity-plugin-extras/skills/observability/SKILL.md +371 -0
  256. package/bundles/antigravity-plugin-extras/skills/onboard-project/SKILL.md +192 -0
  257. package/bundles/antigravity-plugin-extras/skills/performance-testing/SKILL.md +226 -0
  258. package/bundles/antigravity-plugin-extras/skills/pipeline-state/SKILL.md +208 -0
  259. package/bundles/antigravity-plugin-extras/skills/plantuml/SKILL.md +228 -0
  260. package/bundles/antigravity-plugin-extras/skills/popular-web-designs/SKILL.md +142 -0
  261. package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/linear.app.md +196 -0
  262. package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/stripe.md +214 -0
  263. package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/vercel.md +218 -0
  264. package/bundles/antigravity-plugin-extras/skills/prd-to-code/SKILL.md +127 -0
  265. package/bundles/antigravity-plugin-extras/skills/raffle-winner-picker/SKILL.md +159 -0
  266. package/bundles/antigravity-plugin-extras/skills/react-useeffect/README.md +320 -0
  267. package/bundles/antigravity-plugin-extras/skills/react-useeffect/SKILL.md +53 -0
  268. package/bundles/antigravity-plugin-extras/skills/react-useeffect/alternatives.md +258 -0
  269. package/bundles/antigravity-plugin-extras/skills/react-useeffect/anti-patterns.md +290 -0
  270. package/bundles/antigravity-plugin-extras/skills/receiving-code-review/SKILL.md +213 -0
  271. package/bundles/antigravity-plugin-extras/skills/relay/SKILL.md +246 -0
  272. package/bundles/antigravity-plugin-extras/skills/requesting-code-review/SKILL.md +105 -0
  273. package/bundles/antigravity-plugin-extras/skills/requesting-code-review/code-reviewer.md +146 -0
  274. package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/SKILL.md +350 -0
  275. package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/pwa-checklist.md +226 -0
  276. package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/touch-and-interaction.md +265 -0
  277. package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/transformation-catalogue.md +326 -0
  278. package/bundles/antigravity-plugin-extras/skills/schema-migration/SKILL.md +275 -0
  279. package/bundles/antigravity-plugin-extras/skills/setup-project-ai/SKILL.md +120 -0
  280. package/bundles/antigravity-plugin-extras/skills/shadcn-radix/SKILL.md +330 -0
  281. package/bundles/antigravity-plugin-extras/skills/sketch/SKILL.md +104 -0
  282. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/LICENSE.txt +202 -0
  283. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/SKILL.md +646 -0
  284. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/color_palettes.py +302 -0
  285. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/easing.py +230 -0
  286. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/frame_composer.py +469 -0
  287. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/gif_builder.py +246 -0
  288. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/typography.py +357 -0
  289. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/validators.py +264 -0
  290. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/visual_effects.py +494 -0
  291. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/requirements.txt +4 -0
  292. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/bounce.py +106 -0
  293. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/explode.py +331 -0
  294. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/fade.py +329 -0
  295. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/flip.py +291 -0
  296. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
  297. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/morph.py +329 -0
  298. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/move.py +293 -0
  299. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/pulse.py +268 -0
  300. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/shake.py +127 -0
  301. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/slide.py +291 -0
  302. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/spin.py +269 -0
  303. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/wiggle.py +300 -0
  304. package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/zoom.py +312 -0
  305. package/bundles/antigravity-plugin-extras/skills/slides/SKILL.md +38 -0
  306. package/bundles/antigravity-plugin-extras/skills/state-tracking/SKILL.md +131 -0
  307. package/bundles/antigravity-plugin-extras/skills/streamlit-dev/SKILL.md +268 -0
  308. package/bundles/antigravity-plugin-extras/skills/svg-create/SKILL.md +251 -0
  309. package/bundles/antigravity-plugin-extras/skills/theme-factory/LICENSE.txt +202 -0
  310. package/bundles/antigravity-plugin-extras/skills/theme-factory/SKILL.md +59 -0
  311. package/bundles/antigravity-plugin-extras/skills/theme-factory/theme-showcase.pdf +0 -0
  312. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/arctic-frost.md +19 -0
  313. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/botanical-garden.md +19 -0
  314. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/desert-rose.md +19 -0
  315. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/forest-canopy.md +19 -0
  316. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/golden-hour.md +19 -0
  317. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/midnight-galaxy.md +19 -0
  318. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/modern-minimalist.md +19 -0
  319. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/ocean-depths.md +19 -0
  320. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/sunset-boulevard.md +19 -0
  321. package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/tech-innovation.md +19 -0
  322. package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/LICENSE.txt +202 -0
  323. package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/SKILL.md +320 -0
  324. package/bundles/antigravity-plugin-extras/skills/ui-testing/SKILL.md +660 -0
  325. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/SKILL.md +660 -0
  326. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/_sync_all.py +414 -0
  327. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/app-interface.csv +31 -0
  328. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/charts.csv +26 -0
  329. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/colors.csv +162 -0
  330. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/design.csv +1776 -0
  331. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/draft.csv +1779 -0
  332. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/google-fonts.csv +1924 -0
  333. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/icons.csv +106 -0
  334. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/landing.csv +35 -0
  335. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/products.csv +162 -0
  336. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/react-performance.csv +45 -0
  337. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/styles.csv +85 -0
  338. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/typography.csv +74 -0
  339. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/ui-reasoning.csv +162 -0
  340. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/ux-guidelines.csv +100 -0
  341. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/core.py +247 -0
  342. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/design_system.py +1067 -0
  343. package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/search.py +114 -0
  344. package/bundles/antigravity-plugin-extras/skills/understand-anything/SKILL.md +140 -0
  345. package/bundles/antigravity-plugin-extras/skills/understand-anything/references/commands.md +252 -0
  346. package/bundles/antigravity-plugin-extras/skills/understand-anything/references/graph-schema.md +116 -0
  347. package/bundles/antigravity-plugin-extras/skills/understand-anything/references/pipeline.md +331 -0
  348. package/bundles/antigravity-plugin-extras/skills/update-readme/SKILL.md +74 -0
  349. package/bundles/antigravity-plugin-extras/skills/verification-loop/SKILL.md +209 -0
  350. package/bundles/antigravity-plugin-extras/skills/video-downloader/SKILL.md +107 -0
  351. package/bundles/antigravity-plugin-extras/skills/webapp-development/SKILL.md +288 -0
  352. package/bundles/antigravity-plugin-extras/skills/word-cloud/SKILL.md +339 -0
  353. package/bundles/antigravity-plugin-extras/skills/word-cloud/agents/agent-interface.md +175 -0
  354. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/html.md +384 -0
  355. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/nlp-keywords.md +127 -0
  356. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/palettes.md +149 -0
  357. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/python.md +249 -0
  358. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/react.md +427 -0
  359. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/shapes.md +135 -0
  360. package/bundles/antigravity-plugin-extras/skills/word-cloud/references/stopwords.md +115 -0
  361. package/bundles/antigravity-plugin-extras/skills/youtube-transcript/SKILL.md +416 -0
  362. package/bundles/manifest.json +2 -1
  363. package/dist/cli.js +166 -37
  364. package/package.json +1 -1
@@ -0,0 +1,333 @@
1
+ # Layer Responsibilities
2
+
3
+ Detailed specification for each layer in the data contract pipeline. When generating code for a layer, follow these rules exactly.
4
+
5
+ ---
6
+
7
+ ## Layer 1 — Source Adapter
8
+
9
+ **Location**: `src/services/adapters/` or `src/services/`
10
+ **Responsibility**: Fetch raw data from external source and return it as a Python dict or list.
11
+
12
+ ### Rules
13
+
14
+ - The adapter is the ONLY layer that knows about the source (file path, API URL, DB query)
15
+ - Returns raw `dict` / `list[dict]` — no Pydantic models, no transformations
16
+ - Handles connection errors, retries, and timeouts
17
+ - Logs the fetch operation (loguru, never print)
18
+ - Uses `pathlib.Path` for file paths, never hardcoded strings
19
+ - Environment-specific config (URLs, credentials) comes from `pydantic-settings`, never hardcoded
20
+
21
+ ### Template
22
+
23
+ ```python
24
+ from pathlib import Path
25
+ from loguru import logger
26
+
27
+ class {{SourceName}}Adapter:
28
+ """Fetches raw {{source_name}} data from {{source_type}}."""
29
+
30
+ def __init__(self, source_path: Path) -> None:
31
+ self._source_path = source_path
32
+
33
+ def fetch(self) -> dict:
34
+ """Load raw payload. Returns unvalidated dict."""
35
+ logger.debug(f"Fetching {{source_name}} from {self._source_path}")
36
+ # Source-specific fetch logic here
37
+ ...
38
+ ```
39
+
40
+ ### Anti-patterns
41
+
42
+ - ❌ Adapter validates or transforms data (that's the normalizer's job)
43
+ - ❌ Adapter returns a Pydantic model (that couples adapter to schema)
44
+ - ❌ Adapter catches and silently swallows errors
45
+
46
+ ---
47
+
48
+ ## Layer 2 — Ingestion Model
49
+
50
+ **Location**: `src/models/ingestion/`
51
+ **Responsibility**: Pydantic model that matches the raw source payload shape exactly (1:1).
52
+
53
+ ### Rules
54
+
55
+ - Every key in the source payload MUST have a corresponding field
56
+ - Field types match the source data types (str, int, float, list, dict, None)
57
+ - Use `Optional[T]` for keys that may be null or absent in some payloads
58
+ - Use `Field(alias=...)` only if the source key name is not valid Python (e.g., contains spaces or special chars)
59
+ - Use `extra="allow"` during initial development to catch unexpected keys
60
+ - Nested objects get their own ingestion model
61
+ - This model is NOT the API response — it exists to validate raw data
62
+ - **Share a `_FLEX` config constant** across all ingest DTOs so the `extra="allow"` policy is centralized
63
+
64
+ ### Template
65
+
66
+ ```python
67
+ from pydantic import BaseModel, ConfigDict, Field
68
+
69
+ # Shared config for all data-ingest DTOs. extra="allow" means unknown keys
70
+ # land in model_extra and flow through — nothing is silently dropped.
71
+ _FLEX = ConfigDict(populate_by_name=True, extra="allow")
72
+
73
+
74
+ class {{SourceName}}Payload(BaseModel):
75
+ """1:1 representation of raw {{source_name}} payload."""
76
+ model_config = _FLEX
77
+
78
+ {{field_name}}: {{raw_type}}
79
+ # ... one field per source key
80
+ ```
81
+
82
+ ### Anti-patterns
83
+
84
+ - ❌ Dropping fields that "aren't needed yet" (breaks contract completeness)
85
+ - ❌ Applying business logic (renaming, computing, filtering)
86
+ - ❌ Using `extra="ignore"` (hides new source fields)
87
+ - ❌ Declaring `ConfigDict(extra="allow")` inline on every model instead of sharing a `_FLEX` constant
88
+
89
+ ---
90
+
91
+ ## Layer 3 — Normalizer
92
+
93
+ **Location**: `src/services/normalizers/`
94
+ **Responsibility**: Transform ingestion model into display DTO. This is where business logic lives.
95
+
96
+ ### Rules
97
+
98
+ - Input: ingestion model instance. Output: display DTO instance
99
+ - Handles field renaming, unit conversion, computed fields, filtering
100
+ - Every transformation is explicit — no implicit field passing
101
+ - Pure function where possible (no side effects, no DB calls)
102
+ - If a field is intentionally dropped, document WHY with a comment
103
+
104
+ ### Template
105
+
106
+ ```python
107
+ from src.models.ingestion.{{source_slug}} import {{SourceName}}Payload
108
+ from src.models.responses.{{source_slug}} import {{DtoName}}
109
+
110
+ def normalize_{{source_slug}}(raw: {{SourceName}}Payload) -> {{DtoName}}:
111
+ """Transform raw {{source_name}} payload into display DTO."""
112
+ return {{DtoName}}(
113
+ {{dto_field}}=raw.{{source_field}},
114
+ # Computed fields
115
+ {{computed_field}}=_compute_{{computed_field}}(raw),
116
+ )
117
+ ```
118
+
119
+ ### Anti-patterns
120
+
121
+ - ❌ Normalizer fetches data (that's the adapter's job)
122
+ - ❌ Normalizer returns dict instead of DTO (loses type safety)
123
+ - ❌ Implicit field dropping without documentation
124
+
125
+ ---
126
+
127
+ ## Layer 4 — Display DTO
128
+
129
+ **Location**: `src/models/responses/`
130
+ **Responsibility**: Frozen Pydantic model defining the API boundary contract.
131
+
132
+ ### Rules
133
+
134
+ - `frozen=True` — immutable after construction
135
+ - `populate_by_name=True` — can construct with Python names or aliases
136
+ - `extra="forbid"` — no silent data loss (use "allow" only during migration, with logging)
137
+ - `Field(alias="camelCaseName")` for every field exposed to frontend
138
+ - All fields have type annotations
139
+ - Optional fields have explicit defaults (`Field(default_factory=list)`)
140
+ - This is the API contract — changes here require frontend coordination
141
+
142
+ ### Template
143
+
144
+ ```python
145
+ from pydantic import BaseModel, ConfigDict, Field
146
+
147
+ class {{DtoName}}(BaseModel):
148
+ """API response DTO for {{source_name}}."""
149
+ model_config = ConfigDict(
150
+ frozen=True,
151
+ populate_by_name=True,
152
+ extra="forbid",
153
+ )
154
+
155
+ {{field_name}}: {{python_type}} = Field(alias="{{camelCaseName}}")
156
+ ```
157
+
158
+ ### Anti-patterns
159
+
160
+ - ❌ `extra="ignore"` — silently drops fields, causes data loss bugs
161
+ - ❌ Mutable DTO — allows post-construction tampering
162
+ - ❌ Missing aliases — forces frontend to use snake_case
163
+ - ❌ Any field — loses type safety at the API boundary
164
+
165
+ ---
166
+
167
+ ## Layer 5 — API Router
168
+
169
+ **Location**: `src/api/routers/`
170
+ **Responsibility**: FastAPI endpoint that returns typed `response_model`.
171
+
172
+ ### Rules
173
+
174
+ - Always set `response_model=DtoName` on the endpoint
175
+ - Router calls service layer, never adapter or repository directly
176
+ - Returns DTO instance, not dict
177
+ - Error handling returns structured error responses, not stack traces
178
+ - Follows REST conventions for path naming
179
+
180
+ ### Template
181
+
182
+ ```python
183
+ from fastapi import APIRouter, Depends
184
+ from src.models.responses.{{source_slug}} import {{DtoName}}
185
+ from src.services.{{source_slug}}_service import get_{{source_slug}}
186
+
187
+ router = APIRouter(prefix="/api/{{source-slug}}", tags=["{{source_name}}"])
188
+
189
+ @router.get("/", response_model={{DtoName}})
190
+ async def get_data(
191
+ # query params here
192
+ ):
193
+ """Get {{source_name}} data."""
194
+ return await get_{{source_slug}}()
195
+ ```
196
+
197
+ ### Anti-patterns
198
+
199
+ - ❌ No `response_model` — FastAPI can't validate the response shape
200
+ - ❌ Returning raw dict — bypasses DTO validation
201
+ - ❌ Business logic in router — should be in service layer
202
+
203
+ ---
204
+
205
+ ## Layer 6 — Frontend Types
206
+
207
+ **Location**: `frontend/src/types/`
208
+ **Responsibility**: TypeScript interfaces that mirror the display DTO.
209
+
210
+ ### Rules
211
+
212
+ - One interface per DTO, field names match DTO aliases (camelCase)
213
+ - Use strict TypeScript types — no `any`
214
+ - Nested objects get their own interface
215
+ - Export from a barrel file (`index.ts`) for clean imports
216
+ - When DTO changes, TypeScript interface changes in the same PR
217
+
218
+ ### Template
219
+
220
+ ```typescript
221
+ export interface {{DtoName}} {
222
+ {{camelCaseName}}: {{tsType}};
223
+ }
224
+ ```
225
+
226
+ ### Type Mapping
227
+
228
+ | Python Type | TypeScript Type |
229
+ |------------|----------------|
230
+ | `str` | `string` |
231
+ | `int`, `float` | `number` |
232
+ | `bool` | `boolean` |
233
+ | `list[T]` | `T[]` |
234
+ | `dict[str, T]` | `Record<string, T>` |
235
+ | `Optional[T]` | `T \| null` |
236
+ | `datetime` | `string` (ISO format) |
237
+ | `Decimal` | `number` |
238
+
239
+ ---
240
+
241
+ ## Layer 7 — Frontend Service
242
+
243
+ **Location**: `frontend/src/services/`
244
+ **Responsibility**: Typed fetch/axios functions that call the API and return typed data.
245
+
246
+ ### Rules
247
+
248
+ - Every function has a return type matching the TypeScript interface
249
+ - Base URL from environment config, never hardcoded
250
+ - Error handling with typed error responses
251
+ - Uses the project's HTTP client (axios, fetch, React Query, etc.)
252
+
253
+ ### Template
254
+
255
+ ```typescript
256
+ import type { {{DtoName}} } from '@/types/{{source-slug}}';
257
+ import { apiClient } from '@/lib/api-client';
258
+
259
+ export async function get{{DtoName}}(): Promise<{{DtoName}}> {
260
+ const { data } = await apiClient.get<{{DtoName}}>('/api/{{source-slug}}');
261
+ return data;
262
+ }
263
+ ```
264
+
265
+ ### Anti-patterns
266
+
267
+ - ❌ `any` return type — loses type safety
268
+ - ❌ Raw `fetch()` without error handling
269
+ - ❌ Hardcoded API URL
270
+
271
+ ---
272
+
273
+ ## Layer 8 — Contract Tests
274
+
275
+ **Location**: `tests/unit/test_contract_*.py`
276
+ **Responsibility**: Validate alignment between layers using golden sample payloads.
277
+
278
+ ### Rules
279
+
280
+ - At minimum: payload → DTO validation, uncovered keys check
281
+ - Tests run fast (no network, no database)
282
+ - Tests use golden sample from `tests/fixtures/payloads/`
283
+ - Each data source gets its own test file
284
+ - Test names describe what contract they validate
285
+
286
+ ### Test Categories
287
+
288
+ 1. **Structural**: Does the payload parse into the DTO?
289
+ 2. **Coverage**: Does the DTO cover all payload keys?
290
+ 3. **Alias**: Do aliases match the camelCase keys the frontend expects?
291
+ 4. **Optional**: Do fields with defaults handle absent keys?
292
+ 5. **Cross-layer**: Do TypeScript interface properties match DTO aliases?
293
+
294
+ See [drift-check-catalog.md](./drift-check-catalog.md) for the complete check list.
295
+
296
+ ---
297
+
298
+ ## Schema Evolution Lifecycle
299
+
300
+ Data pipelines rarely start with a frozen schema. This lifecycle describes how the three-layer defence adapts as the upstream schema matures.
301
+
302
+ ### Three-Layer Defence Summary
303
+
304
+ | Layer | Mechanism | Purpose |
305
+ |-------|-----------|----------|
306
+ | **1 — Passthrough** | `extra="allow"` on all ingest DTOs (`_FLEX`) | Unknown keys flow through `model_extra` instead of being silently dropped |
307
+ | **2 — Drift detection** | Recursive `_collect_dropped_keys()` in contract tests | Compares raw JSON keys vs DTO field aliases at every nesting depth |
308
+ | **3 — Exclusion allow-list** | `KNOWN_EXCLUDED_KEYS` dict with fnmatch globs | Intentionally untyped keys don't pollute drift reports |
309
+
310
+ ### Workflow by Schema State
311
+
312
+ | Pipeline state | `extra=` config | Drift test mode | Action |
313
+ |---|---|---|---|
314
+ | **Schema evolving daily** | `extra="allow"` (`_FLEX`) | Soft warning — `warnings.warn()`, CI passes | New keys flow through `model_extra`; drift reports show untyped keys as non-blocking warnings |
315
+ | **Schema stabilised / frozen** | `extra="forbid"` on display DTO; `extra="allow"` on ingest if you want to catch new keys | Hard assert — `assert dropped == []`, CI blocks | Type all remaining `model_extra` keys; set `CONTRACT_SCHEMA_FROZEN=1` (preferred), or `_contract_state.json` (`{"schema_frozen": true}`), or rely on CI fallback |
316
+ | **Key intentionally untyped** | n/a | Both modes | Add to `KNOWN_EXCLUDED_KEYS` with fnmatch glob + ticket ref; key is silently excluded from drift detection |
317
+
318
+ ### Decision Checklist for New JSON Keys
319
+
320
+ 1. **Is the key in every payload?** → Add typed field to the DTO now.
321
+ 2. **Is it experimental / may be removed?** → Leave untyped; `extra="allow"` forwards it. Add to `KNOWN_EXCLUDED_KEYS` if the warning is noisy.
322
+ 3. **Is it deprecated upstream?** → Add to `KNOWN_EXCLUDED_KEYS` permanently with ticket ref.
323
+ 4. **Is the schema frozen?** → Switch drift test to hard assert via precedence: `CONTRACT_SCHEMA_FROZEN=1` (preferred), then `_contract_state.json`, then CI fallback. Any new untyped key is a CI failure.
324
+
325
+ ### Anti-Patterns
326
+
327
+ | Anti-pattern | Why it fails | Correct approach |
328
+ |---|---|---|
329
+ | `extra='ignore'` on ingest DTOs | Silently drops evolving fields | `extra='allow'` — data flows through |
330
+ | Shape-only tests (`len(surveys) == 3`) | Pass even when half the fields are dropped | Recursive key-vs-field comparison |
331
+ | Hardcoded expected-key lists in tests | Stale within a week | Read actual JSON files, compare dynamically |
332
+ | One giant DTO with all fields optional | No validation, no IDE support | Nested models with required + optional typed fields |
333
+ | `model_dump(exclude_unset=True)` to hide extras | Hides the problem, doesn’t fix it | Let `model_extra` flow through; type when ready |
@@ -0,0 +1,170 @@
1
+ """Discover connection configuration in an app repository.
2
+
3
+ This script scans common config files for DB/API/file connection hints and
4
+ emits a masked connection_manifest.json. It never prints secret values.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import argparse
10
+ import json
11
+ import re
12
+ from dataclasses import asdict, dataclass
13
+ from datetime import datetime, timezone
14
+ from pathlib import Path
15
+
16
+
17
+ SECRET_RE = re.compile(
18
+ r"(password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key)",
19
+ re.IGNORECASE,
20
+ )
21
+ KEY_VALUE_RE = re.compile(r"^\s*([A-Z0-9_.-]+)\s*[:=]\s*(.+?)\s*$", re.IGNORECASE)
22
+ CONNECTION_KEYS = (
23
+ "DB_",
24
+ "DATABASE",
25
+ "SQL",
26
+ "MSSQL",
27
+ "POSTGRES",
28
+ "MYSQL",
29
+ "ODBC",
30
+ "JDBC",
31
+ "CONNECTION",
32
+ "API_",
33
+ "FILE_",
34
+ )
35
+ DEFAULT_SUFFIXES = {".ini", ".toml", ".yaml", ".yml", ".json", ".config"}
36
+ CONFIG_NAME_HINTS = (
37
+ ".env",
38
+ "settings",
39
+ "config",
40
+ "docker-compose",
41
+ "compose",
42
+ "alembic",
43
+ "database",
44
+ "connection",
45
+ "deploy",
46
+ "deployment",
47
+ "readme",
48
+ "runbook",
49
+ )
50
+ SKIP_DIRS = {
51
+ ".git",
52
+ ".venv",
53
+ "venv",
54
+ "env",
55
+ "node_modules",
56
+ "dist",
57
+ "build",
58
+ "__pycache__",
59
+ ".next",
60
+ ".turbo",
61
+ }
62
+
63
+
64
+ @dataclass
65
+ class ConnectionHint:
66
+ file: str
67
+ key: str
68
+ value: str
69
+ secret: bool
70
+
71
+
72
+ def is_candidate_file(path: Path) -> bool:
73
+ if any(part in SKIP_DIRS for part in path.parts):
74
+ return False
75
+ name = path.name.lower()
76
+ if any(hint in name for hint in CONFIG_NAME_HINTS):
77
+ return True
78
+ if path.suffix.lower() in DEFAULT_SUFFIXES:
79
+ return True
80
+ return False
81
+
82
+
83
+ def mask_value(key: str, value: str) -> tuple[str, bool]:
84
+ is_secret = bool(SECRET_RE.search(key))
85
+ if is_secret:
86
+ return "***", True
87
+ if SECRET_RE.search(value):
88
+ return re.sub(r"(?i)(pwd|password|token|secret)=([^;\\s]+)", r"\1=***", value), True
89
+ return value.strip().strip('"').strip("'"), False
90
+
91
+
92
+ def scan_file(path: Path, root: Path) -> list[ConnectionHint]:
93
+ hints: list[ConnectionHint] = []
94
+ try:
95
+ text = path.read_text(encoding="utf-8", errors="ignore")
96
+ except OSError:
97
+ return hints
98
+
99
+ for line in text.splitlines():
100
+ match = KEY_VALUE_RE.match(line)
101
+ if not match:
102
+ continue
103
+ key, raw_value = match.group(1), match.group(2)
104
+ if raw_value.strip() in {"(", "{", "["}:
105
+ continue
106
+ if not key.upper().startswith(CONNECTION_KEYS) and "CONNECTION" not in key.upper():
107
+ continue
108
+ value, secret = mask_value(key, raw_value)
109
+ hints.append(
110
+ ConnectionHint(
111
+ file=str(path.relative_to(root)),
112
+ key=key,
113
+ value=value,
114
+ secret=secret,
115
+ )
116
+ )
117
+ return hints
118
+
119
+
120
+ def infer_summary(hints: list[ConnectionHint]) -> dict[str, str]:
121
+ by_key = {h.key.upper(): h.value for h in hints if not h.secret}
122
+ return {
123
+ "host": by_key.get("DB_HOST") or by_key.get("DATABASE_HOST") or "",
124
+ "port": by_key.get("DB_PORT") or by_key.get("DATABASE_PORT") or "",
125
+ "database": by_key.get("DB_NAME") or by_key.get("DATABASE") or "",
126
+ "driver": by_key.get("DB_DRIVER") or by_key.get("ODBC_DRIVER") or "",
127
+ "auth_mode": (
128
+ "trusted"
129
+ if by_key.get("DB_TRUSTED_CONNECTION", "").lower() in {"yes", "true", "1"}
130
+ else "credential-or-unknown"
131
+ ),
132
+ }
133
+
134
+
135
+ def discover(app_path: Path) -> dict[str, object]:
136
+ root = app_path.resolve()
137
+ hints: list[ConnectionHint] = []
138
+ for path in root.rglob("*"):
139
+ if path.is_file() and is_candidate_file(path):
140
+ hints.extend(scan_file(path, root))
141
+
142
+ return {
143
+ "generated_at": datetime.now(timezone.utc).isoformat(),
144
+ "app_path": str(root),
145
+ "summary": infer_summary(hints),
146
+ "connection_hints": [asdict(h) for h in hints],
147
+ "notes": [
148
+ "Secret values are masked.",
149
+ "Validate stale or conflicting configs before using a connection.",
150
+ ],
151
+ }
152
+
153
+
154
+ def main() -> None:
155
+ parser = argparse.ArgumentParser(description="Discover masked connection config in an app repo.")
156
+ parser.add_argument("--app", type=Path, required=True, help="Application repository path")
157
+ parser.add_argument("--output", type=Path, help="Output connection_manifest.json path")
158
+ args = parser.parse_args()
159
+
160
+ manifest = discover(args.app)
161
+ text = json.dumps(manifest, indent=2)
162
+ if args.output:
163
+ args.output.parent.mkdir(parents=True, exist_ok=True)
164
+ args.output.write_text(text + "\n", encoding="utf-8")
165
+ else:
166
+ print(text)
167
+
168
+
169
+ if __name__ == "__main__":
170
+ main()
@@ -0,0 +1,161 @@
1
+ """Discover source schemas from files or a SQL Server connection string.
2
+
3
+ The script emits a normalized source_manifest.json. DB discovery uses pyodbc
4
+ when available and metadata-only queries by default.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import argparse
10
+ import csv
11
+ import json
12
+ from datetime import datetime, timezone
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+
17
+ def infer_value_type(value: Any) -> str:
18
+ if value is None or value == "":
19
+ return "null-or-empty"
20
+ if isinstance(value, bool):
21
+ return "bool"
22
+ if isinstance(value, int):
23
+ return "int"
24
+ if isinstance(value, float):
25
+ return "float"
26
+ text = str(value).strip()
27
+ for caster, name in ((int, "int"), (float, "float")):
28
+ try:
29
+ caster(text.replace(",", ""))
30
+ return name
31
+ except ValueError:
32
+ pass
33
+ return "str"
34
+
35
+
36
+ def discover_json(path: Path) -> dict[str, object]:
37
+ data = json.loads(path.read_text(encoding="utf-8"))
38
+ sample = data[0] if isinstance(data, list) and data else data
39
+ fields = []
40
+ if isinstance(sample, dict):
41
+ fields = [
42
+ {"path": key, "type": infer_value_type(value), "example": str(value)[:120]}
43
+ for key, value in sample.items()
44
+ ]
45
+ return {"source": str(path), "kind": "json", "fields": fields}
46
+
47
+
48
+ def discover_csv(path: Path) -> dict[str, object]:
49
+ with path.open(newline="", encoding="utf-8-sig") as handle:
50
+ reader = csv.DictReader(handle)
51
+ first = next(reader, {})
52
+ fields = [
53
+ {"path": key, "type": infer_value_type(value), "example": str(value)[:120]}
54
+ for key, value in first.items()
55
+ ]
56
+ return {"source": str(path), "kind": "csv", "fields": fields}
57
+
58
+
59
+ def discover_text(path: Path) -> dict[str, object]:
60
+ text = path.read_text(encoding="utf-8", errors="ignore")
61
+ return {
62
+ "source": str(path),
63
+ "kind": path.suffix.lower().lstrip(".") or "text",
64
+ "line_count": len(text.splitlines()),
65
+ "fields": [],
66
+ }
67
+
68
+
69
+ def discover_file(path: Path) -> dict[str, object]:
70
+ suffix = path.suffix.lower()
71
+ if suffix == ".json":
72
+ return discover_json(path)
73
+ if suffix in {".csv", ".tsv"}:
74
+ return discover_csv(path)
75
+ return discover_text(path)
76
+
77
+
78
+ def discover_db(connection_string: str, schema: str | None) -> dict[str, object]:
79
+ try:
80
+ import pyodbc # type: ignore
81
+ except ModuleNotFoundError:
82
+ return {
83
+ "kind": "db",
84
+ "status": "blocked",
85
+ "reason": "pyodbc is not installed",
86
+ "objects": [],
87
+ }
88
+
89
+ objects: list[dict[str, object]] = []
90
+ with pyodbc.connect(connection_string, timeout=10) as conn:
91
+ cursor = conn.cursor()
92
+ cursor.execute(
93
+ """
94
+ SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE
95
+ FROM INFORMATION_SCHEMA.TABLES
96
+ WHERE (? IS NULL OR TABLE_SCHEMA = ?)
97
+ ORDER BY TABLE_SCHEMA, TABLE_NAME
98
+ """,
99
+ schema,
100
+ schema,
101
+ )
102
+ rows = cursor.fetchall()
103
+ for row in rows:
104
+ table_schema, table_name, table_type = row
105
+ cursor.execute(
106
+ """
107
+ SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE
108
+ FROM INFORMATION_SCHEMA.COLUMNS
109
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
110
+ ORDER BY ORDINAL_POSITION
111
+ """,
112
+ table_schema,
113
+ table_name,
114
+ )
115
+ columns = [
116
+ {"name": c.COLUMN_NAME, "type": c.DATA_TYPE, "nullable": c.IS_NULLABLE}
117
+ for c in cursor.fetchall()
118
+ ]
119
+ objects.append(
120
+ {
121
+ "schema": table_schema,
122
+ "name": table_name,
123
+ "type": table_type,
124
+ "columns": columns,
125
+ }
126
+ )
127
+ return {"kind": "db", "status": "discovered", "objects": objects}
128
+
129
+
130
+ def main() -> None:
131
+ parser = argparse.ArgumentParser(description="Discover data sources and emit source_manifest.json.")
132
+ parser.add_argument("--source", type=Path, action="append", help="Source file or directory")
133
+ parser.add_argument("--connection-string", help="ODBC connection string for DB metadata discovery")
134
+ parser.add_argument("--schema", help="Optional DB schema filter")
135
+ parser.add_argument("--output", type=Path, required=True, help="Output source_manifest.json path")
136
+ args = parser.parse_args()
137
+
138
+ sources: list[dict[str, object]] = []
139
+ for source in args.source or []:
140
+ if source.is_dir():
141
+ for path in source.rglob("*"):
142
+ if path.is_file():
143
+ sources.append(discover_file(path))
144
+ elif source.exists():
145
+ sources.append(discover_file(source))
146
+ else:
147
+ sources.append({"source": str(source), "status": "missing", "fields": []})
148
+
149
+ if args.connection_string:
150
+ sources.append(discover_db(args.connection_string, args.schema))
151
+
152
+ manifest = {
153
+ "generated_at": datetime.now(timezone.utc).isoformat(),
154
+ "sources": sources,
155
+ }
156
+ args.output.parent.mkdir(parents=True, exist_ok=True)
157
+ args.output.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
158
+
159
+
160
+ if __name__ == "__main__":
161
+ main()