@ngocsangairvds/vsaf 3.1.27 → 3.2.1
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/package.json +2 -2
- package/src/global.js +70 -10
- package/tools/skills/vds-scripts-skill/.openskills.json +6 -0
- package/tools/skills/vds-scripts-skill/QUALITY.md +44 -0
- package/tools/skills/vds-scripts-skill/SKILL.md +135 -0
- package/tools/skills/vds-scripts-skill/references/audit-commands.md +171 -0
- package/tools/skills/vds-scripts-skill/references/capability-index.md +34 -0
- package/tools/skills/vds-scripts-skill/references/development-commands.md +12 -0
- package/tools/skills/vds-scripts-skill/references/google-sheets.md +73 -0
- package/tools/skills/vds-scripts-skill/references/integration-commands.md +17 -0
- package/tools/skills/vds-scripts-skill/references/platform-bootstrap.md +31 -0
- package/tools/skills/vds-scripts-skill/references/specialist-routing.md +14 -0
- package/tools/skills/vds-scripts-skill/references/validation-commands.md +15 -0
- package/tools/skills/vsaf-build/SKILL.md +32 -2
- package/tools/skills/vsaf-ship/SKILL.md +41 -10
- package/tools/skills/vsaf-test/SKILL.md +8 -0
- package/tools/vds-scripts/.mcp.json +11 -0
- package/tools/vds-scripts/.secrets.baseline +133 -0
- package/tools/vds-scripts/AGENTS.md +152 -0
- package/tools/vds-scripts/CLAUDE.md +101 -0
- package/tools/vds-scripts/CLI_COMMAND_OPTIMIZATION.md +156 -0
- package/tools/vds-scripts/PACKAGE_P125B_IMPLEMENTATION_SUMMARY.md +131 -0
- package/tools/vds-scripts/PROJECT_COMPLETION_SUMMARY.md +45 -0
- package/tools/vds-scripts/README.md +97 -0
- package/tools/vds-scripts/bitbucket_manifest_mapping.toml +34 -0
- package/tools/vds-scripts/bitbucket_orchestrator/ARCHITECTURE_ANALYSIS.md +258 -0
- package/tools/vds-scripts/bitbucket_orchestrator/BITBUCKET_API_PRACTICES.md +393 -0
- package/tools/vds-scripts/bitbucket_orchestrator/EVALUATION_REPORT.md +61 -0
- package/tools/vds-scripts/bitbucket_orchestrator/FEATURES.md +908 -0
- package/tools/vds-scripts/bitbucket_orchestrator/README.md +687 -0
- package/tools/vds-scripts/bitbucket_orchestrator/pyproject.toml +40 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/__init__.py +20 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py +657 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/cli.py +2108 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/client.py +2534 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/config.py +171 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/errors.py +67 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/factory.py +185 -0
- package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/protocols.py +244 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/__init__.py +8 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/conftest.py +65 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_advanced_search.py +151 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_async_client.py +546 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_branch_permissions.py +145 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_cli.py +115 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client.py +157 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_branch_conditions.py +79 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_code_advanced.py +163 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_code_file.py +32 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_deployment_environments.py +194 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_issues.py +164 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_pipelines_advanced.py +179 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_pr_blockers.py +119 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_repository_variables.py +156 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_code.py +98 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_code_advanced.py +282 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_code_insights.py +335 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_conditions.py +147 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_config.py +131 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_deployment_env.py +352 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_factory.py +371 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_fork_operations.py +204 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_issue_cli.py +261 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_pipeline_advanced.py +270 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_pr_blocker.py +204 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_protocols.py +334 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_repo_settings.py +343 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_repo_variables.py +270 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_webhooks.py +189 -0
- package/tools/vds-scripts/bitbucket_orchestrator/tests/test_workspace.py +233 -0
- package/tools/vds-scripts/bitbucket_orchestrator/uv.lock +742 -0
- package/tools/vds-scripts/confluence_orchestrator/Dockerfile +19 -0
- package/tools/vds-scripts/confluence_orchestrator/README.md +412 -0
- package/tools/vds-scripts/confluence_orchestrator/SYNC_SCRIPTS.md +127 -0
- package/tools/vds-scripts/confluence_orchestrator/SYNC_STANDARDIZATION.md +108 -0
- package/tools/vds-scripts/confluence_orchestrator/pyproject.toml +48 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/__init__.py +20 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/cli.py +2532 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/config.py +175 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content.py +290 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content_v2.py +94 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/crawl_tree.py +1835 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/errors.py +80 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/eventing.py +109 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/http.py +1114 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/orchestration.py +165 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/reporting.py +78 -0
- package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/tree.py +121 -0
- package/tools/vds-scripts/confluence_orchestrator/sync_pdfs_from_markdown.py +213 -0
- package/tools/vds-scripts/confluence_orchestrator/sync_pdfs_to_confluence.py +305 -0
- package/tools/vds-scripts/confluence_orchestrator/sync_png_attachments.py +305 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/conftest.py +8 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_advanced_content.py +224 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_advanced_search.py +188 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_cache_management.py +247 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_cli.py +499 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_config.py +83 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_content.py +186 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_content_flags.py +27 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_crawl_tree.py +2250 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_draft_management.py +223 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing.py +71 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing_chaos.py +37 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing_rate_limit.py +44 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing_timeout.py +49 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_export.py +230 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_history.py +204 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_http.py +117 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_orchestration.py +91 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_reporting.py +24 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_search_cql.py +34 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_space_management.py +237 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_space_permissions.py +332 -0
- package/tools/vds-scripts/confluence_orchestrator/tests/test_user_group_management.py +388 -0
- package/tools/vds-scripts/confluence_orchestrator/uv.lock +1023 -0
- package/tools/vds-scripts/git_orchestrator/ENHANCEMENT_SUMMARY.md +119 -0
- package/tools/vds-scripts/git_orchestrator/README.md +280 -0
- package/tools/vds-scripts/git_orchestrator/VERIFICATION_REPORT.md +152 -0
- package/tools/vds-scripts/git_orchestrator/pyproject.toml +35 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__init__.py +7 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__main__.py +4 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/cli.py +847 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/logging_config.py +63 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/manifest.py +129 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/orchestrator.py +819 -0
- package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/reporting.py +53 -0
- package/tools/vds-scripts/git_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/git_orchestrator/tests/test_cli_settings.py +21 -0
- package/tools/vds-scripts/git_orchestrator/tests/test_integration.py +74 -0
- package/tools/vds-scripts/git_orchestrator/tests/test_manifest.py +79 -0
- package/tools/vds-scripts/git_orchestrator/tests/test_orchestrator.py +204 -0
- package/tools/vds-scripts/git_orchestrator/tests/test_public_api.py +236 -0
- package/tools/vds-scripts/git_orchestrator/tests/test_resilience.py +345 -0
- package/tools/vds-scripts/git_orchestrator/uv.lock +271 -0
- package/tools/vds-scripts/jira_orchestrator/README.md +770 -0
- package/tools/vds-scripts/jira_orchestrator/pyproject.toml +39 -0
- package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/__init__.py +1 -0
- package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/adapter.py +1320 -0
- package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/cli.py +2271 -0
- package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/config.py +138 -0
- package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/errors.py +67 -0
- package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/reporting.py +65 -0
- package/tools/vds-scripts/jira_orchestrator/tests/__init__.py +1 -0
- package/tools/vds-scripts/jira_orchestrator/tests/conftest.py +86 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_agile_list_payloads.py +54 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_bulk_operations.py +69 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_components.py +57 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_createmeta.py +45 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_dashboard.py +117 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_issue_properties.py +54 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_permissions_compat.py +42 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_reindex.py +42 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_remote_links.py +76 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_transitions.py +91 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_user_management.py +110 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_version_management.py +133 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_watchers.py +41 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_advanced_search.py +164 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_agile.py +256 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_application_properties.py +193 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_backlog.py +91 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_bulk_operations.py +277 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_cli.py +106 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_components.py +106 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_config.py +164 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_dashboard.py +122 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_discover_fields.py +207 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_filter_management.py +333 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_issue_archiving.py +164 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_issue_links.py +257 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_issue_properties.py +171 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_link_types.py +314 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_parse_set.py +37 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_permissions.py +273 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_reindex.py +81 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_remote_links.py +254 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_security_schemes.py +170 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_transitions_changelog.py +114 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_user_management.py +226 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_version_management.py +339 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_watchers.py +101 -0
- package/tools/vds-scripts/jira_orchestrator/tests/test_worklog.py +223 -0
- package/tools/vds-scripts/jira_orchestrator/uv.lock +738 -0
- package/tools/vds-scripts/mcp_server/Dockerfile +34 -0
- package/tools/vds-scripts/mcp_server/README.md +140 -0
- package/tools/vds-scripts/mcp_server/pyproject.toml +42 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/__init__.py +4 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/config.py +36 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/server.py +66 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/__init__.py +14 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/bitbucket_tools.py +47 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/confluence_tools.py +59 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/git_tools.py +71 -0
- package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/jira_tools.py +63 -0
- package/tools/vds-scripts/mcp_server/tests/__init__.py +2 -0
- package/tools/vds-scripts/mcp_server/tests/conftest.py +29 -0
- package/tools/vds-scripts/mcp_server/tests/unit/__init__.py +2 -0
- package/tools/vds-scripts/mcp_server/tests/unit/test_bitbucket_tools.py +25 -0
- package/tools/vds-scripts/mcp_server/tests/unit/test_confluence_tools.py +25 -0
- package/tools/vds-scripts/mcp_server/tests/unit/test_git_tools.py +32 -0
- package/tools/vds-scripts/mcp_server/tests/unit/test_jira_tools.py +32 -0
- package/tools/vds-scripts/mcp_server/tests/verification/__init__.py +2 -0
- package/tools/vds-scripts/mcp_server/tests/verification/test_mcp_confluence_tools.py +40 -0
- package/tools/vds-scripts/mcp_server/tests/verification/test_mcp_jira_tools.py +37 -0
- package/tools/vds-scripts/mcp_server/tests/verification/test_mcp_tool_registration.py +47 -0
- package/tools/vds-scripts/mcp_server/uv.lock +1032 -0
- package/tools/vds-scripts/mypy.ini +5 -0
- package/tools/vds-scripts/pyproject.toml +29 -0
- package/tools/vds-scripts/repo-manifest.yaml +273 -0
- package/tools/vds-scripts/repo-manifest.yaml.example +25 -0
- package/tools/vds-scripts/scripts/BRD-Validation-API.postman_collection.json +706 -0
- package/tools/vds-scripts/scripts/BRD-Validation-README.md +308 -0
- package/tools/vds-scripts/scripts/README.md +162 -0
- package/tools/vds-scripts/scripts/bootstrap_uv.sh +30 -0
- package/tools/vds-scripts/scripts/brd-validation-environment.json +51 -0
- package/tools/vds-scripts/scripts/brd-validation-test-results.json +13023 -0
- package/tools/vds-scripts/scripts/brd_coverage_report.json +276 -0
- package/tools/vds-scripts/scripts/create_memory_session.py +35 -0
- package/tools/vds-scripts/scripts/deployment/load_docker_images_offline.sh +90 -0
- package/tools/vds-scripts/scripts/final_completion_report.md +139 -0
- package/tools/vds-scripts/scripts/folder_structure_report.json +321 -0
- package/tools/vds-scripts/scripts/generate_completion_report.py +125 -0
- package/tools/vds-scripts/scripts/generate_intellij_modules.py +150 -0
- package/tools/vds-scripts/scripts/link_integrity_report.json +807 -0
- package/tools/vds-scripts/scripts/move_audit_artifact_pages.py +255 -0
- package/tools/vds-scripts/scripts/move_audit_artifact_pages_rest.py +165 -0
- package/tools/vds-scripts/scripts/move_wrong_dept_pages.py +216 -0
- package/tools/vds-scripts/scripts/save_intellij_memories.py +120 -0
- package/tools/vds-scripts/scripts/save_memories_to_vds_ai.py +83 -0
- package/tools/vds-scripts/scripts/save_memories_vds_style.py +129 -0
- package/tools/vds-scripts/scripts/search_intellij_memories.py +50 -0
- package/tools/vds-scripts/scripts/setup_intellij_workspace.py +65 -0
- package/tools/vds-scripts/scripts/target-state-automation/README.md +89 -0
- package/tools/vds-scripts/scripts/target-state-automation/confluence_sync_coordinator.sh +27 -0
- package/tools/vds-scripts/scripts/target-state-automation/coordination.sh +114 -0
- package/tools/vds-scripts/scripts/target-state-automation/diagram_coordinator.sh +25 -0
- package/tools/vds-scripts/scripts/target-state-automation/docs_root.sh +22 -0
- package/tools/vds-scripts/scripts/target-state-automation/generate_diagrams.sh +22 -0
- package/tools/vds-scripts/scripts/target-state-automation/markdown_coordinator.sh +25 -0
- package/tools/vds-scripts/scripts/target-state-automation/progress_dashboard.sh +17 -0
- package/tools/vds-scripts/scripts/target-state-automation/schema_coordinator.sh +25 -0
- package/tools/vds-scripts/scripts/target-state-automation/sync_confluence.sh +30 -0
- package/tools/vds-scripts/scripts/target-state-automation/update_dependencies.sh +19 -0
- package/tools/vds-scripts/scripts/target-state-automation/validate_links.sh +86 -0
- package/tools/vds-scripts/scripts/target-state-automation/validate_markdown.sh +52 -0
- package/tools/vds-scripts/scripts/target-state-automation/validate_schemas.sh +26 -0
- package/tools/vds-scripts/scripts/target-state-automation/validate_structure.sh +98 -0
- package/tools/vds-scripts/scripts/update_modules_xml.py +190 -0
- package/tools/vds-scripts/scripts/uv-workspace-alignment-verification-2026-03-25.md +128 -0
- package/tools/vds-scripts/scripts/validate_brd_coverage.py +179 -0
- package/tools/vds-scripts/scripts/validate_folder_structure.py +240 -0
- package/tools/vds-scripts/scripts/validate_link_integrity.py +272 -0
- package/tools/vds-scripts/scripts/vds_sh_helpers.sh +180 -0
- package/tools/vds-scripts/scripts/verification/phase2_portable_paths_ubuntu_docker.sh +26 -0
- package/tools/vds-scripts/scripts/worktree_uv.sh +48 -0
- package/tools/vds-scripts/uv.lock +8 -0
- package/tools/vds-scripts/vds_cli/README.md +126 -0
- package/tools/vds-scripts/vds_cli/VERIFICATION_REPORT.md +41 -0
- package/tools/vds-scripts/vds_cli/pyproject.toml +38 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/__init__.py +3 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/cli.py +173 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/docs_sync.py +1203 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/env.py +41 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/__init__.py +3 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/google_sheets_orchestrator.py +198 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/router.py +93 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/sync_api.py +647 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/sync_service.py +266 -0
- package/tools/vds-scripts/vds_cli/tests/__init__.py +2 -0
- package/tools/vds-scripts/vds_cli/tests/conftest.py +49 -0
- package/tools/vds-scripts/vds_cli/tests/unit/__init__.py +2 -0
- package/tools/vds-scripts/vds_cli/tests/unit/test_cli.py +143 -0
- package/tools/vds-scripts/vds_cli/tests/unit/test_docs_sync.py +422 -0
- package/tools/vds-scripts/vds_cli/tests/unit/test_env.py +51 -0
- package/tools/vds-scripts/vds_cli/tests/unit/test_router.py +72 -0
- package/tools/vds-scripts/vds_cli/tests/unit/test_sync_api.py +357 -0
- package/tools/vds-scripts/vds_cli/tests/unit/test_sync_service.py +160 -0
- package/tools/vds-scripts/vds_cli/tests/verification/__init__.py +2 -0
- package/tools/vds-scripts/vds_cli/tests/verification/test_bitbucket_real.py +33 -0
- package/tools/vds-scripts/vds_cli/tests/verification/test_confluence_real.py +35 -0
- package/tools/vds-scripts/vds_cli/tests/verification/test_jira_real.py +41 -0
- package/tools/vds-scripts/vds_cli/uv.lock +524 -0
- package/tools/vds-scripts/vds_cli_common/README.md +190 -0
- package/tools/vds-scripts/vds_cli_common/pyproject.toml +92 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/__init__.py +34 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/completers.py +139 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/context.py +201 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/env.py +119 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/errors.py +318 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/output.py +284 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/paths.py +78 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/testing.py +213 -0
- package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/version.py +85 -0
- package/tools/vds-scripts/vds_cli_common/tests/__init__.py +1 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_completers.py +148 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_context.py +192 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_env.py +102 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_errors.py +186 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_output.py +229 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_paths.py +61 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_testing.py +138 -0
- package/tools/vds-scripts/vds_cli_common/tests/test_version.py +64 -0
package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py
ADDED
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
"""Async Bitbucket client wrapper using asyncio.to_thread().
|
|
2
|
+
|
|
3
|
+
This module provides an async wrapper around the synchronous BitbucketClient,
|
|
4
|
+
enabling non-blocking Bitbucket API operations in async contexts.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from vds_bitbucket_orchestrator import create_async_client
|
|
8
|
+
|
|
9
|
+
async def audit_repos():
|
|
10
|
+
client = create_async_client()
|
|
11
|
+
repos = await client.list_repositories("INS")
|
|
12
|
+
return repos
|
|
13
|
+
|
|
14
|
+
References:
|
|
15
|
+
- FR-21.2.3: AsyncBitbucketClient using asyncio.to_thread()
|
|
16
|
+
- TSK-225: Async Bitbucket wrapper
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import asyncio
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from .client import BitbucketClient
|
|
25
|
+
from .config import BitbucketSettings
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AsyncBitbucketClient:
|
|
29
|
+
"""Async wrapper for BitbucketClient using asyncio.to_thread().
|
|
30
|
+
|
|
31
|
+
This class wraps the synchronous BitbucketClient methods using
|
|
32
|
+
asyncio.to_thread() to enable non-blocking execution in async contexts.
|
|
33
|
+
It implements the same protocols as BitbucketClient:
|
|
34
|
+
- BitbucketRepositoryClient: Repository operations
|
|
35
|
+
- BitbucketBranchClient: Branch and permission operations
|
|
36
|
+
- BitbucketCodeClient: Code and commit operations
|
|
37
|
+
- BitbucketFullClient: Combined protocol
|
|
38
|
+
|
|
39
|
+
The async wrapper is useful for:
|
|
40
|
+
- Concurrent API calls without blocking the event loop
|
|
41
|
+
- Integration with async frameworks (FastAPI, aiohttp, etc.)
|
|
42
|
+
- Parallel evidence collection in audit workflows
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
from vds_bitbucket_orchestrator import create_async_client
|
|
46
|
+
|
|
47
|
+
async def collect_evidence():
|
|
48
|
+
client = create_async_client()
|
|
49
|
+
|
|
50
|
+
# Concurrent API calls
|
|
51
|
+
repos, branches = await asyncio.gather(
|
|
52
|
+
client.list_repositories("INS"),
|
|
53
|
+
client.get_branches("INS", "insurance-core"),
|
|
54
|
+
)
|
|
55
|
+
return repos, branches
|
|
56
|
+
|
|
57
|
+
Note:
|
|
58
|
+
The underlying HTTP calls are still synchronous but run in a
|
|
59
|
+
thread pool, preventing them from blocking the async event loop.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
settings: BitbucketSettings,
|
|
65
|
+
*,
|
|
66
|
+
timeout: int | None = 30,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Initialize the async client with a sync BitbucketClient.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
settings: BitbucketSettings instance with credentials and configuration.
|
|
72
|
+
timeout: HTTP timeout in seconds (default: 30).
|
|
73
|
+
"""
|
|
74
|
+
self._sync_client = BitbucketClient(settings, timeout=timeout)
|
|
75
|
+
self._settings = settings
|
|
76
|
+
self._timeout = timeout
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def sync_client(self) -> BitbucketClient:
|
|
80
|
+
"""Access the underlying synchronous client.
|
|
81
|
+
|
|
82
|
+
Useful for cases where sync access is needed or for testing.
|
|
83
|
+
"""
|
|
84
|
+
return self._sync_client
|
|
85
|
+
|
|
86
|
+
# =========================================================================
|
|
87
|
+
# Project Management (BitbucketRepositoryClient)
|
|
88
|
+
# =========================================================================
|
|
89
|
+
|
|
90
|
+
async def list_projects(self, limit: int = 25) -> list[dict[str, Any]]:
|
|
91
|
+
"""List all projects asynchronously.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
limit: Maximum number of projects to return (default: 25)
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
List of project dictionaries with keys like 'key', 'name', 'description'
|
|
98
|
+
"""
|
|
99
|
+
return await asyncio.to_thread(self._sync_client.list_projects, limit)
|
|
100
|
+
|
|
101
|
+
async def get_project(self, project_key: str) -> dict[str, Any]:
|
|
102
|
+
"""Get project information asynchronously.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
project_key: The project key (e.g., 'INS', 'LEP')
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Project dictionary with metadata
|
|
109
|
+
"""
|
|
110
|
+
return await asyncio.to_thread(self._sync_client.get_project, project_key)
|
|
111
|
+
|
|
112
|
+
async def create_project(
|
|
113
|
+
self, key: str, name: str, description: str = "Project created via VDS orchestrator"
|
|
114
|
+
) -> dict[str, Any]:
|
|
115
|
+
"""Create a new project asynchronously.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
key: Project key
|
|
119
|
+
name: Project name
|
|
120
|
+
description: Project description
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Created project dictionary
|
|
124
|
+
"""
|
|
125
|
+
return await asyncio.to_thread(self._sync_client.create_project, key, name, description)
|
|
126
|
+
|
|
127
|
+
# =========================================================================
|
|
128
|
+
# Repository Management (BitbucketRepositoryClient)
|
|
129
|
+
# =========================================================================
|
|
130
|
+
|
|
131
|
+
async def list_repositories(self, project_key: str, limit: int = 25) -> list[dict[str, Any]]:
|
|
132
|
+
"""List repositories in a project asynchronously.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
project_key: The project key
|
|
136
|
+
limit: Maximum number of repositories to return (default: 25)
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
List of repository dictionaries with keys like 'slug', 'name', 'description'
|
|
140
|
+
"""
|
|
141
|
+
return await asyncio.to_thread(self._sync_client.list_repositories, project_key, limit)
|
|
142
|
+
|
|
143
|
+
async def get_repository(self, project_key: str, repository_slug: str) -> dict[str, Any]:
|
|
144
|
+
"""Get repository information asynchronously.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
project_key: The project key
|
|
148
|
+
repository_slug: The repository slug
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Repository dictionary with metadata
|
|
152
|
+
"""
|
|
153
|
+
return await asyncio.to_thread(self._sync_client.get_repository, project_key, repository_slug)
|
|
154
|
+
|
|
155
|
+
async def create_repository(
|
|
156
|
+
self, project_key: str, repository: str, forkable: bool = False, is_private: bool = True
|
|
157
|
+
) -> dict[str, Any]:
|
|
158
|
+
"""Create a new repository asynchronously.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
project_key: Project key
|
|
162
|
+
repository: Repository name
|
|
163
|
+
forkable: Whether the repository can be forked
|
|
164
|
+
is_private: Whether the repository is private
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Created repository dictionary
|
|
168
|
+
"""
|
|
169
|
+
return await asyncio.to_thread(
|
|
170
|
+
self._sync_client.create_repository, project_key, repository, forkable, is_private
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
async def update_repository(
|
|
174
|
+
self, project_key: str, repository_slug: str, description: str | None = None
|
|
175
|
+
) -> dict[str, Any]:
|
|
176
|
+
"""Update repository information asynchronously.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
project_key: Project key
|
|
180
|
+
repository_slug: Repository slug
|
|
181
|
+
description: New description
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Updated repository dictionary
|
|
185
|
+
"""
|
|
186
|
+
return await asyncio.to_thread(
|
|
187
|
+
self._sync_client.update_repository, project_key, repository_slug, description
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
async def delete_repository(self, project_key: str, repository_slug: str) -> None:
|
|
191
|
+
"""Delete a repository asynchronously (DANGER!).
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
project_key: Project key
|
|
195
|
+
repository_slug: Repository slug
|
|
196
|
+
"""
|
|
197
|
+
return await asyncio.to_thread(self._sync_client.delete_repository, project_key, repository_slug)
|
|
198
|
+
|
|
199
|
+
async def get_repository_labels(self, project_key: str, repository_slug: str) -> list[str]:
|
|
200
|
+
"""Get labels for a repository asynchronously.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
project_key: Project key
|
|
204
|
+
repository_slug: Repository slug
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
List of label strings
|
|
208
|
+
"""
|
|
209
|
+
return await asyncio.to_thread(self._sync_client.get_repository_labels, project_key, repository_slug)
|
|
210
|
+
|
|
211
|
+
async def get_default_branch(self, project_key: str, repository_slug: str) -> dict[str, Any]:
|
|
212
|
+
"""Get default branch for a repository asynchronously.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
project_key: Project key
|
|
216
|
+
repository_slug: Repository slug
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Default branch dictionary
|
|
220
|
+
"""
|
|
221
|
+
return await asyncio.to_thread(self._sync_client.get_default_branch, project_key, repository_slug)
|
|
222
|
+
|
|
223
|
+
async def set_repository_label(
|
|
224
|
+
self, project_key: str, repository_slug: str, label_name: str
|
|
225
|
+
) -> dict[str, Any]:
|
|
226
|
+
"""Set a label for a repository asynchronously.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
project_key: Project key
|
|
230
|
+
repository_slug: Repository slug
|
|
231
|
+
label_name: Label to set
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Result dictionary
|
|
235
|
+
"""
|
|
236
|
+
return await asyncio.to_thread(
|
|
237
|
+
self._sync_client.set_repository_label, project_key, repository_slug, label_name
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# =========================================================================
|
|
241
|
+
# Branch Management (BitbucketBranchClient)
|
|
242
|
+
# =========================================================================
|
|
243
|
+
|
|
244
|
+
async def get_branches(
|
|
245
|
+
self,
|
|
246
|
+
project_key: str,
|
|
247
|
+
repository_slug: str,
|
|
248
|
+
filter: str = "",
|
|
249
|
+
limit: int = 99999,
|
|
250
|
+
details: bool = True,
|
|
251
|
+
) -> list[dict[str, Any]]:
|
|
252
|
+
"""Get branches from a repository asynchronously.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
project_key: The project key
|
|
256
|
+
repository_slug: The repository slug
|
|
257
|
+
filter: Optional filter string for branch names
|
|
258
|
+
limit: Maximum number of branches to return (default: 99999)
|
|
259
|
+
details: Whether to include branch details (default: True)
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
List of branch dictionaries with metadata
|
|
263
|
+
"""
|
|
264
|
+
return await asyncio.to_thread(
|
|
265
|
+
self._sync_client.get_branches, project_key, repository_slug, filter, limit, details
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
async def create_branch(
|
|
269
|
+
self, project_key: str, repository_slug: str, name: str, start_point: str, message: str | None = None
|
|
270
|
+
) -> dict[str, Any]:
|
|
271
|
+
"""Create a branch asynchronously.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
project_key: Project key
|
|
275
|
+
repository_slug: Repository slug
|
|
276
|
+
name: Branch name
|
|
277
|
+
start_point: Starting commit/branch
|
|
278
|
+
message: Optional message
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
Created branch dictionary
|
|
282
|
+
"""
|
|
283
|
+
return await asyncio.to_thread(
|
|
284
|
+
self._sync_client.create_branch, project_key, repository_slug, name, start_point, message
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
async def delete_branch(
|
|
288
|
+
self, project_key: str, repository_slug: str, name: str, end_point: str | None = None
|
|
289
|
+
) -> dict[str, Any]:
|
|
290
|
+
"""Delete a branch asynchronously.
|
|
291
|
+
|
|
292
|
+
Args:
|
|
293
|
+
project_key: Project key
|
|
294
|
+
repository_slug: Repository slug
|
|
295
|
+
name: Branch name
|
|
296
|
+
end_point: Optional end point
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
Result dictionary
|
|
300
|
+
"""
|
|
301
|
+
return await asyncio.to_thread(
|
|
302
|
+
self._sync_client.delete_branch, project_key, repository_slug, name, end_point
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
async def list_branch_permissions(
|
|
306
|
+
self,
|
|
307
|
+
project_key: str,
|
|
308
|
+
repository_slug: str | None = None,
|
|
309
|
+
start: int = 0,
|
|
310
|
+
limit: int = 25,
|
|
311
|
+
) -> list[dict[str, Any]]:
|
|
312
|
+
"""List branch permissions asynchronously.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
project_key: The project key
|
|
316
|
+
repository_slug: Optional repository slug (required for cloud mode)
|
|
317
|
+
start: Start index for pagination (default: 0)
|
|
318
|
+
limit: Maximum number of permissions to return (default: 25)
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
Normalized list of branch restriction objects
|
|
322
|
+
"""
|
|
323
|
+
return await asyncio.to_thread(
|
|
324
|
+
self._sync_client.list_branch_permissions, project_key, repository_slug, start, limit
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
# =========================================================================
|
|
328
|
+
# Tag Management
|
|
329
|
+
# =========================================================================
|
|
330
|
+
|
|
331
|
+
async def get_tags(
|
|
332
|
+
self, project_key: str, repository_slug: str, filter: str = "", limit: int = 99999
|
|
333
|
+
) -> list[dict[str, Any]]:
|
|
334
|
+
"""Get tags for a repository asynchronously.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
project_key: Project key
|
|
338
|
+
repository_slug: Repository slug
|
|
339
|
+
filter: Optional filter string
|
|
340
|
+
limit: Maximum number of tags
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
List of tag dictionaries
|
|
344
|
+
"""
|
|
345
|
+
return await asyncio.to_thread(
|
|
346
|
+
self._sync_client.get_tags, project_key, repository_slug, filter, limit
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
async def set_tag(
|
|
350
|
+
self,
|
|
351
|
+
project_key: str,
|
|
352
|
+
repository_slug: str,
|
|
353
|
+
tag_name: str,
|
|
354
|
+
commit_revision: str,
|
|
355
|
+
description: str | None = None,
|
|
356
|
+
) -> dict[str, Any]:
|
|
357
|
+
"""Set a tag asynchronously.
|
|
358
|
+
|
|
359
|
+
Args:
|
|
360
|
+
project_key: Project key
|
|
361
|
+
repository_slug: Repository slug
|
|
362
|
+
tag_name: Tag name
|
|
363
|
+
commit_revision: Commit to tag
|
|
364
|
+
description: Optional description
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
Created tag dictionary
|
|
368
|
+
"""
|
|
369
|
+
return await asyncio.to_thread(
|
|
370
|
+
self._sync_client.set_tag, project_key, repository_slug, tag_name, commit_revision, description
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
async def delete_tag(self, project_key: str, repository_slug: str, tag_name: str) -> dict[str, Any]:
|
|
374
|
+
"""Delete a tag asynchronously.
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
project_key: Project key
|
|
378
|
+
repository_slug: Repository slug
|
|
379
|
+
tag_name: Tag name
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
Result dictionary
|
|
383
|
+
"""
|
|
384
|
+
return await asyncio.to_thread(self._sync_client.delete_tag, project_key, repository_slug, tag_name)
|
|
385
|
+
|
|
386
|
+
# =========================================================================
|
|
387
|
+
# Code Operations (BitbucketCodeClient)
|
|
388
|
+
# =========================================================================
|
|
389
|
+
|
|
390
|
+
async def get_content_of_file(
|
|
391
|
+
self,
|
|
392
|
+
project_key: str,
|
|
393
|
+
repository_slug: str,
|
|
394
|
+
filename: str,
|
|
395
|
+
at: str | None = None,
|
|
396
|
+
markup: str | None = None,
|
|
397
|
+
) -> str:
|
|
398
|
+
"""Get raw content of a file from repository asynchronously.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
project_key: The project key
|
|
402
|
+
repository_slug: The repository slug
|
|
403
|
+
filename: Path to the file in the repository
|
|
404
|
+
at: Optional commit hash, branch, or tag to retrieve file at
|
|
405
|
+
markup: Optional markup format for rendering
|
|
406
|
+
|
|
407
|
+
Returns:
|
|
408
|
+
File content as string
|
|
409
|
+
"""
|
|
410
|
+
return await asyncio.to_thread(
|
|
411
|
+
self._sync_client.get_content_of_file, project_key, repository_slug, filename, at, markup
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
async def get_commits(
|
|
415
|
+
self,
|
|
416
|
+
project_key: str,
|
|
417
|
+
repository_slug: str,
|
|
418
|
+
hash_oldest: str | None = None,
|
|
419
|
+
hash_newest: str | None = None,
|
|
420
|
+
limit: int = 99999,
|
|
421
|
+
) -> list[dict[str, Any]]:
|
|
422
|
+
"""Get commit list from repository asynchronously.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
project_key: The project key
|
|
426
|
+
repository_slug: The repository slug
|
|
427
|
+
hash_oldest: Optional oldest commit hash to start from
|
|
428
|
+
hash_newest: Optional newest commit hash to end at
|
|
429
|
+
limit: Maximum number of commits to return (default: 99999)
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
List of commit dictionaries with metadata
|
|
433
|
+
"""
|
|
434
|
+
return await asyncio.to_thread(
|
|
435
|
+
self._sync_client.get_commits, project_key, repository_slug, hash_oldest, hash_newest, limit
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
# =========================================================================
|
|
439
|
+
# Pull Request Management
|
|
440
|
+
# =========================================================================
|
|
441
|
+
|
|
442
|
+
async def list_pull_requests(
|
|
443
|
+
self,
|
|
444
|
+
project_key: str,
|
|
445
|
+
repository_slug: str,
|
|
446
|
+
state: str = "OPEN",
|
|
447
|
+
order: str = "newest",
|
|
448
|
+
limit: int = 100,
|
|
449
|
+
start: int = 0,
|
|
450
|
+
) -> list[dict[str, Any]]:
|
|
451
|
+
"""List pull requests asynchronously.
|
|
452
|
+
|
|
453
|
+
Args:
|
|
454
|
+
project_key: Project key
|
|
455
|
+
repository_slug: Repository slug
|
|
456
|
+
state: PR state (OPEN, MERGED, DECLINED)
|
|
457
|
+
order: Sort order (newest, oldest)
|
|
458
|
+
limit: Maximum number of PRs to return
|
|
459
|
+
start: Start index for pagination
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
List of pull request dictionaries
|
|
463
|
+
"""
|
|
464
|
+
return await asyncio.to_thread(
|
|
465
|
+
self._sync_client.list_pull_requests, project_key, repository_slug, state, order, limit, start
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
async def get_pull_request(
|
|
469
|
+
self, project_key: str, repository_slug: str, pull_request_id: str
|
|
470
|
+
) -> dict[str, Any]:
|
|
471
|
+
"""Get a specific pull request asynchronously.
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
project_key: Project key
|
|
475
|
+
repository_slug: Repository slug
|
|
476
|
+
pull_request_id: Pull request ID
|
|
477
|
+
|
|
478
|
+
Returns:
|
|
479
|
+
Pull request dictionary
|
|
480
|
+
"""
|
|
481
|
+
return await asyncio.to_thread(
|
|
482
|
+
self._sync_client.get_pull_request, project_key, repository_slug, pull_request_id
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
async def create_pull_request(
|
|
486
|
+
self,
|
|
487
|
+
source_project: str,
|
|
488
|
+
source_repo: str,
|
|
489
|
+
dest_project: str,
|
|
490
|
+
dest_repo: str,
|
|
491
|
+
source_branch: str,
|
|
492
|
+
destination_branch: str,
|
|
493
|
+
title: str,
|
|
494
|
+
description: str,
|
|
495
|
+
reviewers: list[str] | None = None,
|
|
496
|
+
) -> dict[str, Any]:
|
|
497
|
+
"""Create a pull request asynchronously.
|
|
498
|
+
|
|
499
|
+
Args:
|
|
500
|
+
source_project: Source project key
|
|
501
|
+
source_repo: Source repository slug
|
|
502
|
+
dest_project: Destination project key
|
|
503
|
+
dest_repo: Destination repository slug
|
|
504
|
+
source_branch: Source branch name
|
|
505
|
+
destination_branch: Destination branch name
|
|
506
|
+
title: PR title
|
|
507
|
+
description: PR description
|
|
508
|
+
reviewers: Optional list of reviewer usernames
|
|
509
|
+
|
|
510
|
+
Returns:
|
|
511
|
+
Created pull request dictionary
|
|
512
|
+
"""
|
|
513
|
+
return await asyncio.to_thread(
|
|
514
|
+
self._sync_client.create_pull_request,
|
|
515
|
+
source_project,
|
|
516
|
+
source_repo,
|
|
517
|
+
dest_project,
|
|
518
|
+
dest_repo,
|
|
519
|
+
source_branch,
|
|
520
|
+
destination_branch,
|
|
521
|
+
title,
|
|
522
|
+
description,
|
|
523
|
+
reviewers,
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
async def add_pull_request_comment(
|
|
527
|
+
self,
|
|
528
|
+
project_key: str,
|
|
529
|
+
repository_slug: str,
|
|
530
|
+
pull_request_id: str,
|
|
531
|
+
text: str,
|
|
532
|
+
parent_id: str | None = None,
|
|
533
|
+
) -> dict[str, Any]:
|
|
534
|
+
"""Add a comment to a pull request asynchronously.
|
|
535
|
+
|
|
536
|
+
Args:
|
|
537
|
+
project_key: Project key
|
|
538
|
+
repository_slug: Repository slug
|
|
539
|
+
pull_request_id: Pull request ID
|
|
540
|
+
text: Comment text
|
|
541
|
+
parent_id: Optional parent comment ID for replies
|
|
542
|
+
|
|
543
|
+
Returns:
|
|
544
|
+
Created comment dictionary
|
|
545
|
+
"""
|
|
546
|
+
return await asyncio.to_thread(
|
|
547
|
+
self._sync_client.add_pull_request_comment,
|
|
548
|
+
project_key,
|
|
549
|
+
repository_slug,
|
|
550
|
+
pull_request_id,
|
|
551
|
+
text,
|
|
552
|
+
parent_id,
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
async def get_pull_request_activities(
|
|
556
|
+
self, project_key: str, repository_slug: str, pull_request_id: str
|
|
557
|
+
) -> list[dict[str, Any]]:
|
|
558
|
+
"""Get pull request activities asynchronously.
|
|
559
|
+
|
|
560
|
+
Args:
|
|
561
|
+
project_key: Project key
|
|
562
|
+
repository_slug: Repository slug
|
|
563
|
+
pull_request_id: Pull request ID
|
|
564
|
+
|
|
565
|
+
Returns:
|
|
566
|
+
List of activity dictionaries
|
|
567
|
+
"""
|
|
568
|
+
return await asyncio.to_thread(
|
|
569
|
+
self._sync_client.get_pull_request_activities, project_key, repository_slug, pull_request_id
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
async def get_pull_request_changes(
|
|
573
|
+
self, project_key: str, repository_slug: str, pull_request_id: str
|
|
574
|
+
) -> list[dict[str, Any]]:
|
|
575
|
+
"""Get pull request changes asynchronously.
|
|
576
|
+
|
|
577
|
+
Args:
|
|
578
|
+
project_key: Project key
|
|
579
|
+
repository_slug: Repository slug
|
|
580
|
+
pull_request_id: Pull request ID
|
|
581
|
+
|
|
582
|
+
Returns:
|
|
583
|
+
List of change dictionaries
|
|
584
|
+
"""
|
|
585
|
+
return await asyncio.to_thread(
|
|
586
|
+
self._sync_client.get_pull_request_changes, project_key, repository_slug, pull_request_id
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
async def merge_pull_request(
|
|
590
|
+
self, project_key: str, repository_slug: str, pull_request_id: str
|
|
591
|
+
) -> dict[str, Any]:
|
|
592
|
+
"""Merge a pull request asynchronously.
|
|
593
|
+
|
|
594
|
+
Args:
|
|
595
|
+
project_key: Project key
|
|
596
|
+
repository_slug: Repository slug
|
|
597
|
+
pull_request_id: Pull request ID
|
|
598
|
+
|
|
599
|
+
Returns:
|
|
600
|
+
Merge result dictionary
|
|
601
|
+
"""
|
|
602
|
+
return await asyncio.to_thread(
|
|
603
|
+
self._sync_client.merge_pull_request, project_key, repository_slug, pull_request_id
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
# =========================================================================
|
|
607
|
+
# Pipeline Management (Bitbucket Cloud only)
|
|
608
|
+
# =========================================================================
|
|
609
|
+
|
|
610
|
+
async def list_pipelines(
|
|
611
|
+
self, workspace: str, repository: str, limit: int = 10
|
|
612
|
+
) -> list[dict[str, Any]]:
|
|
613
|
+
"""List pipelines asynchronously (Bitbucket Cloud only).
|
|
614
|
+
|
|
615
|
+
Args:
|
|
616
|
+
workspace: Workspace name
|
|
617
|
+
repository: Repository name
|
|
618
|
+
limit: Maximum number of pipelines
|
|
619
|
+
|
|
620
|
+
Returns:
|
|
621
|
+
List of pipeline dictionaries
|
|
622
|
+
"""
|
|
623
|
+
return await asyncio.to_thread(self._sync_client.list_pipelines, workspace, repository, limit)
|
|
624
|
+
|
|
625
|
+
async def trigger_pipeline(
|
|
626
|
+
self, workspace: str, repository: str, branch: str = "master"
|
|
627
|
+
) -> dict[str, Any]:
|
|
628
|
+
"""Trigger a pipeline asynchronously (Bitbucket Cloud only).
|
|
629
|
+
|
|
630
|
+
Args:
|
|
631
|
+
workspace: Workspace name
|
|
632
|
+
repository: Repository name
|
|
633
|
+
branch: Branch to trigger pipeline on
|
|
634
|
+
|
|
635
|
+
Returns:
|
|
636
|
+
Triggered pipeline dictionary
|
|
637
|
+
"""
|
|
638
|
+
return await asyncio.to_thread(self._sync_client.trigger_pipeline, workspace, repository, branch)
|
|
639
|
+
|
|
640
|
+
# =========================================================================
|
|
641
|
+
# User and Group Management
|
|
642
|
+
# =========================================================================
|
|
643
|
+
|
|
644
|
+
async def list_groups(self, group_filter: str | None = None, limit: int = 25) -> list[dict[str, Any]]:
|
|
645
|
+
"""List all available groups asynchronously.
|
|
646
|
+
|
|
647
|
+
Args:
|
|
648
|
+
group_filter: Optional filter string
|
|
649
|
+
limit: Maximum number of groups
|
|
650
|
+
|
|
651
|
+
Returns:
|
|
652
|
+
List of group dictionaries
|
|
653
|
+
"""
|
|
654
|
+
return await asyncio.to_thread(self._sync_client.list_groups, group_filter, limit)
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
__all__ = ["AsyncBitbucketClient"]
|