@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,358 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Authentication Manager for NotebookLM
|
|
4
|
+
Handles Google login and browser state persistence
|
|
5
|
+
Based on the MCP server implementation
|
|
6
|
+
|
|
7
|
+
Implements hybrid auth approach:
|
|
8
|
+
- Persistent browser profile (user_data_dir) for fingerprint consistency
|
|
9
|
+
- Manual cookie injection from state.json for session cookies (Playwright bug workaround)
|
|
10
|
+
See: https://github.com/microsoft/playwright/issues/36139
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import time
|
|
15
|
+
import argparse
|
|
16
|
+
import shutil
|
|
17
|
+
import re
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Optional, Dict, Any
|
|
21
|
+
|
|
22
|
+
from patchright.sync_api import sync_playwright, BrowserContext
|
|
23
|
+
|
|
24
|
+
# Add parent directory to path
|
|
25
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
26
|
+
|
|
27
|
+
from config import BROWSER_STATE_DIR, STATE_FILE, AUTH_INFO_FILE, DATA_DIR
|
|
28
|
+
from browser_utils import BrowserFactory
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class AuthManager:
|
|
32
|
+
"""
|
|
33
|
+
Manages authentication and browser state for NotebookLM
|
|
34
|
+
|
|
35
|
+
Features:
|
|
36
|
+
- Interactive Google login
|
|
37
|
+
- Browser state persistence
|
|
38
|
+
- Session restoration
|
|
39
|
+
- Account switching
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
"""Initialize the authentication manager"""
|
|
44
|
+
# Ensure directories exist
|
|
45
|
+
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
|
46
|
+
BROWSER_STATE_DIR.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
|
|
48
|
+
self.state_file = STATE_FILE
|
|
49
|
+
self.auth_info_file = AUTH_INFO_FILE
|
|
50
|
+
self.browser_state_dir = BROWSER_STATE_DIR
|
|
51
|
+
|
|
52
|
+
def is_authenticated(self) -> bool:
|
|
53
|
+
"""Check if valid authentication exists"""
|
|
54
|
+
if not self.state_file.exists():
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
# Check if state file is not too old (7 days)
|
|
58
|
+
age_days = (time.time() - self.state_file.stat().st_mtime) / 86400
|
|
59
|
+
if age_days > 7:
|
|
60
|
+
print(f"⚠️ Browser state is {age_days:.1f} days old, may need re-authentication")
|
|
61
|
+
|
|
62
|
+
return True
|
|
63
|
+
|
|
64
|
+
def get_auth_info(self) -> Dict[str, Any]:
|
|
65
|
+
"""Get authentication information"""
|
|
66
|
+
info = {
|
|
67
|
+
'authenticated': self.is_authenticated(),
|
|
68
|
+
'state_file': str(self.state_file),
|
|
69
|
+
'state_exists': self.state_file.exists()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if self.auth_info_file.exists():
|
|
73
|
+
try:
|
|
74
|
+
with open(self.auth_info_file, 'r') as f:
|
|
75
|
+
saved_info = json.load(f)
|
|
76
|
+
info.update(saved_info)
|
|
77
|
+
except Exception:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
if info['state_exists']:
|
|
81
|
+
age_hours = (time.time() - self.state_file.stat().st_mtime) / 3600
|
|
82
|
+
info['state_age_hours'] = age_hours
|
|
83
|
+
|
|
84
|
+
return info
|
|
85
|
+
|
|
86
|
+
def setup_auth(self, headless: bool = False, timeout_minutes: int = 10) -> bool:
|
|
87
|
+
"""
|
|
88
|
+
Perform interactive authentication setup
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
headless: Run browser in headless mode (False for login)
|
|
92
|
+
timeout_minutes: Maximum time to wait for login
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
True if authentication successful
|
|
96
|
+
"""
|
|
97
|
+
print("🔐 Starting authentication setup...")
|
|
98
|
+
print(f" Timeout: {timeout_minutes} minutes")
|
|
99
|
+
|
|
100
|
+
playwright = None
|
|
101
|
+
context = None
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
playwright = sync_playwright().start()
|
|
105
|
+
|
|
106
|
+
# Launch using factory
|
|
107
|
+
context = BrowserFactory.launch_persistent_context(
|
|
108
|
+
playwright,
|
|
109
|
+
headless=headless
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Navigate to NotebookLM
|
|
113
|
+
page = context.new_page()
|
|
114
|
+
page.goto("https://notebooklm.google.com", wait_until="domcontentloaded")
|
|
115
|
+
|
|
116
|
+
# Check if already authenticated
|
|
117
|
+
if "notebooklm.google.com" in page.url and "accounts.google.com" not in page.url:
|
|
118
|
+
print(" ✅ Already authenticated!")
|
|
119
|
+
self._save_browser_state(context)
|
|
120
|
+
return True
|
|
121
|
+
|
|
122
|
+
# Wait for manual login
|
|
123
|
+
print("\n ⏳ Please log in to your Google account...")
|
|
124
|
+
print(f" ⏱️ Waiting up to {timeout_minutes} minutes for login...")
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
# Wait for URL to change to NotebookLM (regex ensures it's the actual domain, not a parameter)
|
|
128
|
+
timeout_ms = int(timeout_minutes * 60 * 1000)
|
|
129
|
+
page.wait_for_url(re.compile(r"^https://notebooklm\.google\.com/"), timeout=timeout_ms)
|
|
130
|
+
|
|
131
|
+
print(f" ✅ Login successful!")
|
|
132
|
+
|
|
133
|
+
# Save authentication state
|
|
134
|
+
self._save_browser_state(context)
|
|
135
|
+
self._save_auth_info()
|
|
136
|
+
return True
|
|
137
|
+
|
|
138
|
+
except Exception as e:
|
|
139
|
+
print(f" ❌ Authentication timeout: {e}")
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
except Exception as e:
|
|
143
|
+
print(f" ❌ Error: {e}")
|
|
144
|
+
return False
|
|
145
|
+
|
|
146
|
+
finally:
|
|
147
|
+
# Clean up browser resources
|
|
148
|
+
if context:
|
|
149
|
+
try:
|
|
150
|
+
context.close()
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
if playwright:
|
|
155
|
+
try:
|
|
156
|
+
playwright.stop()
|
|
157
|
+
except Exception:
|
|
158
|
+
pass
|
|
159
|
+
|
|
160
|
+
def _save_browser_state(self, context: BrowserContext):
|
|
161
|
+
"""Save browser state to disk"""
|
|
162
|
+
try:
|
|
163
|
+
# Save storage state (cookies, localStorage)
|
|
164
|
+
context.storage_state(path=str(self.state_file))
|
|
165
|
+
print(f" 💾 Saved browser state to: {self.state_file}")
|
|
166
|
+
except Exception as e:
|
|
167
|
+
print(f" ❌ Failed to save browser state: {e}")
|
|
168
|
+
raise
|
|
169
|
+
|
|
170
|
+
def _save_auth_info(self):
|
|
171
|
+
"""Save authentication metadata"""
|
|
172
|
+
try:
|
|
173
|
+
info = {
|
|
174
|
+
'authenticated_at': time.time(),
|
|
175
|
+
'authenticated_at_iso': time.strftime('%Y-%m-%d %H:%M:%S')
|
|
176
|
+
}
|
|
177
|
+
with open(self.auth_info_file, 'w') as f:
|
|
178
|
+
json.dump(info, f, indent=2)
|
|
179
|
+
except Exception:
|
|
180
|
+
pass # Non-critical
|
|
181
|
+
|
|
182
|
+
def clear_auth(self) -> bool:
|
|
183
|
+
"""
|
|
184
|
+
Clear all authentication data
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
True if cleared successfully
|
|
188
|
+
"""
|
|
189
|
+
print("🗑️ Clearing authentication data...")
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
# Remove browser state
|
|
193
|
+
if self.state_file.exists():
|
|
194
|
+
self.state_file.unlink()
|
|
195
|
+
print(" ✅ Removed browser state")
|
|
196
|
+
|
|
197
|
+
# Remove auth info
|
|
198
|
+
if self.auth_info_file.exists():
|
|
199
|
+
self.auth_info_file.unlink()
|
|
200
|
+
print(" ✅ Removed auth info")
|
|
201
|
+
|
|
202
|
+
# Clear entire browser state directory
|
|
203
|
+
if self.browser_state_dir.exists():
|
|
204
|
+
shutil.rmtree(self.browser_state_dir)
|
|
205
|
+
self.browser_state_dir.mkdir(parents=True, exist_ok=True)
|
|
206
|
+
print(" ✅ Cleared browser data")
|
|
207
|
+
|
|
208
|
+
return True
|
|
209
|
+
|
|
210
|
+
except Exception as e:
|
|
211
|
+
print(f" ❌ Error clearing auth: {e}")
|
|
212
|
+
return False
|
|
213
|
+
|
|
214
|
+
def re_auth(self, headless: bool = False, timeout_minutes: int = 10) -> bool:
|
|
215
|
+
"""
|
|
216
|
+
Perform re-authentication (clear and setup)
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
headless: Run browser in headless mode
|
|
220
|
+
timeout_minutes: Login timeout in minutes
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
True if successful
|
|
224
|
+
"""
|
|
225
|
+
print("🔄 Starting re-authentication...")
|
|
226
|
+
|
|
227
|
+
# Clear existing auth
|
|
228
|
+
self.clear_auth()
|
|
229
|
+
|
|
230
|
+
# Setup new auth
|
|
231
|
+
return self.setup_auth(headless, timeout_minutes)
|
|
232
|
+
|
|
233
|
+
def validate_auth(self) -> bool:
|
|
234
|
+
"""
|
|
235
|
+
Validate that stored authentication works
|
|
236
|
+
Uses persistent context to match actual usage pattern
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
True if authentication is valid
|
|
240
|
+
"""
|
|
241
|
+
if not self.is_authenticated():
|
|
242
|
+
return False
|
|
243
|
+
|
|
244
|
+
print("🔍 Validating authentication...")
|
|
245
|
+
|
|
246
|
+
playwright = None
|
|
247
|
+
context = None
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
playwright = sync_playwright().start()
|
|
251
|
+
|
|
252
|
+
# Launch using factory
|
|
253
|
+
context = BrowserFactory.launch_persistent_context(
|
|
254
|
+
playwright,
|
|
255
|
+
headless=True
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
# Try to access NotebookLM
|
|
259
|
+
page = context.new_page()
|
|
260
|
+
page.goto("https://notebooklm.google.com", wait_until="domcontentloaded", timeout=30000)
|
|
261
|
+
|
|
262
|
+
# Check if we can access NotebookLM
|
|
263
|
+
if "notebooklm.google.com" in page.url and "accounts.google.com" not in page.url:
|
|
264
|
+
print(" ✅ Authentication is valid")
|
|
265
|
+
return True
|
|
266
|
+
else:
|
|
267
|
+
print(" ❌ Authentication is invalid (redirected to login)")
|
|
268
|
+
return False
|
|
269
|
+
|
|
270
|
+
except Exception as e:
|
|
271
|
+
print(f" ❌ Validation failed: {e}")
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
finally:
|
|
275
|
+
if context:
|
|
276
|
+
try:
|
|
277
|
+
context.close()
|
|
278
|
+
except Exception:
|
|
279
|
+
pass
|
|
280
|
+
if playwright:
|
|
281
|
+
try:
|
|
282
|
+
playwright.stop()
|
|
283
|
+
except Exception:
|
|
284
|
+
pass
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def main():
|
|
288
|
+
"""Command-line interface for authentication management"""
|
|
289
|
+
parser = argparse.ArgumentParser(description='Manage NotebookLM authentication')
|
|
290
|
+
|
|
291
|
+
subparsers = parser.add_subparsers(dest='command', help='Commands')
|
|
292
|
+
|
|
293
|
+
# Setup command
|
|
294
|
+
setup_parser = subparsers.add_parser('setup', help='Setup authentication')
|
|
295
|
+
setup_parser.add_argument('--headless', action='store_true', help='Run in headless mode')
|
|
296
|
+
setup_parser.add_argument('--timeout', type=float, default=10, help='Login timeout in minutes (default: 10)')
|
|
297
|
+
|
|
298
|
+
# Status command
|
|
299
|
+
subparsers.add_parser('status', help='Check authentication status')
|
|
300
|
+
|
|
301
|
+
# Validate command
|
|
302
|
+
subparsers.add_parser('validate', help='Validate authentication')
|
|
303
|
+
|
|
304
|
+
# Clear command
|
|
305
|
+
subparsers.add_parser('clear', help='Clear authentication')
|
|
306
|
+
|
|
307
|
+
# Re-auth command
|
|
308
|
+
reauth_parser = subparsers.add_parser('reauth', help='Re-authenticate (clear + setup)')
|
|
309
|
+
reauth_parser.add_argument('--timeout', type=float, default=10, help='Login timeout in minutes (default: 10)')
|
|
310
|
+
|
|
311
|
+
args = parser.parse_args()
|
|
312
|
+
|
|
313
|
+
# Initialize manager
|
|
314
|
+
auth = AuthManager()
|
|
315
|
+
|
|
316
|
+
# Execute command
|
|
317
|
+
if args.command == 'setup':
|
|
318
|
+
if auth.setup_auth(headless=args.headless, timeout_minutes=args.timeout):
|
|
319
|
+
print("\n✅ Authentication setup complete!")
|
|
320
|
+
print("You can now use ask_question.py to query NotebookLM")
|
|
321
|
+
else:
|
|
322
|
+
print("\n❌ Authentication setup failed")
|
|
323
|
+
exit(1)
|
|
324
|
+
|
|
325
|
+
elif args.command == 'status':
|
|
326
|
+
info = auth.get_auth_info()
|
|
327
|
+
print("\n🔐 Authentication Status:")
|
|
328
|
+
print(f" Authenticated: {'Yes' if info['authenticated'] else 'No'}")
|
|
329
|
+
if info.get('state_age_hours'):
|
|
330
|
+
print(f" State age: {info['state_age_hours']:.1f} hours")
|
|
331
|
+
if info.get('authenticated_at_iso'):
|
|
332
|
+
print(f" Last auth: {info['authenticated_at_iso']}")
|
|
333
|
+
print(f" State file: {info['state_file']}")
|
|
334
|
+
|
|
335
|
+
elif args.command == 'validate':
|
|
336
|
+
if auth.validate_auth():
|
|
337
|
+
print("Authentication is valid and working")
|
|
338
|
+
else:
|
|
339
|
+
print("Authentication is invalid or expired")
|
|
340
|
+
print("Run: auth_manager.py setup")
|
|
341
|
+
|
|
342
|
+
elif args.command == 'clear':
|
|
343
|
+
if auth.clear_auth():
|
|
344
|
+
print("Authentication cleared")
|
|
345
|
+
|
|
346
|
+
elif args.command == 'reauth':
|
|
347
|
+
if auth.re_auth(timeout_minutes=args.timeout):
|
|
348
|
+
print("\n✅ Re-authentication complete!")
|
|
349
|
+
else:
|
|
350
|
+
print("\n❌ Re-authentication failed")
|
|
351
|
+
exit(1)
|
|
352
|
+
|
|
353
|
+
else:
|
|
354
|
+
parser.print_help()
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
if __name__ == "__main__":
|
|
358
|
+
main()
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Browser Session Management for NotebookLM
|
|
4
|
+
Individual browser session for persistent NotebookLM conversations
|
|
5
|
+
Based on the original NotebookLM API implementation
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
import sys
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from patchright.sync_api import BrowserContext, Page
|
|
14
|
+
|
|
15
|
+
# Add parent directory to path
|
|
16
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
17
|
+
|
|
18
|
+
from browser_utils import StealthUtils
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class BrowserSession:
|
|
22
|
+
"""
|
|
23
|
+
Represents a single persistent browser session for NotebookLM
|
|
24
|
+
|
|
25
|
+
Each session gets its own Page (tab) within a shared BrowserContext,
|
|
26
|
+
allowing for contextual conversations where NotebookLM remembers
|
|
27
|
+
previous messages.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, session_id: str, context: BrowserContext, notebook_url: str):
|
|
31
|
+
"""
|
|
32
|
+
Initialize a new browser session
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
session_id: Unique identifier for this session
|
|
36
|
+
context: Browser context (shared or dedicated)
|
|
37
|
+
notebook_url: Target NotebookLM URL for this session
|
|
38
|
+
"""
|
|
39
|
+
self.id = session_id
|
|
40
|
+
self.created_at = time.time()
|
|
41
|
+
self.last_activity = time.time()
|
|
42
|
+
self.message_count = 0
|
|
43
|
+
self.notebook_url = notebook_url
|
|
44
|
+
self.context = context
|
|
45
|
+
self.page = None
|
|
46
|
+
self.stealth = StealthUtils()
|
|
47
|
+
|
|
48
|
+
# Initialize the session
|
|
49
|
+
self._initialize()
|
|
50
|
+
|
|
51
|
+
def _initialize(self):
|
|
52
|
+
"""Initialize the browser session and navigate to NotebookLM"""
|
|
53
|
+
print(f"🚀 Creating session {self.id}...")
|
|
54
|
+
|
|
55
|
+
# Create new page (tab) in context
|
|
56
|
+
self.page = self.context.new_page()
|
|
57
|
+
print(f" 🌐 Navigating to NotebookLM...")
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
# Navigate to notebook
|
|
61
|
+
self.page.goto(self.notebook_url, wait_until="domcontentloaded", timeout=30000)
|
|
62
|
+
|
|
63
|
+
# Check if login is needed
|
|
64
|
+
if "accounts.google.com" in self.page.url:
|
|
65
|
+
raise RuntimeError("Authentication required. Please run auth_manager.py setup first.")
|
|
66
|
+
|
|
67
|
+
# Wait for page to be ready
|
|
68
|
+
self._wait_for_ready()
|
|
69
|
+
|
|
70
|
+
# Simulate human inspection
|
|
71
|
+
self.stealth.random_mouse_movement(self.page)
|
|
72
|
+
self.stealth.random_delay(300, 600)
|
|
73
|
+
|
|
74
|
+
print(f"✅ Session {self.id} ready!")
|
|
75
|
+
|
|
76
|
+
except Exception as e:
|
|
77
|
+
print(f"❌ Failed to initialize session: {e}")
|
|
78
|
+
if self.page:
|
|
79
|
+
self.page.close()
|
|
80
|
+
raise
|
|
81
|
+
|
|
82
|
+
def _wait_for_ready(self):
|
|
83
|
+
"""Wait for NotebookLM page to be ready"""
|
|
84
|
+
try:
|
|
85
|
+
# Wait for chat input
|
|
86
|
+
self.page.wait_for_selector("textarea.query-box-input", timeout=10000, state="visible")
|
|
87
|
+
except Exception:
|
|
88
|
+
# Try alternative selector
|
|
89
|
+
self.page.wait_for_selector('textarea[aria-label="Feld für Anfragen"]', timeout=5000, state="visible")
|
|
90
|
+
|
|
91
|
+
def ask(self, question: str) -> Dict[str, Any]:
|
|
92
|
+
"""
|
|
93
|
+
Ask a question in this session
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
question: The question to ask
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Dict with status, question, answer, session_id
|
|
100
|
+
"""
|
|
101
|
+
try:
|
|
102
|
+
self.last_activity = time.time()
|
|
103
|
+
self.message_count += 1
|
|
104
|
+
|
|
105
|
+
print(f"💬 [{self.id}] Asking: {question}")
|
|
106
|
+
|
|
107
|
+
# Snapshot current answer to detect new response
|
|
108
|
+
previous_answer = self._snapshot_latest_response()
|
|
109
|
+
|
|
110
|
+
# Find chat input
|
|
111
|
+
chat_input_selector = "textarea.query-box-input"
|
|
112
|
+
try:
|
|
113
|
+
self.page.wait_for_selector(chat_input_selector, timeout=5000, state="visible")
|
|
114
|
+
except Exception:
|
|
115
|
+
chat_input_selector = 'textarea[aria-label="Feld für Anfragen"]'
|
|
116
|
+
self.page.wait_for_selector(chat_input_selector, timeout=5000, state="visible")
|
|
117
|
+
|
|
118
|
+
# Click and type with human-like behavior
|
|
119
|
+
self.stealth.realistic_click(self.page, chat_input_selector)
|
|
120
|
+
self.stealth.human_type(self.page, chat_input_selector, question)
|
|
121
|
+
|
|
122
|
+
# Small pause before submit
|
|
123
|
+
self.stealth.random_delay(300, 800)
|
|
124
|
+
|
|
125
|
+
# Submit
|
|
126
|
+
self.page.keyboard.press("Enter")
|
|
127
|
+
|
|
128
|
+
# Wait for response
|
|
129
|
+
print(" ⏳ Waiting for response...")
|
|
130
|
+
self.stealth.random_delay(1500, 3000)
|
|
131
|
+
|
|
132
|
+
# Get new answer
|
|
133
|
+
answer = self._wait_for_latest_answer(previous_answer)
|
|
134
|
+
|
|
135
|
+
if not answer:
|
|
136
|
+
raise Exception("Empty response from NotebookLM")
|
|
137
|
+
|
|
138
|
+
print(f" ✅ Got response ({len(answer)} chars)")
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
"status": "success",
|
|
142
|
+
"question": question,
|
|
143
|
+
"answer": answer,
|
|
144
|
+
"session_id": self.id,
|
|
145
|
+
"notebook_url": self.notebook_url
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
except Exception as e:
|
|
149
|
+
print(f" ❌ Error: {e}")
|
|
150
|
+
return {
|
|
151
|
+
"status": "error",
|
|
152
|
+
"question": question,
|
|
153
|
+
"error": str(e),
|
|
154
|
+
"session_id": self.id
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
def _snapshot_latest_response(self) -> Optional[str]:
|
|
158
|
+
"""Get the current latest response text"""
|
|
159
|
+
try:
|
|
160
|
+
# Use correct NotebookLM selector
|
|
161
|
+
responses = self.page.query_selector_all(".to-user-container .message-text-content")
|
|
162
|
+
if responses:
|
|
163
|
+
return responses[-1].inner_text()
|
|
164
|
+
except Exception:
|
|
165
|
+
pass
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
def _wait_for_latest_answer(self, previous_answer: Optional[str], timeout: int = 120) -> str:
|
|
169
|
+
"""Wait for and extract the new answer"""
|
|
170
|
+
start_time = time.time()
|
|
171
|
+
last_candidate = None
|
|
172
|
+
stable_count = 0
|
|
173
|
+
|
|
174
|
+
while time.time() - start_time < timeout:
|
|
175
|
+
# Check if NotebookLM is still thinking (most reliable indicator)
|
|
176
|
+
try:
|
|
177
|
+
thinking_element = self.page.query_selector('div.thinking-message')
|
|
178
|
+
if thinking_element and thinking_element.is_visible():
|
|
179
|
+
time.sleep(0.5)
|
|
180
|
+
continue
|
|
181
|
+
except Exception:
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
# Use correct NotebookLM selector
|
|
186
|
+
responses = self.page.query_selector_all(".to-user-container .message-text-content")
|
|
187
|
+
|
|
188
|
+
if responses:
|
|
189
|
+
latest_text = responses[-1].inner_text().strip()
|
|
190
|
+
|
|
191
|
+
# Check if it's a new response
|
|
192
|
+
if latest_text and latest_text != previous_answer:
|
|
193
|
+
# Check if text is stable (3 consecutive polls)
|
|
194
|
+
if latest_text == last_candidate:
|
|
195
|
+
stable_count += 1
|
|
196
|
+
if stable_count >= 3:
|
|
197
|
+
return latest_text
|
|
198
|
+
else:
|
|
199
|
+
stable_count = 1
|
|
200
|
+
last_candidate = latest_text
|
|
201
|
+
|
|
202
|
+
except Exception:
|
|
203
|
+
pass
|
|
204
|
+
|
|
205
|
+
time.sleep(0.5)
|
|
206
|
+
|
|
207
|
+
raise TimeoutError(f"No response received within {timeout} seconds")
|
|
208
|
+
|
|
209
|
+
def reset(self):
|
|
210
|
+
"""Reset the chat by reloading the page"""
|
|
211
|
+
print(f"🔄 Resetting session {self.id}...")
|
|
212
|
+
|
|
213
|
+
self.page.reload(wait_until="domcontentloaded")
|
|
214
|
+
self._wait_for_ready()
|
|
215
|
+
|
|
216
|
+
previous_count = self.message_count
|
|
217
|
+
self.message_count = 0
|
|
218
|
+
self.last_activity = time.time()
|
|
219
|
+
|
|
220
|
+
print(f"✅ Session reset (cleared {previous_count} messages)")
|
|
221
|
+
return previous_count
|
|
222
|
+
|
|
223
|
+
def close(self):
|
|
224
|
+
"""Close this session and clean up resources"""
|
|
225
|
+
print(f"🛑 Closing session {self.id}...")
|
|
226
|
+
|
|
227
|
+
if self.page:
|
|
228
|
+
try:
|
|
229
|
+
self.page.close()
|
|
230
|
+
except Exception as e:
|
|
231
|
+
print(f" ⚠️ Error closing page: {e}")
|
|
232
|
+
|
|
233
|
+
print(f"✅ Session {self.id} closed")
|
|
234
|
+
|
|
235
|
+
def get_info(self) -> Dict[str, Any]:
|
|
236
|
+
"""Get information about this session"""
|
|
237
|
+
return {
|
|
238
|
+
"id": self.id,
|
|
239
|
+
"created_at": self.created_at,
|
|
240
|
+
"last_activity": self.last_activity,
|
|
241
|
+
"age_seconds": time.time() - self.created_at,
|
|
242
|
+
"inactive_seconds": time.time() - self.last_activity,
|
|
243
|
+
"message_count": self.message_count,
|
|
244
|
+
"notebook_url": self.notebook_url
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
def is_expired(self, timeout_seconds: int = 900) -> bool:
|
|
248
|
+
"""Check if session has expired (default: 15 minutes)"""
|
|
249
|
+
return (time.time() - self.last_activity) > timeout_seconds
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
if __name__ == "__main__":
|
|
253
|
+
# Example usage
|
|
254
|
+
print("Browser Session Module - Use ask_question.py for main interface")
|
|
255
|
+
print("This module provides low-level browser session management.")
|