@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.
- package/README.md +29 -16
- package/bundles/antigravity-plugin-extras/plugin.json +5 -0
- package/bundles/antigravity-plugin-extras/skills/_registry.md +154 -0
- package/bundles/antigravity-plugin-extras/skills/agent-md-refactor/SKILL.md +356 -0
- package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +517 -0
- package/bundles/antigravity-plugin-extras/skills/algorithmic-art/SKILL.md +293 -0
- package/bundles/antigravity-plugin-extras/skills/anchor-review/SKILL.md +135 -0
- package/bundles/antigravity-plugin-extras/skills/api-client-patterns/SKILL.md +367 -0
- package/bundles/antigravity-plugin-extras/skills/architecture-design/SKILL.md +244 -0
- package/bundles/antigravity-plugin-extras/skills/architecture-diagram/SKILL.md +156 -0
- package/bundles/antigravity-plugin-extras/skills/architecture-document/SKILL.md +321 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/SKILL.md +74 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/bundles/antigravity-plugin-extras/skills/ascii-art/SKILL.md +144 -0
- package/bundles/antigravity-plugin-extras/skills/asking-questions/SKILL.md +81 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/SKILL.md +118 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/cross-service/credential-management.md +450 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/browser/README.md +363 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/code-interpreter/README.md +232 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/README.md +100 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/deploy-template.sh +117 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/deployment-strategies.md +416 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/troubleshooting-guide.md +384 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/validate-deployment.sh +186 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/identity/README.md +186 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/memory/README.md +253 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/observability/README.md +517 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/runtime/README.md +215 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/SKILL.md +279 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/references/cdk-patterns.md +431 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/scripts/validate-stack.sh +240 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/SKILL.md +318 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/references/cloudwatch-alarms.md +567 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/references/operations-patterns.md +394 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/SKILL.md +758 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/deployment-best-practices.md +830 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/eda-patterns.md +1002 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/observability-best-practices.md +770 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/performance-optimization.md +671 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/security-best-practices.md +625 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/serverless-patterns.md +838 -0
- package/bundles/antigravity-plugin-extras/skills/backend-to-frontend-handoff/SKILL.md +139 -0
- package/bundles/antigravity-plugin-extras/skills/banner-design/SKILL.md +188 -0
- package/bundles/antigravity-plugin-extras/skills/brand-design/SKILL.md +298 -0
- package/bundles/antigravity-plugin-extras/skills/brand-guidelines/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/brand-guidelines/SKILL.md +118 -0
- package/bundles/antigravity-plugin-extras/skills/brand-voice/SKILL.md +93 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/SKILL.md +392 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/agent-patterns.md +461 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/examples.md +188 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/state-patterns.md +360 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/troubleshooting.md +362 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/SKILL.md +266 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/examples.md +115 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/oauth-setup.md +338 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/troubleshooting.md +317 -0
- package/bundles/antigravity-plugin-extras/skills/caching-patterns/SKILL.md +385 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/SKILL.md +91 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/changelog-generator/SKILL.md +105 -0
- package/bundles/antigravity-plugin-extras/skills/code-explainer/SKILL.md +91 -0
- package/bundles/antigravity-plugin-extras/skills/competitive-ads-extractor/SKILL.md +294 -0
- package/bundles/antigravity-plugin-extras/skills/component-testing/SKILL.md +310 -0
- package/bundles/antigravity-plugin-extras/skills/content-research-writer/SKILL.md +539 -0
- package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +51 -0
- package/bundles/antigravity-plugin-extras/skills/data-analysis/SKILL.md +111 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/README.md +248 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/SKILL.md +203 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/adapter.py.template +44 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/api-router.py.template +43 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/contract-test.py.template +384 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/display-dto.py.template +39 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/frontend-service.ts.template +46 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/frontend-types.ts.template +38 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/ingestion-model.py.template +42 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/mapping-doc.md.template +46 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/normalizer.py.template +48 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/extract_requirements.md +36 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/extract_ui_demand.md +35 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/reconcile_mapping.md +66 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/query-catalog.md.template +62 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/consumer-driven-contracts.md +131 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/drift-check-catalog.md +305 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/layer-responsibilities.md +333 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/discover_connections.py +170 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/discover_sources.py +161 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/drift_check.py +171 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/extract_schema.py +1363 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/generate_gap_report.py +81 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/generate_mapping_doc.py +294 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/ts_dto_compare.py +214 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/validate_lineage.py +51 -0
- package/bundles/antigravity-plugin-extras/skills/data-loader/SKILL.md +753 -0
- package/bundles/antigravity-plugin-extras/skills/data-validation/SKILL.md +220 -0
- package/bundles/antigravity-plugin-extras/skills/db-testing/SKILL.md +117 -0
- package/bundles/antigravity-plugin-extras/skills/deploy-local/SKILL.md +259 -0
- package/bundles/antigravity-plugin-extras/skills/design-md/SKILL.md +167 -0
- package/bundles/antigravity-plugin-extras/skills/design-system-tokens/SKILL.md +240 -0
- package/bundles/antigravity-plugin-extras/skills/design-system-tokens/references/DESIGN-SYSTEM-TEMPLATE.md +577 -0
- package/bundles/antigravity-plugin-extras/skills/developer-growth-analysis/SKILL.md +323 -0
- package/bundles/antigravity-plugin-extras/skills/doc-coauthoring/SKILL.md +378 -0
- package/bundles/antigravity-plugin-extras/skills/documentation-analyzer/SKILL.md +78 -0
- package/bundles/antigravity-plugin-extras/skills/domain-name-brainstormer/SKILL.md +213 -0
- package/bundles/antigravity-plugin-extras/skills/enterprise-dashboard-aesthetic-system/SKILL.md +120 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/SKILL.md +193 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/references/element-types.md +497 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/references/excalidraw-schema.md +356 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/references/reliable-diagrams.md +115 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/README.md +60 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/add-arrow.py +354 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/add-icon-to-diagram.py +412 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/split-excalidraw-library.py +183 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/business-flow-swimlane-template.excalidraw +334 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/class-diagram-template.excalidraw +558 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/data-flow-diagram-template.excalidraw +279 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/er-diagram-template.excalidraw +662 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/flowchart-template.excalidraw +179 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/mindmap-template.excalidraw +244 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/relationship-template.excalidraw +145 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/reliable-flowchart.excalidraw +1 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/sequence-diagram-template.excalidraw +509 -0
- package/bundles/antigravity-plugin-extras/skills/file-organizer/SKILL.md +434 -0
- package/bundles/antigravity-plugin-extras/skills/game-changing-features/README.md +221 -0
- package/bundles/antigravity-plugin-extras/skills/game-changing-features/SKILL.md +265 -0
- package/bundles/antigravity-plugin-extras/skills/github-issues/SKILL.md +359 -0
- package/bundles/antigravity-plugin-extras/skills/github-issues/references/templates.md +90 -0
- package/bundles/antigravity-plugin-extras/skills/golden-nuggets/SKILL.md +192 -0
- package/bundles/antigravity-plugin-extras/skills/humanizer/SKILL.md +194 -0
- package/bundles/antigravity-plugin-extras/skills/image-enhancer/SKILL.md +100 -0
- package/bundles/antigravity-plugin-extras/skills/intent-writer/SKILL.md +201 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/SKILL.md +124 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/3p-updates.md +47 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/faq-answers.md +30 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/general-comms.md +16 -0
- package/bundles/antigravity-plugin-extras/skills/invoice-organizer/SKILL.md +447 -0
- package/bundles/antigravity-plugin-extras/skills/jira-issues/SKILL.md +182 -0
- package/bundles/antigravity-plugin-extras/skills/job-application/SKILL.md +188 -0
- package/bundles/antigravity-plugin-extras/skills/lead-research-assistant/SKILL.md +200 -0
- package/bundles/antigravity-plugin-extras/skills/llm-application-dev/SKILL.md +217 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/SKILL.md +100 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/evaluation.md +602 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/mcp_best_practices.md +915 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/node_mcp_server.md +916 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/python_mcp_server.md +752 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/connections.py +151 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/bundles/antigravity-plugin-extras/skills/meeting-insights-analyzer/SKILL.md +328 -0
- package/bundles/antigravity-plugin-extras/skills/monorepo/SKILL.md +267 -0
- package/bundles/antigravity-plugin-extras/skills/naming-analyzer/SKILL.md +376 -0
- package/bundles/antigravity-plugin-extras/skills/nextjs-app-router/SKILL.md +271 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/AUTHENTICATION.md +154 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/SKILL.md +270 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/references/api_reference.md +309 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/references/troubleshooting.md +376 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/references/usage_patterns.md +338 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/__init__.py +81 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/ask_question.py +256 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/auth_manager.py +358 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/browser_session.py +255 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/browser_utils.py +107 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/cleanup_manager.py +302 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/config.py +44 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/notebook_manager.py +410 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/run.py +102 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/setup_environment.py +204 -0
- package/bundles/antigravity-plugin-extras/skills/observability/SKILL.md +371 -0
- package/bundles/antigravity-plugin-extras/skills/onboard-project/SKILL.md +192 -0
- package/bundles/antigravity-plugin-extras/skills/performance-testing/SKILL.md +226 -0
- package/bundles/antigravity-plugin-extras/skills/pipeline-state/SKILL.md +208 -0
- package/bundles/antigravity-plugin-extras/skills/plantuml/SKILL.md +228 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/SKILL.md +142 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/linear.app.md +196 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/stripe.md +214 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/vercel.md +218 -0
- package/bundles/antigravity-plugin-extras/skills/prd-to-code/SKILL.md +127 -0
- package/bundles/antigravity-plugin-extras/skills/raffle-winner-picker/SKILL.md +159 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/README.md +320 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/SKILL.md +53 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/alternatives.md +258 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/anti-patterns.md +290 -0
- package/bundles/antigravity-plugin-extras/skills/receiving-code-review/SKILL.md +213 -0
- package/bundles/antigravity-plugin-extras/skills/relay/SKILL.md +246 -0
- package/bundles/antigravity-plugin-extras/skills/requesting-code-review/SKILL.md +105 -0
- package/bundles/antigravity-plugin-extras/skills/requesting-code-review/code-reviewer.md +146 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/SKILL.md +350 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/pwa-checklist.md +226 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/touch-and-interaction.md +265 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/transformation-catalogue.md +326 -0
- package/bundles/antigravity-plugin-extras/skills/schema-migration/SKILL.md +275 -0
- package/bundles/antigravity-plugin-extras/skills/setup-project-ai/SKILL.md +120 -0
- package/bundles/antigravity-plugin-extras/skills/shadcn-radix/SKILL.md +330 -0
- package/bundles/antigravity-plugin-extras/skills/sketch/SKILL.md +104 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/SKILL.md +646 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/color_palettes.py +302 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/easing.py +230 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/frame_composer.py +469 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/gif_builder.py +246 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/typography.py +357 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/validators.py +264 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/visual_effects.py +494 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/requirements.txt +4 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/bounce.py +106 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/explode.py +331 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/fade.py +329 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/flip.py +291 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/morph.py +329 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/move.py +293 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/pulse.py +268 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/shake.py +127 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/slide.py +291 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/spin.py +269 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/wiggle.py +300 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/zoom.py +312 -0
- package/bundles/antigravity-plugin-extras/skills/slides/SKILL.md +38 -0
- package/bundles/antigravity-plugin-extras/skills/state-tracking/SKILL.md +131 -0
- package/bundles/antigravity-plugin-extras/skills/streamlit-dev/SKILL.md +268 -0
- package/bundles/antigravity-plugin-extras/skills/svg-create/SKILL.md +251 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/SKILL.md +59 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/theme-showcase.pdf +0 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/desert-rose.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/golden-hour.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/SKILL.md +320 -0
- package/bundles/antigravity-plugin-extras/skills/ui-testing/SKILL.md +660 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/SKILL.md +660 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/_sync_all.py +414 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/app-interface.csv +31 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/charts.csv +26 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/colors.csv +162 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/design.csv +1776 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/draft.csv +1779 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/google-fonts.csv +1924 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/icons.csv +106 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/landing.csv +35 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/products.csv +162 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/react-performance.csv +45 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/styles.csv +85 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/typography.csv +74 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/ui-reasoning.csv +162 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/ux-guidelines.csv +100 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/core.py +247 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/design_system.py +1067 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/search.py +114 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/SKILL.md +140 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/references/commands.md +252 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/references/graph-schema.md +116 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/references/pipeline.md +331 -0
- package/bundles/antigravity-plugin-extras/skills/update-readme/SKILL.md +74 -0
- package/bundles/antigravity-plugin-extras/skills/verification-loop/SKILL.md +209 -0
- package/bundles/antigravity-plugin-extras/skills/video-downloader/SKILL.md +107 -0
- package/bundles/antigravity-plugin-extras/skills/webapp-development/SKILL.md +288 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/SKILL.md +339 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/agents/agent-interface.md +175 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/html.md +384 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/nlp-keywords.md +127 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/palettes.md +149 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/python.md +249 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/react.md +427 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/shapes.md +135 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/stopwords.md +115 -0
- package/bundles/antigravity-plugin-extras/skills/youtube-transcript/SKILL.md +416 -0
- package/bundles/manifest.json +2 -1
- package/dist/cli.js +166 -37
- package/package.json +1 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# MCP Server Troubleshooting
|
|
2
|
+
|
|
3
|
+
Common errors and solutions for MCP servers on Cloudflare.
|
|
4
|
+
|
|
5
|
+
## Connection Issues
|
|
6
|
+
|
|
7
|
+
### "Failed to connect to MCP server"
|
|
8
|
+
|
|
9
|
+
**Symptoms:** Client cannot establish connection to deployed server.
|
|
10
|
+
|
|
11
|
+
**Causes & Solutions:**
|
|
12
|
+
|
|
13
|
+
1. **Wrong URL path**
|
|
14
|
+
```
|
|
15
|
+
# Wrong
|
|
16
|
+
https://my-server.workers.dev/
|
|
17
|
+
|
|
18
|
+
# Correct
|
|
19
|
+
https://my-server.workers.dev/mcp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. **Worker not deployed**
|
|
23
|
+
```bash
|
|
24
|
+
wrangler deployments list
|
|
25
|
+
# If empty, deploy first:
|
|
26
|
+
wrangler deploy
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. **Worker crashed on startup**
|
|
30
|
+
```bash
|
|
31
|
+
wrangler tail
|
|
32
|
+
# Check for initialization errors
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### "WebSocket connection failed"
|
|
36
|
+
|
|
37
|
+
MCP uses SSE (Server-Sent Events), not WebSockets. Ensure your client is configured for SSE transport:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"my-server": {
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["mcp-remote", "https://my-server.workers.dev/mcp"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### CORS Errors in Browser
|
|
51
|
+
|
|
52
|
+
If calling from browser-based client:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// Add CORS headers to your worker
|
|
56
|
+
export default {
|
|
57
|
+
async fetch(request: Request, env: Env) {
|
|
58
|
+
// Handle preflight
|
|
59
|
+
if (request.method === "OPTIONS") {
|
|
60
|
+
return new Response(null, {
|
|
61
|
+
headers: {
|
|
62
|
+
"Access-Control-Allow-Origin": "*",
|
|
63
|
+
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
64
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const response = await handleRequest(request, env);
|
|
70
|
+
|
|
71
|
+
// Add CORS headers to response
|
|
72
|
+
const headers = new Headers(response.headers);
|
|
73
|
+
headers.set("Access-Control-Allow-Origin", "*");
|
|
74
|
+
|
|
75
|
+
return new Response(response.body, {
|
|
76
|
+
status: response.status,
|
|
77
|
+
headers,
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Tool Errors
|
|
84
|
+
|
|
85
|
+
### "Tool not found: [tool_name]"
|
|
86
|
+
|
|
87
|
+
**Causes:**
|
|
88
|
+
|
|
89
|
+
1. Tool not registered in `init()`
|
|
90
|
+
2. Tool name mismatch (case-sensitive)
|
|
91
|
+
3. `init()` threw an error before registering tool
|
|
92
|
+
|
|
93
|
+
**Debug:**
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
async init() {
|
|
97
|
+
console.log("Registering tools...");
|
|
98
|
+
|
|
99
|
+
this.server.tool("my_tool", { ... }, async () => { ... });
|
|
100
|
+
|
|
101
|
+
console.log("Tools registered:", this.server.listTools());
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Check logs: `wrangler tail`
|
|
106
|
+
|
|
107
|
+
### "Invalid parameters for tool"
|
|
108
|
+
|
|
109
|
+
Zod validation failed. Check parameter schema:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Schema expects number, client sent string
|
|
113
|
+
this.server.tool(
|
|
114
|
+
"calculate",
|
|
115
|
+
{ value: z.number() }, // Client must send number, not "123"
|
|
116
|
+
async ({ value }) => { ... }
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// Fix: Coerce string to number
|
|
120
|
+
this.server.tool(
|
|
121
|
+
"calculate",
|
|
122
|
+
{ value: z.coerce.number() }, // "123" → 123
|
|
123
|
+
async ({ value }) => { ... }
|
|
124
|
+
);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Tool Timeout
|
|
128
|
+
|
|
129
|
+
Workers have CPU time limits (10-30ms for free, longer for paid). For long operations:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
this.server.tool(
|
|
133
|
+
"long_operation",
|
|
134
|
+
{ ... },
|
|
135
|
+
async (params) => {
|
|
136
|
+
// Break into smaller chunks
|
|
137
|
+
// Or use Queues/Durable Objects for background work
|
|
138
|
+
|
|
139
|
+
// Don't do this:
|
|
140
|
+
// await sleep(5000); // Will timeout
|
|
141
|
+
|
|
142
|
+
return { content: [{ type: "text", text: "Queued for processing" }] };
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Authentication Errors
|
|
148
|
+
|
|
149
|
+
### "401 Unauthorized"
|
|
150
|
+
|
|
151
|
+
OAuth token missing or expired.
|
|
152
|
+
|
|
153
|
+
1. **Check client is handling OAuth flow**
|
|
154
|
+
2. **Verify secrets are set:**
|
|
155
|
+
```bash
|
|
156
|
+
wrangler secret list
|
|
157
|
+
# Should show GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
3. **Check KV namespace exists:**
|
|
161
|
+
```bash
|
|
162
|
+
wrangler kv namespace list
|
|
163
|
+
# Should show OAUTH_KV
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### "Invalid redirect_uri"
|
|
167
|
+
|
|
168
|
+
OAuth callback URL doesn't match app configuration.
|
|
169
|
+
|
|
170
|
+
**Local development:**
|
|
171
|
+
- OAuth app callback: `http://localhost:8788/callback`
|
|
172
|
+
|
|
173
|
+
**Production:**
|
|
174
|
+
- OAuth app callback: `https://[worker-name].[account].workers.dev/callback`
|
|
175
|
+
|
|
176
|
+
Must match EXACTLY (including trailing slash or lack thereof).
|
|
177
|
+
|
|
178
|
+
### "State mismatch" / CSRF Error
|
|
179
|
+
|
|
180
|
+
State parameter validation failed.
|
|
181
|
+
|
|
182
|
+
1. **Clear browser cookies and retry**
|
|
183
|
+
2. **Check KV is storing state:**
|
|
184
|
+
```typescript
|
|
185
|
+
// In your auth handler
|
|
186
|
+
console.log("Storing state:", state);
|
|
187
|
+
await env.OAUTH_KV.put(`state:${state}`, "1", { expirationTtl: 600 });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
3. **Verify same domain for all requests**
|
|
191
|
+
|
|
192
|
+
## Binding Errors
|
|
193
|
+
|
|
194
|
+
### "Binding not found: [BINDING_NAME]"
|
|
195
|
+
|
|
196
|
+
Binding not in `wrangler.toml` or not deployed.
|
|
197
|
+
|
|
198
|
+
```toml
|
|
199
|
+
# wrangler.toml
|
|
200
|
+
[[d1_databases]]
|
|
201
|
+
binding = "DB" # Must match env.DB in code
|
|
202
|
+
database_name = "mydb"
|
|
203
|
+
database_id = "xxx-xxx"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
After adding bindings: `wrangler deploy`
|
|
207
|
+
|
|
208
|
+
### "D1_ERROR: no such table"
|
|
209
|
+
|
|
210
|
+
Migrations not applied.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Local
|
|
214
|
+
wrangler d1 migrations apply DB_NAME --local
|
|
215
|
+
|
|
216
|
+
# Production
|
|
217
|
+
wrangler d1 migrations apply DB_NAME
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Durable Object Not Found
|
|
221
|
+
|
|
222
|
+
```toml
|
|
223
|
+
# wrangler.toml must have:
|
|
224
|
+
[durable_objects]
|
|
225
|
+
bindings = [{ name = "MCP", class_name = "MyMCP" }]
|
|
226
|
+
|
|
227
|
+
[[migrations]]
|
|
228
|
+
tag = "v1"
|
|
229
|
+
new_classes = ["MyMCP"]
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
And class must be exported:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
export { MyMCP }; // Don't forget this!
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Deployment Errors
|
|
239
|
+
|
|
240
|
+
### "Class MyMCP is not exported"
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// src/index.ts - Must export the class
|
|
244
|
+
export { MyMCP } from "./mcp";
|
|
245
|
+
|
|
246
|
+
// OR in same file
|
|
247
|
+
export class MyMCP extends McpAgent { ... }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### "Migration required"
|
|
251
|
+
|
|
252
|
+
New Durable Object class needs migration:
|
|
253
|
+
|
|
254
|
+
```toml
|
|
255
|
+
# Add to wrangler.toml
|
|
256
|
+
[[migrations]]
|
|
257
|
+
tag = "v2" # Increment version
|
|
258
|
+
new_classes = ["NewClassName"]
|
|
259
|
+
# Or for renames:
|
|
260
|
+
# renamed_classes = [{ from = "OldName", to = "NewName" }]
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Build Errors
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
# Clear cache and rebuild
|
|
267
|
+
rm -rf node_modules .wrangler
|
|
268
|
+
npm install
|
|
269
|
+
wrangler deploy
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Debugging Tips
|
|
273
|
+
|
|
274
|
+
### Enable Verbose Logging
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
export class MyMCP extends McpAgent {
|
|
278
|
+
async init() {
|
|
279
|
+
console.log("MCP Server initializing...");
|
|
280
|
+
console.log("Environment:", Object.keys(this.env));
|
|
281
|
+
|
|
282
|
+
this.server.tool("test", {}, async () => {
|
|
283
|
+
console.log("Test tool called");
|
|
284
|
+
return { content: [{ type: "text", text: "OK" }] };
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
console.log("Tools registered");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
View logs:
|
|
293
|
+
```bash
|
|
294
|
+
wrangler tail --format pretty
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Test Locally First
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
npm start
|
|
301
|
+
npx @modelcontextprotocol/inspector@latest
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Always verify tools work locally before deploying.
|
|
305
|
+
|
|
306
|
+
### Check Worker Health
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# List deployments
|
|
310
|
+
wrangler deployments list
|
|
311
|
+
|
|
312
|
+
# View recent logs
|
|
313
|
+
wrangler tail
|
|
314
|
+
|
|
315
|
+
# Check worker status
|
|
316
|
+
curl -I https://your-worker.workers.dev/mcp
|
|
317
|
+
```
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: caching-patterns
|
|
3
|
+
description: Caching strategies for Streamlit and FastAPI applications
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Caching Patterns
|
|
7
|
+
|
|
8
|
+
> **Project Context** — Read `project-config.md` in the repo root for brand tokens, shared-library paths, and deployment targets.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
Invoke this skill when:
|
|
13
|
+
- Adding caching to Streamlit data fetches
|
|
14
|
+
- Caching database connections or ML models
|
|
15
|
+
- Implementing multi-user caching for dashboards
|
|
16
|
+
- Setting up Redis caching for FastAPI
|
|
17
|
+
- Deciding cache TTL values for application data
|
|
18
|
+
- Debugging stale data issues
|
|
19
|
+
- Optimizing page load performance
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### Step 1: Choose the Right Caching Strategy
|
|
26
|
+
|
|
27
|
+
| Scenario | Strategy | Decorator/Tool |
|
|
28
|
+
|----------|----------|----------------|
|
|
29
|
+
| SQL query results (DataFrames) | Data cache with TTL | `@st.cache_data(ttl=...)` |
|
|
30
|
+
| DB connections, adapters | Resource cache (singleton) | `@st.cache_resource` |
|
|
31
|
+
| ML models, LLM clients | Resource cache (singleton) | `@st.cache_resource` |
|
|
32
|
+
| Multi-user shared data | Cached repository pattern | Custom `get_repo()` |
|
|
33
|
+
| FastAPI endpoint responses | Redis or in-memory | `redis` / `cachetools` |
|
|
34
|
+
| Static config, lookups | Long TTL or no TTL | `@st.cache_data` |
|
|
35
|
+
|
|
36
|
+
### Step 2: Implement Streamlit Caching
|
|
37
|
+
|
|
38
|
+
#### Data Caching (returns serialized copy per caller)
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from datetime import timedelta
|
|
42
|
+
import streamlit as st
|
|
43
|
+
import pandas as pd
|
|
44
|
+
|
|
45
|
+
@st.cache_data(ttl=timedelta(minutes=15), show_spinner="Loading records...")
|
|
46
|
+
def load_records() -> pd.DataFrame:
|
|
47
|
+
"""Cached data fetch -- each caller gets an independent copy."""
|
|
48
|
+
from libs.data import DatabaseAdapter
|
|
49
|
+
adapter = DatabaseAdapter()
|
|
50
|
+
return adapter.fetch_dataframe(
|
|
51
|
+
"SELECT * FROM AppRecords WHERE [Created Date Time] >= DATEADD(day, -7, GETDATE())"
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Resource Caching (shared singleton)
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
@st.cache_resource
|
|
59
|
+
def get_database_adapter():
|
|
60
|
+
"""Singleton resource -- shared across all users."""
|
|
61
|
+
from libs.data import DatabaseAdapter
|
|
62
|
+
return DatabaseAdapter()
|
|
63
|
+
|
|
64
|
+
@st.cache_resource
|
|
65
|
+
def load_ml_model():
|
|
66
|
+
"""Load and cache ML model."""
|
|
67
|
+
import joblib
|
|
68
|
+
return joblib.load("models/classifier.joblib")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Step 3: Multi-User Cached Repository Pattern
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
# src/services/cached_repository.py
|
|
75
|
+
import streamlit as st
|
|
76
|
+
from datetime import timedelta
|
|
77
|
+
from copy import deepcopy
|
|
78
|
+
|
|
79
|
+
@st.cache_data(ttl=timedelta(minutes=15), show_spinner=False)
|
|
80
|
+
def _fetch_data(query_name: str, filter_type: str, date_str: str = "") -> pd.DataFrame:
|
|
81
|
+
"""Internal cached fetch -- keyed by query + filters."""
|
|
82
|
+
repo = _get_repo_instance()
|
|
83
|
+
return repo.execute_query(query_name, filter_type=filter_type, date_str=date_str)
|
|
84
|
+
|
|
85
|
+
def get_chart_data(query_name: str, filter_type: str, date_str: str = "") -> pd.DataFrame:
|
|
86
|
+
"""Public API -- returns deep copy to prevent mutation."""
|
|
87
|
+
return deepcopy(_fetch_data(query_name, filter_type, date_str))
|
|
88
|
+
|
|
89
|
+
@st.cache_resource
|
|
90
|
+
def _get_repo_instance():
|
|
91
|
+
"""Singleton repository instance."""
|
|
92
|
+
from src.services.data_repository import DataRepository
|
|
93
|
+
return DataRepository()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Step 4: FastAPI Caching (Redis or In-Memory)
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
# Redis caching for FastAPI
|
|
100
|
+
from functools import lru_cache
|
|
101
|
+
from cachetools import TTLCache
|
|
102
|
+
|
|
103
|
+
# In-memory TTL cache (simple, no Redis dependency)
|
|
104
|
+
_cache = TTLCache(maxsize=100, ttl=900) # 15 min TTL
|
|
105
|
+
|
|
106
|
+
async def get_records_cached(status: str) -> list:
|
|
107
|
+
cache_key = f"records:{status}"
|
|
108
|
+
if cache_key in _cache:
|
|
109
|
+
return _cache[cache_key]
|
|
110
|
+
result = await repo.get_by_status(status)
|
|
111
|
+
_cache[cache_key] = result
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
# Cache invalidation on write
|
|
115
|
+
async def create_record(record: RecordCreate):
|
|
116
|
+
result = await repo.create(record)
|
|
117
|
+
# Invalidate relevant cache entries
|
|
118
|
+
_cache.pop(f"records:{record.status}", None)
|
|
119
|
+
return result
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Step 5: Set TTL Values
|
|
123
|
+
|
|
124
|
+
| Data Type | Recommended TTL | Rationale |
|
|
125
|
+
|-----------|----------------|-----------|
|
|
126
|
+
| Dashboard KPIs | 15 min | Balance freshness vs performance |
|
|
127
|
+
| Records list | 5-10 min | Users expect near-real-time |
|
|
128
|
+
| Static lookups (categories) | 1 hour | Rarely change |
|
|
129
|
+
| User session data | No cache | Must be real-time |
|
|
130
|
+
| Historical reports | 1 hour+ | Data doesn't change |
|
|
131
|
+
| DB connections | No TTL (resource) | Persist for app lifetime |
|
|
132
|
+
|
|
133
|
+
### Step 6: SPA Shell/Asset Cache Coherence (FastAPI + Vite)
|
|
134
|
+
|
|
135
|
+
For FastAPI-served SPAs, split cache behavior by file type:
|
|
136
|
+
|
|
137
|
+
- `index.html` (app shell): `Cache-Control: no-cache, no-store, must-revalidate`
|
|
138
|
+
- `/assets/*` hashed bundles: `Cache-Control: public, max-age=31536000, immutable`
|
|
139
|
+
|
|
140
|
+
Why this matters:
|
|
141
|
+
- The shell maps route/module imports to hashed chunk filenames.
|
|
142
|
+
- If old shell HTML is cached, it points to deleted chunks after deploy.
|
|
143
|
+
- Hashed bundles are immutable and safe for long cache.
|
|
144
|
+
|
|
145
|
+
Recommended implementation:
|
|
146
|
+
1. Mount `/assets` using a `StaticFiles` subclass that injects immutable cache headers.
|
|
147
|
+
2. Serve `index.html` via `FileResponse(..., headers={"Cache-Control": "no-cache, no-store, must-revalidate"})`.
|
|
148
|
+
3. Add frontend lazy-import fallback: one automatic reload on chunk-load failure, then show explicit retry UI.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Patterns and Examples
|
|
153
|
+
|
|
154
|
+
### Cache Key Strategy
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
# Good: include all parameters that affect the result
|
|
158
|
+
@st.cache_data(ttl=timedelta(minutes=15))
|
|
159
|
+
def load_data(filter_type: str, date_range: str, category: str | None = None):
|
|
160
|
+
# Streamlit auto-generates cache key from all arguments
|
|
161
|
+
...
|
|
162
|
+
|
|
163
|
+
# Bad: mutable objects as parameters (breaks caching)
|
|
164
|
+
@st.cache_data(ttl=timedelta(minutes=15))
|
|
165
|
+
def load_data(filters: dict): # dict is unhashable!
|
|
166
|
+
...
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Performance Logging
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from loguru import logger
|
|
173
|
+
import time
|
|
174
|
+
|
|
175
|
+
@st.cache_data(ttl=timedelta(minutes=15), show_spinner="Loading...")
|
|
176
|
+
def load_records_with_logging() -> pd.DataFrame:
|
|
177
|
+
start = time.perf_counter()
|
|
178
|
+
adapter = get_database_adapter()
|
|
179
|
+
df = adapter.fetch_dataframe("SELECT * FROM AppRecords WHERE Status = 'Open'")
|
|
180
|
+
elapsed = time.perf_counter() - start
|
|
181
|
+
logger.info(f"Loaded {len(df)} records in {elapsed:.2f}s")
|
|
182
|
+
return df
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Cache Warming
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
def warm_caches():
|
|
189
|
+
"""Pre-load critical data on app startup."""
|
|
190
|
+
logger.info("Warming caches...")
|
|
191
|
+
load_records() # Triggers initial cache fill
|
|
192
|
+
load_categories()
|
|
193
|
+
logger.info("Caches warmed successfully")
|
|
194
|
+
|
|
195
|
+
# Call at app startup
|
|
196
|
+
if "caches_warmed" not in st.session_state:
|
|
197
|
+
warm_caches()
|
|
198
|
+
st.session_state.caches_warmed = True
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## ⚠️ Caching Gotchas (CRITICAL — Read Before Caching)
|
|
204
|
+
|
|
205
|
+
These are **proven failure modes** encountered in production. Every caching decision must account for them.
|
|
206
|
+
|
|
207
|
+
### Gotcha 1: `@st.cache_data` Uses Pickle — Pydantic Computed Fields Break
|
|
208
|
+
|
|
209
|
+
`@st.cache_data` serializes return values with `pickle`. Pydantic models with `@computed_field` or `@property` **will fail** because pickle cannot serialize computed/dynamic attributes.
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
# ❌ WILL FAIL: Pickle cannot serialize computed fields
|
|
213
|
+
from pydantic import BaseModel, computed_field
|
|
214
|
+
|
|
215
|
+
class CustomerProfile(BaseModel):
|
|
216
|
+
first_name: str
|
|
217
|
+
last_name: str
|
|
218
|
+
|
|
219
|
+
@computed_field
|
|
220
|
+
@property
|
|
221
|
+
def full_name(self) -> str:
|
|
222
|
+
return f"{self.first_name} {self.last_name}"
|
|
223
|
+
|
|
224
|
+
@st.cache_data(ttl=timedelta(minutes=30))
|
|
225
|
+
def get_cached_profile(account: str) -> CustomerProfile:
|
|
226
|
+
return service.lookup(account) # 💥 UnpicklingError on cache hit
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Fix — Use JSON serialization layer:**
|
|
230
|
+
```python
|
|
231
|
+
# ✅ CORRECT: Serialize to JSON, deserialize on read
|
|
232
|
+
@st.cache_data(ttl=timedelta(minutes=30))
|
|
233
|
+
def _get_profile_json(account: str) -> str:
|
|
234
|
+
"""Cache stores JSON string (always picklable)."""
|
|
235
|
+
profile = service.lookup(account)
|
|
236
|
+
return profile.model_dump_json()
|
|
237
|
+
|
|
238
|
+
def get_cached_profile(account: str) -> CustomerProfile:
|
|
239
|
+
"""Public API — returns reconstructed Pydantic model."""
|
|
240
|
+
json_str = _get_profile_json(account)
|
|
241
|
+
return CustomerProfile.model_validate_json(json_str)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Rule: Never use `@st.cache_data` directly on functions returning Pydantic models with computed fields. Always use a JSON serialization layer.**
|
|
245
|
+
|
|
246
|
+
### Gotcha 2: `@st.cache_resource` + Streamlit Hot-Reload = Type Mismatch
|
|
247
|
+
|
|
248
|
+
`@st.cache_resource` returns a **singleton reference**. When Streamlit hot-reloads (code change, file save), Python re-imports all modules, creating **new class definitions**. But the cached singleton still holds an instance of the **old** class. This causes `isinstance()` checks and Pydantic `model_validate()` to fail with confusing `ValidationError`s.
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
# ❌ DANGEROUS: Cached resource survives hot-reload, class identity changes
|
|
252
|
+
@st.cache_resource
|
|
253
|
+
def get_service() -> CustomerLookupService:
|
|
254
|
+
return CustomerLookupService()
|
|
255
|
+
|
|
256
|
+
# After hot-reload, this service holds old CustomerInfo class
|
|
257
|
+
# Any isinstance() or Pydantic validation against new CustomerInfo fails
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Fix — Use `@st.cache_resource` only for stateless adapters, never for services that return typed domain objects:**
|
|
261
|
+
```python
|
|
262
|
+
# ✅ SAFE: Cache the stateless adapter, create service fresh
|
|
263
|
+
@st.cache_resource
|
|
264
|
+
def get_db_adapter():
|
|
265
|
+
return DatabaseAdapter() # Stateless, no typed domain objects
|
|
266
|
+
|
|
267
|
+
def get_service() -> CustomerLookupService:
|
|
268
|
+
"""Fresh service instance — uses cached adapter underneath."""
|
|
269
|
+
return CustomerLookupService(adapter=get_db_adapter())
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Rule: `@st.cache_resource` is safe for stateless I/O objects (DB adapters, HTTP clients, ML models). It is NOT safe for services that construct and return Pydantic/dataclass instances.**
|
|
273
|
+
|
|
274
|
+
### Gotcha 3: Caching Objects That Hold References to Session State
|
|
275
|
+
|
|
276
|
+
Objects stored in `@st.cache_resource` must NEVER reference `st.session_state`. Session state is per-user; cached resources are shared across all users.
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
# ❌ BAD: Leaks one user's state to all users
|
|
280
|
+
@st.cache_resource
|
|
281
|
+
def get_service():
|
|
282
|
+
service = MyService()
|
|
283
|
+
service.user = st.session_state.get("current_user") # 💥 Shared!
|
|
284
|
+
return service
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Gotcha 4: Don't Cache What Shouldn't Be Cached (YAGNI)
|
|
288
|
+
|
|
289
|
+
Not everything benefits from caching. Apply the KISS principle:
|
|
290
|
+
|
|
291
|
+
| Should Cache | Should NOT Cache |
|
|
292
|
+
|-------------|-----------------|
|
|
293
|
+
| Expensive DB queries (>500ms) | Lightweight dict lookups |
|
|
294
|
+
| ML model loading | Simple string formatting |
|
|
295
|
+
| External API calls | Already-loaded DataFrame filtering |
|
|
296
|
+
| Aggregate computations | Session-specific data |
|
|
297
|
+
|
|
298
|
+
**Rule: Measure before caching. If the uncached operation takes <100ms, caching adds complexity for zero benefit.**
|
|
299
|
+
|
|
300
|
+
### Gotcha 5: Overlapping Model Fields (Data Deduplication)
|
|
301
|
+
|
|
302
|
+
When a model has multiple fields that can resolve to the same value (e.g., `display_phone` and `mobile_number` both containing the mobile number for mobile-only customers), the **UI must deduplicate** before display.
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
# ❌ BAD: Shows same number twice
|
|
306
|
+
st.caption(f"📞 {profile.display_phone}")
|
|
307
|
+
st.caption(f"📱 {profile.mobile_number}")
|
|
308
|
+
|
|
309
|
+
# ✅ GOOD: Deduplicate at display time
|
|
310
|
+
phones = {}
|
|
311
|
+
if profile.display_phone:
|
|
312
|
+
phones[profile.display_phone] = "📞"
|
|
313
|
+
if profile.mobile_number and profile.mobile_number != profile.display_phone:
|
|
314
|
+
phones[profile.mobile_number] = "📱"
|
|
315
|
+
for number, icon in phones.items():
|
|
316
|
+
st.caption(f"{icon} {number}")
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Gotcha 6: Stale Shell HTML Causes Chunk 404s After Deploy
|
|
320
|
+
|
|
321
|
+
Symptom:
|
|
322
|
+
- Browser error: `Failed to fetch dynamically imported module: .../assets/<chunk>.js`
|
|
323
|
+
- Requested chunk hash does not exist on server.
|
|
324
|
+
|
|
325
|
+
Root cause:
|
|
326
|
+
- Cached `index.html` references old chunk hash names from prior build.
|
|
327
|
+
|
|
328
|
+
Mitigation:
|
|
329
|
+
1. Enforce shell/asset split cache policy from Step 6.
|
|
330
|
+
2. Keep route/module imports behind retry-capable lazy loaders.
|
|
331
|
+
3. Auto-reload once on chunk-load error, then stop and show retry prompt.
|
|
332
|
+
|
|
333
|
+
### Gotcha 7: Long-Lived Sessions Miss Deploys (Dashboard Left Open)
|
|
334
|
+
|
|
335
|
+
Symptom:
|
|
336
|
+
- User leaves dashboard tab open for hours/days (common with executives).
|
|
337
|
+
- After a deploy, the old main bundle references chunk hashes that no longer exist on disk.
|
|
338
|
+
- Navigating between tabs triggers `Failed to fetch dynamically imported module` errors.
|
|
339
|
+
- Reactive chunk recovery (Gotcha 6) helps but only fires on error — user already sees a broken state.
|
|
340
|
+
|
|
341
|
+
Root cause:
|
|
342
|
+
- The browser loaded the main bundle at time T. A deploy at T+N produced new chunk hashes. The running bundle still references the old hashes.
|
|
343
|
+
|
|
344
|
+
**Why not Service Workers?** Service workers (e.g. `vite-plugin-pwa`) are the industry standard for cache management but require HTTPS. Intranet apps on plain HTTP (e.g. IIS on internal hostnames) cannot register a service worker. Use the 3-layer approach below instead.
|
|
345
|
+
|
|
346
|
+
Mitigation (3-layer proactive version detection — zero-gap):
|
|
347
|
+
1. **Build-time**: Emit `version.json` to `dist/` with a unique build ID. Inject the same ID as `import.meta.env.VITE_BUILD_VERSION`.
|
|
348
|
+
2. **Router `beforeLoad`**: Check version on every route navigation via a shared `version-check.ts` module. This is the critical layer — it catches stale chunks **before** they are requested, not after.
|
|
349
|
+
3. **Periodic polling (60 s)** + **`visibilitychange`**: A React hook polls every 60 seconds and on tab refocus. Handles the idle-tab and tab-switch-back scenarios.
|
|
350
|
+
4. **Update strategy**:
|
|
351
|
+
- Background tab → `window.location.reload()` silently.
|
|
352
|
+
- Foreground tab → brief "Updating…" toast, reload after ~3 seconds.
|
|
353
|
+
5. **Loop prevention**: Store reloaded version in `sessionStorage`. Skip reload if session already reloaded for that version.
|
|
354
|
+
6. **Fetch hygiene**: Use `cache: "no-store"` + `_t=<timestamp>` query param to bypass HTTP cache for `version.json`. Shared module caches fetch results for 30 s so rapid tab switches don't hammer the server.
|
|
355
|
+
|
|
356
|
+
Version JSON should live in the dist root (not under `/assets/`), which means the SPA catch-all serves it — verify no immutable cache header leaks onto it.
|
|
357
|
+
|
|
358
|
+
This pattern is complementary to chunk retry (Step 6 + Gotcha 6) — the 3-layer check prevents the error from happening at all, while retry handles transient network failures.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Checklist
|
|
363
|
+
|
|
364
|
+
- [ ] Data fetches use `@st.cache_data` with appropriate TTL
|
|
365
|
+
- [ ] DB connections use `@st.cache_resource` (no TTL)
|
|
366
|
+
- [ ] Multi-user data returns deep copies (not shared references)
|
|
367
|
+
- [ ] Cache keys include all filter/parameter variations
|
|
368
|
+
- [ ] No mutable objects (dict, list) as cache function parameters
|
|
369
|
+
- [ ] TTL values documented and justified
|
|
370
|
+
- [ ] Cache invalidation strategy for write operations
|
|
371
|
+
- [ ] Performance logging for slow queries
|
|
372
|
+
- [ ] `show_spinner` set on user-facing cached functions
|
|
373
|
+
- [ ] Cache warming for critical dashboard data
|
|
374
|
+
- [ ] **No `@st.cache_data` on Pydantic models with computed fields** (use JSON layer)
|
|
375
|
+
- [ ] **No `@st.cache_resource` on services returning typed domain objects** (hot-reload risk)
|
|
376
|
+
- [ ] **Caching is justified by measurement** (not speculative — YAGNI)
|
|
377
|
+
- [ ] **SPA version polling implemented** for long-lived sessions (Gotcha 7)
|
|
378
|
+
|
|
379
|
+
## Related Resources
|
|
380
|
+
|
|
381
|
+
| Resource | Path |
|
|
382
|
+
|----------|------|
|
|
383
|
+
| Streamlit dev skill | `skills/frontend/streamlit-dev/SKILL.md` |
|
|
384
|
+
| Streamlit instructions | `instructions/streamlit.instructions.md` |
|
|
385
|
+
| SQL expert skill | `skills/coding/sql/SKILL.md` |
|