mcp-gee-sweet 0.8.2.dev258__tar.gz → 0.8.2.dev259__tar.gz
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.
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/CLAUDE.md +1 -1
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/PKG-INFO +1 -1
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/transfer.py +29 -7
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/cleanup-worktrees.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/merge-pr.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/orchestrator.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/prep-for-pr.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/qa-kickoff.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/release.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/retro.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/start-worktree.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/team-member.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/verify-pr.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/settings.json +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/amy.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/aziz.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/bob.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/dev.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/joy.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/kai.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/team-roles/qa.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.dockerignore +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/dependabot.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/workflows/ci.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/workflows/docs.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/workflows/publish-dev.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/workflows/release.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.gitignore +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.pre-commit-config.yaml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.python-version +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/CHANGELOG.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/CODE_OF_CONDUCT.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/CONTRIBUTING.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/Dockerfile +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/LICENSE +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/Makefile +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/README.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/SECURITY.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docker-compose.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/auth.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/client-setup.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/configuration.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-async-tool-execution.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-auth-status-limitation-categories.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-cache-invalidation.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-chart-theming.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-composite-tools.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-dev-team.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-docs-formatting.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-fork.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-grid-data-size-cap.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-prompt-qa-role.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-publishing.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-release-docs-roles.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-repositioning.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-response-size-cap-generalization.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-sync-folder-recursion.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-testing.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/index.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/borderless-table-columns.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/docs-ast-pipeline.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/effectiveformat-spike.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/heading-anchor-resolution.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/image-conversion.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/index.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/markdown-support.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/phase3-theme-system.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/index.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/known-limitations.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/notes-read.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/README.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/qa-fixture-pixel.png +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d195-create-doc.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d196-create-doc.html +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d213-dollar-escape.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d226-heading-table.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc102-image-conversion.html +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc103-image-conversion.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc104-nested-lists.html +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc105-nested-lists-gfm.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc106-nested-lists-4space.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc135-paragraph-boundary.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc136-interrupted-block-boundary.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc137-inline-hr-no-block-ancestor.html +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc138-nbsp-spacer-paragraph.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc141-mismatched-list-tags.html +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc142-heading-anchors.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc144-anchor-in-table-cell.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-doc145-anchor-on-first-element.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures.template.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/operations.yaml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/playwright_oauth.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/.gitkeep +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-02.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-14.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-17.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-18.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-21-drive-discovery.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-21-sheets-delete-clear.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-06-28.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-docs.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-drive-smoke.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-infra.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-sheets_read.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/retro-v0.8.0.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/run.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/runs/README.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/runs/v0.8.0.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/runs/v0.8.1.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/setup.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/calendar.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/docs.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/drive.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/infra.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/sheets_charts.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/sheets_mgmt.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/sheets_read.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/tests/sheets_write.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/roadmap.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/style-guide.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/tools.md +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/mkdocs.yml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/pyproject.toml +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/pyrightconfig.json +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/scripts/gen_tool_docs.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/scripts/oauth_setup.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/scripts/setup_team.sh +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/.env.template +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/auth.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/cache.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/http_transport.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/server.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/cache.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/calendar.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/anchors.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/ast.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/comments.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/content.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/emitter.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/html_parser.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/indices.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/layout.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/style.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/tables.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/activity.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/files.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/sharing.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/response_limits.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/data.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/helpers.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/structure.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/drive/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/drive/test_activity.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/drive/test_files.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/drive/test_sharing.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/drive/test_transfer.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/sheets/__init__.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/sheets/test_data.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/sheets/test_helpers.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/sheets/test_structure.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_auth.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_cache.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_calendar.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_anchors.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_comments.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_content.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_core.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_layout.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_style.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_docs_tables.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_gen_tool_docs.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_response_limits.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/tests/test_server.py +0 -0
- {mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/uv.lock +0 -0
|
@@ -36,7 +36,7 @@ Logic is split across `src/mcp_gee_sweet/`: `server.py` (MCP setup, tool decorat
|
|
|
36
36
|
- `tools/sheets/helpers.py` — A1 notation helpers (`_parse_a1_notation`, `_column_index_to_letter`, etc.)
|
|
37
37
|
- `tools/drive/files.py` — file/folder operations (`create_spreadsheet`, `import_csv_to_sheet`, `list_spreadsheets`, `list_files`, `search_files`, `create_folder`, `create_shortcut`, `copy_file`, `move_file`, `rename_file`, `star_file`, `unstar_file`, `delete_file`, `restore_file`, `empty_trash`, `list_shared_with_me`, `list_recent_files`, `get_storage_quota`, etc.). `star_file`/`unstar_file` (#139) set `starred` via `files().update` — neither `get_file_metadata` nor `list_files` currently exposes the `starred` field back, so live QA verification is round-trip only (see TC-D202/203 in `docs/qa/tests/drive.md`). Both `list_files` and `get_file_metadata` now surface Drive's `md5Checksum` field as `md5_checksum` (#274) — `None` for Google Workspace files (Docs/Sheets/Slides have no fixed byte content, so the Drive API omits the field for them), a real hash for binary files. Exists so callers can detect real content drift instead of inferring it from `modifiedTime`, which sync/upload paths don't always keep faithful to actual content (see `transfer.py`'s `sync_folder` `use_checksum` param below, the primary consumer of this).
|
|
38
38
|
- `tools/drive/sharing.py` — permissions (`share_spreadsheet`, `share_file`, `list_permissions`, `update_permission`, `remove_permission`, `transfer_ownership`). `transfer_ownership` requires OAuth — service accounts have no personal Drive identity to transfer ownership to/from, so Drive's API rejects the transfer.
|
|
39
|
-
- `tools/drive/transfer.py` — upload/download/sync/export/revisions; `_upload_local_file` (the core behind the `upload_local_file` tool) is a module-level helper so `docs/content.py`'s `insert_local_images` can call it directly, imported cross-package the same way `docs/content.py` imports `_SA_QUOTA_ERROR` from `tools/drive/__init__.py`. `upload_local_file`'s `convert` param (#188) requests Drive's *native* import conversion — CSV/XLSX→Sheets, DOCX/MD/HTML→Docs, PPTX→Slides — by uploading with the source format's mimeType while setting the destination's `mimeType` metadata to the target Google Workspace type (`_CONVERT_MIME` maps extension → (source mime, target mime)). This is a different mechanism from `docs/content.py`'s `create_doc_from_file`, which parses the file locally and rebuilds it via Docs API requests instead of Drive's importer — don't conflate the two when adding new conversion paths. `sync_folder`'s `convert_markdown` param (#211) applies the same native-conversion mechanism to local `.md` files during sync uploads. Because the converted Doc keeps its `.md` name in Drive, `_sync_level`'s drive_map-building loop matches it back to the local `.md` file directly (bypassing the export_format-suffix scheme normal Workspace files need) so resyncs settle into "in sync" instead of re-uploading a duplicate every run — this also reopens matching for a drive-only converted Doc with no local counterpart and no `export_format` (previously unreachable, since such files were always excluded from `drive_map`) — the plan-building loop classifies that case as a `conflict` (a convert_markdown Doc has no reverse conversion) before it ever reaches the download branch, so the download branch's own `_EXPORT_MIME[None]` guard is defensive-only dead code in the current implementation, not a reachable path (confirmed live: TC-D221). There is no reverse conversion (Doc → markdown). A converted Doc is recognized on every later sync via a Drive `properties` marker (`_CONVERT_MARKDOWN_SOURCE_PROP`) stamped at creation time by both `_sync_level`'s own upload path and `_upload_local_file`'s `convert=True` path (#414 rounds 2-3) — recognition is deliberately independent of whether the *current* call passes `convert_markdown`/`convert`, since the Doc's own persisted property is what matters, not this call's flag. Three further edge cases from that round-3 review shipped as issue #422: the `drive_map`-building loop now detects (rather than silently resolving) a name collision between a plain file and a converted Doc, reporting it under `failed` instead of letting whichever is listed last win the slot and make the other invisible to the sync; `_upload_local_file` now stamps `modifiedTime` from the local file's mtime on a converted Doc (via `create()` then a metadata-only `update()`, mirroring `_sync_level`'s own create() branch, since Drive's native import-conversion overwrites the create()-time value once conversion finishes) so a subsequent `sync_folder` lands in `skipped` rather than `conflicts`; and the drive-only branch now checks `direction` before `_is_converted_md`, so `direction='upload'` reports a plain `skip` like any other drive-only file instead of always reporting `conflict`. PR #433's own review round found the collision guard needed to go further: it originally only fired when the two colliding entries' `_is_converted_md` differed (a plain file vs. a converted Doc, #422's own reported shape), silently overwriting a same-type collision (two plain files, or two converted Docs, sharing a name) the exact same way; it now fires on any duplicate name regardless of type. The collision case is also now routed through the normal `plan`/`action` machinery (a new `"collision"` action, mapped to `conflict` during `dry_run` and to a real `failed` entry — `kind: "collision_fail"` — once execution is actually attempted) rather than writing to `failed` directly from the `drive_map`-building loop: that direct write both leaked into `failed` during `dry_run` (breaking the "dry_run never reports failures, only previews" invariant the pre-existing folder-collision failure path already upholds) and silently dropped a *local* file sharing the colliding name from every result list, since the plan loop's bare `continue` skipped it with zero acknowledgment. Separately, `_upload_local_file`'s `create()`+`update()` pair now shares one broad `except Exception` returning `{"error": ...}` (matching `_sync_level._run_one`'s own create+update pattern) instead of only catching quota `HttpError`s and letting everything else — including a failure in the new metadata-only restamp `update()`, after `create()` already succeeded — propagate uncaught to `upload_local_file`, which has no try/except of its own. `sync_folder`'s `use_checksum` param (#274) adds a content check ahead of `_sync_level`'s mtime comparison for names present on both sides: when the local file's md5 (`_local_md5`, streamed in 1 MiB chunks) matches Drive's own `md5Checksum` (now fetched by `_list_drive_children`), the pair is treated as in sync regardless of `modifiedTime` drift — this is what actually fixes `upload_local_file` not stamping `modifiedTime` (unlike `_sync_level`'s own upload path) causing a spurious re-download of identical content on the next sync, not just a same-mtime coincidence. Only applies where Drive returns a real `md5Checksum` — Workspace files and `convert_markdown` Docs have none and always fall back to mtime-only comparison, flag or no flag. A checksum *mismatch* doesn't force any decision by itself; it just falls through to the same mtime-based upload/download/conflict logic used when `use_checksum=False`, since content differing doesn't by itself say which side is newer. PR #472's own review round found four issues in this first version: the checksum comparison ran unconditionally, before the (cheap) mtime diff, including for pairs already within `_SYNC_MTIME_TOLERANCE` and even during `dry_run=True` — fixed by moving the mtime diff first and gating the hash read on `use_checksum and not dry_run and abs(diff) > _SYNC_MTIME_TOLERANCE`, so an already-in-sync pair or a dry_run preview never pays for a read it can't change the outcome of; `_local_md5` had no try/except unlike every other per-item operation in this module, so a file that became unreadable (deleted, permission-denied) between the directory scan and the hash read raised uncaught out of the whole `sync_folder` call instead of degrading to one `failed` entry — fixed via a new `"checksum_read_fail"` plan action mirroring the existing `"collision"` pattern; and `_upload_local_file`'s plain (non-`convert`) branch was identified as the actual root cause worth fixing directly — it never stamped `modifiedTime` the way the `convert_mime` branch three lines above already did (and `#422` already established for that branch), so a file uploaded through it always read as "Drive newer" on the very next `sync_folder` regardless of content — now stamped unconditionally in the `create()` body for every upload (no follow-up `update()` needed for the plain case, since Drive only overwrites `modifiedTime` when import-conversion is involved). `use_checksum` remains valuable beyond that root-cause fix for causes of drift the mtime stamp doesn't cover (e.g. a local overwrite that happens to preserve mtime). One review finding was accepted as a known tradeoff rather than fixed: a checksum mismatch that resolves to `'upload'` reads the local file twice (once to hash, once via `MediaFileUpload` for the actual transfer) — avoiding it would mean buffering the whole file in memory to share across both reads, a worse tradeoff for large files than one extra (likely page-cache-warm) disk read. `upload_local_folder` (#411) used to have its own independent inline upload loop with no `convert` param, unreachable from `_upload_local_file`'s conversion mechanism — bulk-importing a folder of CSV/DOCX/PPTX into native Workspace formats required falling back to per-file `upload_local_file` calls. Fixed by routing each candidate through `_upload_local_file` itself, gaining the same `convert` param and its semantics (an unsupported extension lands in `failed` rather than uploading as-is, matching `upload_local_file`'s own error-not-silent-fallback behavior). The existing bulk `skip_if_exists` pre-check (one `list()` call for the whole folder, not one per file — TC-D100) is preserved rather than replaced by `_upload_local_file`'s own per-call check: the folder loop now fetches each existing file's `mimeType` alongside its name in that same single call, decides skip-worthiness itself (name-only match when `convert=False`; name *and* target-mimeType match when `convert=True`, mirroring `_upload_local_file`'s own convert-aware duplicate check), and then calls `_upload_local_file` with `skip_if_exists=False` for whatever survives — so existence is never checked twice. `sync_folder(dry_run=True)`'s response used to duplicate every `skip`/`conflict` name into both a flat list (`skipped`/`conflicts`) and a full `{name, action, reason}` entry in `actions`, deterministically tripping the response-size cap on a moderately-sized, mostly-in-sync folder even though `actions` alone (name + action-type + reason for every item, including upload/download entries the flat lists never populated during `dry_run` in the first place) was already a complete, non-redundant picture (issue #512). Fixed by leaving `uploaded`/`downloaded`/`skipped`/`conflicts`/`failed` empty during `dry_run` rather than trimming or toggling `actions` itself. Separately, `sync_folder` previously had no response-size-cap bypass at all (`local_path_available=False`) unlike every other capped tool except `export_file`/`list_file_activity` (both deliberately, per the decision doc below) — its own `local_path` param already means the sync destination, so it can't double as a dump target the way `get_sheet_data`'s `local_path` does. Fixed by adding a separate `result_local_path` param following the same unconditional-if-passed `write_capped_result_to_disk` pattern as every other capped tool with a bypass; `enforce_response_size_cap` gained a `local_path_param` override so its error message names the right parameter instead of hardcoding `local_path`. PR #518's own QA review round live-caught a gap in that first version: `result_local_path` had no guard against pointing at or inside `local_path` — since `local_path` is scanned as sync input on every call (unlike every other capped tool's local_path/result_local_path, which are pure output destinations), a manifest written there showed up as a new local-only file on the very next sync and would have been uploaded to Drive on a real run. Fixed by rejecting the call up front (`ValueError`, before any Drive API call) when `Path(result_local_path).resolve()` equals or is a descendant of the resolved `local_path`.
|
|
39
|
+
- `tools/drive/transfer.py` — upload/download/sync/export/revisions; `_upload_local_file` (the core behind the `upload_local_file` tool) is a module-level helper so `docs/content.py`'s `insert_local_images` can call it directly, imported cross-package the same way `docs/content.py` imports `_SA_QUOTA_ERROR` from `tools/drive/__init__.py`. `upload_local_file`'s `convert` param (#188) requests Drive's *native* import conversion — CSV/XLSX→Sheets, DOCX/MD/HTML→Docs, PPTX→Slides — by uploading with the source format's mimeType while setting the destination's `mimeType` metadata to the target Google Workspace type (`_CONVERT_MIME` maps extension → (source mime, target mime)). This is a different mechanism from `docs/content.py`'s `create_doc_from_file`, which parses the file locally and rebuilds it via Docs API requests instead of Drive's importer — don't conflate the two when adding new conversion paths. `sync_folder`'s `convert_markdown` param (#211) applies the same native-conversion mechanism to local `.md` files during sync uploads. Because the converted Doc keeps its `.md` name in Drive, `_sync_level`'s drive_map-building loop matches it back to the local `.md` file directly (bypassing the export_format-suffix scheme normal Workspace files need) so resyncs settle into "in sync" instead of re-uploading a duplicate every run — this also reopens matching for a drive-only converted Doc with no local counterpart and no `export_format` (previously unreachable, since such files were always excluded from `drive_map`) — the plan-building loop classifies that case as a `conflict` (a convert_markdown Doc has no reverse conversion) before it ever reaches the download branch, so the download branch's own `_EXPORT_MIME[None]` guard is defensive-only dead code in the current implementation, not a reachable path (confirmed live: TC-D221). There is no reverse conversion (Doc → markdown). A converted Doc is recognized on every later sync via a Drive `properties` marker (`_CONVERT_MARKDOWN_SOURCE_PROP`) stamped at creation time by both `_sync_level`'s own upload path and `_upload_local_file`'s `convert=True` path (#414 rounds 2-3) — recognition is deliberately independent of whether the *current* call passes `convert_markdown`/`convert`, since the Doc's own persisted property is what matters, not this call's flag. Three further edge cases from that round-3 review shipped as issue #422: the `drive_map`-building loop now detects (rather than silently resolving) a name collision between a plain file and a converted Doc, reporting it under `failed` instead of letting whichever is listed last win the slot and make the other invisible to the sync; `_upload_local_file` now stamps `modifiedTime` from the local file's mtime on a converted Doc (via `create()` then a metadata-only `update()`, mirroring `_sync_level`'s own create() branch, since Drive's native import-conversion overwrites the create()-time value once conversion finishes) so a subsequent `sync_folder` lands in `skipped` rather than `conflicts`; and the drive-only branch now checks `direction` before `_is_converted_md`, so `direction='upload'` reports a plain `skip` like any other drive-only file instead of always reporting `conflict`. PR #433's own review round found the collision guard needed to go further: it originally only fired when the two colliding entries' `_is_converted_md` differed (a plain file vs. a converted Doc, #422's own reported shape), silently overwriting a same-type collision (two plain files, or two converted Docs, sharing a name) the exact same way; it now fires on any duplicate name regardless of type. The collision case is also now routed through the normal `plan`/`action` machinery (a new `"collision"` action, mapped to `conflict` during `dry_run` and to a real `failed` entry — `kind: "collision_fail"` — once execution is actually attempted) rather than writing to `failed` directly from the `drive_map`-building loop: that direct write both leaked into `failed` during `dry_run` (breaking the "dry_run never reports failures, only previews" invariant the pre-existing folder-collision failure path already upholds) and silently dropped a *local* file sharing the colliding name from every result list, since the plan loop's bare `continue` skipped it with zero acknowledgment. Separately, `_upload_local_file`'s `create()`+`update()` pair now shares one broad `except Exception` returning `{"error": ...}` (matching `_sync_level._run_one`'s own create+update pattern) instead of only catching quota `HttpError`s and letting everything else — including a failure in the new metadata-only restamp `update()`, after `create()` already succeeded — propagate uncaught to `upload_local_file`, which has no try/except of its own. `sync_folder`'s `use_checksum` param (#274) adds a content check ahead of `_sync_level`'s mtime comparison for names present on both sides: when the local file's md5 (`_local_md5`, streamed in 1 MiB chunks) matches Drive's own `md5Checksum` (now fetched by `_list_drive_children`), the pair is treated as in sync regardless of `modifiedTime` drift — this is what actually fixes `upload_local_file` not stamping `modifiedTime` (unlike `_sync_level`'s own upload path) causing a spurious re-download of identical content on the next sync, not just a same-mtime coincidence. Only applies where Drive returns a real `md5Checksum` — Workspace files and `convert_markdown` Docs have none and always fall back to mtime-only comparison, flag or no flag. A checksum *mismatch* doesn't force any decision by itself; it just falls through to the same mtime-based upload/download/conflict logic used when `use_checksum=False`, since content differing doesn't by itself say which side is newer. PR #472's own review round found four issues in this first version: the checksum comparison ran unconditionally, before the (cheap) mtime diff, including for pairs already within `_SYNC_MTIME_TOLERANCE` and even during `dry_run=True` — fixed by moving the mtime diff first and gating the hash read on `use_checksum and not dry_run and abs(diff) > _SYNC_MTIME_TOLERANCE`, so an already-in-sync pair or a dry_run preview never pays for a read it can't change the outcome of; `_local_md5` had no try/except unlike every other per-item operation in this module, so a file that became unreadable (deleted, permission-denied) between the directory scan and the hash read raised uncaught out of the whole `sync_folder` call instead of degrading to one `failed` entry — fixed via a new `"checksum_read_fail"` plan action mirroring the existing `"collision"` pattern; and `_upload_local_file`'s plain (non-`convert`) branch was identified as the actual root cause worth fixing directly — it never stamped `modifiedTime` the way the `convert_mime` branch three lines above already did (and `#422` already established for that branch), so a file uploaded through it always read as "Drive newer" on the very next `sync_folder` regardless of content — now stamped unconditionally in the `create()` body for every upload (no follow-up `update()` needed for the plain case, since Drive only overwrites `modifiedTime` when import-conversion is involved). `use_checksum` remains valuable beyond that root-cause fix for causes of drift the mtime stamp doesn't cover (e.g. a local overwrite that happens to preserve mtime). One review finding was accepted as a known tradeoff rather than fixed: a checksum mismatch that resolves to `'upload'` reads the local file twice (once to hash, once via `MediaFileUpload` for the actual transfer) — avoiding it would mean buffering the whole file in memory to share across both reads, a worse tradeoff for large files than one extra (likely page-cache-warm) disk read. `upload_local_folder` (#411) used to have its own independent inline upload loop with no `convert` param, unreachable from `_upload_local_file`'s conversion mechanism — bulk-importing a folder of CSV/DOCX/PPTX into native Workspace formats required falling back to per-file `upload_local_file` calls. Fixed by routing each candidate through `_upload_local_file` itself, gaining the same `convert` param and its semantics (an unsupported extension lands in `failed` rather than uploading as-is, matching `upload_local_file`'s own error-not-silent-fallback behavior). The existing bulk `skip_if_exists` pre-check (one `list()` call for the whole folder, not one per file — TC-D100) is preserved rather than replaced by `_upload_local_file`'s own per-call check: the folder loop now fetches each existing file's `mimeType` alongside its name in that same single call, decides skip-worthiness itself (name-only match when `convert=False`; name *and* target-mimeType match when `convert=True`, mirroring `_upload_local_file`'s own convert-aware duplicate check), and then calls `_upload_local_file` with `skip_if_exists=False` for whatever survives — so existence is never checked twice. `sync_folder(dry_run=True)`'s response used to duplicate every `skip`/`conflict` name into both a flat list (`skipped`/`conflicts`) and a full `{name, action, reason}` entry in `actions`, deterministically tripping the response-size cap on a moderately-sized, mostly-in-sync folder even though `actions` alone (name + action-type + reason for every item, including upload/download entries the flat lists never populated during `dry_run` in the first place) was already a complete, non-redundant picture (issue #512). Fixed by leaving `uploaded`/`downloaded`/`skipped`/`conflicts`/`failed` empty during `dry_run` rather than trimming or toggling `actions` itself. Separately, `sync_folder` previously had no response-size-cap bypass at all (`local_path_available=False`) unlike every other capped tool except `export_file`/`list_file_activity` (both deliberately, per the decision doc below) — its own `local_path` param already means the sync destination, so it can't double as a dump target the way `get_sheet_data`'s `local_path` does. Fixed by adding a separate `result_local_path` param following the same unconditional-if-passed `write_capped_result_to_disk` pattern as every other capped tool with a bypass; `enforce_response_size_cap` gained a `local_path_param` override so its error message names the right parameter instead of hardcoding `local_path`. PR #518's own QA review round live-caught a gap in that first version: `result_local_path` had no guard against pointing at or inside `local_path` — since `local_path` is scanned as sync input on every call (unlike every other capped tool's local_path/result_local_path, which are pure output destinations), a manifest written there showed up as a new local-only file on the very next sync and would have been uploaded to Drive on a real run. Fixed by rejecting the call up front (`ValueError`, before any Drive API call) when `Path(result_local_path).resolve()` equals or is a descendant of the resolved `local_path`. `upload_file`'s `convert_to_doc` param implements the identical native-import-conversion trick as `_upload_local_file`'s `convert`/`_CONVERT_MIME` above, independently — raw text/markdown/html content instead of a local file, always targeting a Doc since there's no file extension to dispatch Sheets/Slides on — with no cross-reference between the two (issue #412). Fixed by sharing `_GOOGLE_DOC_MIME` as the single source of truth for the target mimeType literal both mechanisms write, plus explicit docstring cross-references at both call sites; the two code paths themselves stayed separate rather than being merged, since their actual upload semantics (raw content vs. local file, single target vs. extension-dispatched) differ enough that unifying them would cost more complexity than it'd save.
|
|
40
40
|
- `tools/drive/activity.py` — `list_file_activity` (Drive Activity API v2; requires `drive.activity.readonly` scope)
|
|
41
41
|
- `tools/docs/` — Google Docs package; `__init__.py` is a thin dispatcher that delegates to four submodules:
|
|
42
42
|
- `docs/content.py` — helpers (`_html_to_text`, `_md_to_html`, `_to_doc_requests`, `_html_to_doc_requests`, `_collect_doc_paragraphs`) and tools (`create_doc`, `get_doc_content`, `write_doc_content`, `create_doc_from_file`, `insert_doc_text`, `delete_doc_range`, `get_doc_structure`, `find_in_doc`, `insert_inline_image`, `insert_page_break`, `insert_softbreak_paragraph`, `insert_local_images`, `create_named_range`, `create_bookmark`). The Docs API has no bookmark-creation endpoint — `create_bookmark` is a thin wrapper over `createNamedRange` spanning a single character; neither tool's output is a link target (only UI-created bookmarks/headings are). `find_in_doc` searches paragraph text (including table cells) and returns `start_index`/`end_index` offsets in UTF-16 code units usable directly with `style_doc_range` — `_collect_doc_paragraphs` is a generator (so a caller can stop early once `max_results` is hit) that walks the Docs API body, trusting each `ParagraphElement`'s own `startIndex` when present and otherwise carrying the running offset forward rather than dropping that element, since the API doesn't always populate it (seen on a document's first element). `insert_softbreak_paragraph` joins multiple lines with a literal `"\v"` (vertical tab) character in a single `insertText` call — confirmed live that the Docs API stores this as one paragraph element rather than splitting it, matching the Docs UI's own Shift+Enter soft-break convention — and sets `namedStyleType` explicitly over the inserted span rather than leaving it to whatever the insertion point would otherwise inherit. `insert_local_images` uploads local image files and swaps each into the doc at a plain-text marker in one call; confirmed live that `insertInlineImage` with a `drive_file_id` fails with "There was a problem retrieving the image" unless the file is first shared `anyone`/`reader` — the Docs backend fetches the image as an anonymous HTTP request, so being accessible to the authenticated user alone is not enough (this also applies to the existing `insert_inline_image` tool's `drive_file_id` path, not just the new one; its docstring now says so). `get_doc_structure` now also surfaces each paragraph's `headingId` (`paragraphStyle.headingId`) — confirmed live present on the default single-tab `documents.get()` response for both `TITLE`/`SUBTITLE` and `HEADING_1`..`6` paragraphs, no `includeTabsContent` needed. `create_doc`/`create_doc_from_file`/`write_doc_content` now run an automatic second pass (`_resolve_heading_anchors`, gated by the cheap `_has_pending_anchor_links` check so content with no `#`-links skips the extra API round trip entirely) after any conversion that left a GitHub/GitLab-style `#slug` heading-anchor link behind (issue #409): it resolves the anchor against the doc's own real headings via `anchors.resolve_heading_anchor` and rewrites it to a working `.../edit?tab=t.0#heading=<headingId>` jump link (an ordinary URL is sufficient — no `Link.headingId` API field needed, confirmed live), or strips the link (keeping the text plain) when no heading matches with reasonable confidence — a link silently pointing at the wrong section is worse than a plain, unlinked mention. This was a deliberate product decision to resolve anchors automatically rather than only exposing `headingId` and leaving matching to the calling agent — see `docs/design/heading-anchor-resolution.md` for the full rationale. PR #453's own QA round (`/code-review high` + live testing against a fixture with no table and no anchor on the doc's first element) caught two correctness bugs the first version's hand-rolled body walk had: it only inspected top-level `paragraph` elements (a heading or anchor link living inside a table cell was invisible to both `_has_pending_anchor_links` and `_resolve_heading_anchors`), and it required a run's own `pe.get("startIndex")`/`endIndex` to both be non-`None` (silently dropping an anchor that is, or is part of, the document's first body element — the Docs API omits `startIndex` there, the same quirk `_collect_doc_paragraphs` already handles). Fixed by `_walk_headings_and_anchor_runs`, a dedicated recursive walker mirroring `_collect_doc_paragraphs`'s own two correctness properties (table-cell recursion; carrying the running offset forward via character-by-character advance rather than trusting a run's own possibly-inconsistent `endIndex`) rather than reusing `_collect_doc_paragraphs` itself, since that generator's yielded shape (text + char-indices only) doesn't carry per-run link URLs or heading-paragraph style info and is used elsewhere (`find_in_doc`) in a way not worth risking a signature change for. `_has_pending_anchor_links` gained a second parameter (`tables: list[Table]`, walked via `_table_has_pending_anchor_link`, recursing into nested tables) since `fill_tables()` builds and executes table-cell requests separately from `content_requests`, invisible to the original single-argument guard. `create_doc`/`create_doc_from_file`/`write_doc_content` now support inline images in markdown (``) and HTML (`<img>`) conversion (issue #333) via a shared `_apply_doc_content` helper: `src` may be a local filesystem path (uploaded to Drive), a `drive:<file_id>` reference to an already-uploaded file, or a public `http(s)://` URL (used directly) — resolved by `_resolve_image_source`, sharing local-path/`drive:` sources `anyone:reader` the same way `insert_local_images` already does, then (per explicit product decision, and now also `insert_local_images`'s own default — a behavior change from its original #332 shipped version) revoking that temporary share once the image is embedded, unless `revoke_sharing=False`. The Docs API rejects an entire `batchUpdate` atomically if any one `insertInlineImage` request in it can't be fetched (confirmed live via TC-DOC102's own deliberately-unreachable-URL case) — `_apply_doc_content` retries with the failing request stripped (its index is parsed directly out of Google's own error message) rather than losing every other request in the same call; see `docs/design/image-conversion.md` for the full design, including why `Image` is a zero-width AST node (not a marker) and the deliberate table-cell-image gap.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-gee-sweet
|
|
3
|
-
Version: 0.8.2.
|
|
3
|
+
Version: 0.8.2.dev259
|
|
4
4
|
Summary: MCP server for Google Workspace — Sheets, Drive, Docs (HTML or Markdown), and Calendar. 60+ tools for AI clients.
|
|
5
5
|
Project-URL: Homepage, https://github.com/khuisman/mcp-gee-sweet
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/khuisman/mcp-gee-sweet/issues
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/transfer.py
RENAMED
|
@@ -49,6 +49,16 @@ _SYNC_MTIME_TOLERANCE = 5 # seconds — absorbs clock skew and upload-time drif
|
|
|
49
49
|
# (#414 QA review, findings #2 and #7).
|
|
50
50
|
_CONVERT_MARKDOWN_SOURCE_PROP = "geeSweetConvertMarkdownSource"
|
|
51
51
|
|
|
52
|
+
# Google Workspace Doc mimeType, requested via Drive's native import-conversion
|
|
53
|
+
# trick (upload with the source format's mimeType while setting the destination
|
|
54
|
+
# file's own mimeType to this target) from two independent places: _CONVERT_MIME
|
|
55
|
+
# below (local-file uploads, dispatched by extension, also covers Sheets/Slides
|
|
56
|
+
# targets) and upload_file's convert_to_doc param (raw text/markdown/html content,
|
|
57
|
+
# always targets a Doc since it has no extension to dispatch on). Shared here as
|
|
58
|
+
# the single source of truth for the literal so the two can't drift apart on it —
|
|
59
|
+
# see upload_file's own convert_to_doc branch for the other call site (#412).
|
|
60
|
+
_GOOGLE_DOC_MIME = "application/vnd.google-apps.document"
|
|
61
|
+
|
|
52
62
|
# extension -> (source mimeType to upload as, target Google Workspace mimeType to
|
|
53
63
|
# request via Drive's native import conversion). Distinct from _EXPORT_MIME above,
|
|
54
64
|
# which maps the other direction (Google type -> downloadable export format).
|
|
@@ -60,11 +70,11 @@ _CONVERT_MIME: dict[str, tuple[str, str]] = {
|
|
|
60
70
|
),
|
|
61
71
|
".docx": (
|
|
62
72
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
63
|
-
|
|
73
|
+
_GOOGLE_DOC_MIME,
|
|
64
74
|
),
|
|
65
|
-
".md": ("text/markdown",
|
|
66
|
-
".html": ("text/html",
|
|
67
|
-
".htm": ("text/html",
|
|
75
|
+
".md": ("text/markdown", _GOOGLE_DOC_MIME),
|
|
76
|
+
".html": ("text/html", _GOOGLE_DOC_MIME),
|
|
77
|
+
".htm": ("text/html", _GOOGLE_DOC_MIME),
|
|
68
78
|
".pptx": (
|
|
69
79
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
70
80
|
"application/vnd.google-apps.presentation",
|
|
@@ -88,7 +98,10 @@ async def _upload_local_file(
|
|
|
88
98
|
DOCX/MD/HTML -> Docs, PPTX -> Slides) by uploading with the source format's
|
|
89
99
|
mimeType while setting the destination file's mimeType to the target Google
|
|
90
100
|
Workspace type — this is distinct from create_doc_from_file, which parses the
|
|
91
|
-
file locally and rebuilds it via Docs API requests instead of Drive's importer.
|
|
101
|
+
file locally and rebuilds it via Docs API requests instead of Drive's importer.
|
|
102
|
+
upload_file's convert_to_doc param implements the identical trick for raw
|
|
103
|
+
text/markdown/html content instead of a local file — see _GOOGLE_DOC_MIME
|
|
104
|
+
above, shared by both so they can't drift apart on the target mimeType (#412)."""
|
|
92
105
|
path = Path(local_path)
|
|
93
106
|
if not path.is_file():
|
|
94
107
|
raise ValueError(f"No file found at {local_path!r}")
|
|
@@ -1212,7 +1225,10 @@ def register(tool):
|
|
|
1212
1225
|
convert_to_doc: If True, create a Google Doc instead of a raw file.
|
|
1213
1226
|
'markdown' and 'html' sources retain heading, list, and link
|
|
1214
1227
|
formatting via Drive's HTML import. 'text' uploads as plain text
|
|
1215
|
-
and Drive converts it (no formatting preserved).
|
|
1228
|
+
and Drive converts it (no formatting preserved). Uses the same
|
|
1229
|
+
Drive native-import-conversion trick as upload_local_file's
|
|
1230
|
+
convert param, simplified to always target a Doc since this
|
|
1231
|
+
tool has no file extension to dispatch Sheets/Slides on.
|
|
1216
1232
|
|
|
1217
1233
|
Returns:
|
|
1218
1234
|
fileId, name, parent folder ID, and webViewLink of the created file.
|
|
@@ -1245,7 +1261,13 @@ def register(tool):
|
|
|
1245
1261
|
file_body["parents"] = [target_folder_id]
|
|
1246
1262
|
|
|
1247
1263
|
if convert_to_doc:
|
|
1248
|
-
|
|
1264
|
+
# Same Drive native-import-conversion trick as _upload_local_file's
|
|
1265
|
+
# convert/_CONVERT_MIME path above (upload with the source mimeType,
|
|
1266
|
+
# override the destination mimeType to request conversion) — simpler
|
|
1267
|
+
# here since this tool only ever targets a Doc, never Sheets/Slides.
|
|
1268
|
+
# Shares _GOOGLE_DOC_MIME as the single source of truth for that
|
|
1269
|
+
# value so the two mechanisms can't drift apart on it (#412).
|
|
1270
|
+
file_body["mimeType"] = _GOOGLE_DOC_MIME
|
|
1249
1271
|
|
|
1250
1272
|
media = MediaInMemoryUpload(upload_content, mimetype=upload_mime, resumable=False)
|
|
1251
1273
|
try:
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/cleanup-worktrees.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.claude/commands/start-worktree.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/ISSUE_TEMPLATE/bug_report.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/.github/ISSUE_TEMPLATE/feature_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-chart-theming.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-composite-tools.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-dev-team.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-docs-formatting.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-prompt-qa-role.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-publishing.md
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-repositioning.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/decisions/decision-testing.md
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/borderless-table-columns.md
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/effectiveformat-spike.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/heading-anchor-resolution.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/design/phase3-theme-system.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/qa-fixture-pixel.png
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d195-create-doc.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d196-create-doc.html
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d213-dollar-escape.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/fixtures/tc-d226-heading-table.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-docs.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-drive-smoke.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-infra.md
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/docs/qa/results/2026-07-04-sheets_read.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/http_transport.py
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/calendar.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/__init__.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/anchors.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/ast.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/comments.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/content.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/emitter.py
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/indices.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/layout.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/style.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/docs/tables.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/__init__.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/activity.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/files.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/drive/sharing.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/response_limits.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/__init__.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/data.py
RENAMED
|
File without changes
|
{mcp_gee_sweet-0.8.2.dev258 → mcp_gee_sweet-0.8.2.dev259}/src/mcp_gee_sweet/tools/sheets/helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|