@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.
Files changed (303) hide show
  1. package/package.json +2 -2
  2. package/src/global.js +70 -10
  3. package/tools/skills/vds-scripts-skill/.openskills.json +6 -0
  4. package/tools/skills/vds-scripts-skill/QUALITY.md +44 -0
  5. package/tools/skills/vds-scripts-skill/SKILL.md +135 -0
  6. package/tools/skills/vds-scripts-skill/references/audit-commands.md +171 -0
  7. package/tools/skills/vds-scripts-skill/references/capability-index.md +34 -0
  8. package/tools/skills/vds-scripts-skill/references/development-commands.md +12 -0
  9. package/tools/skills/vds-scripts-skill/references/google-sheets.md +73 -0
  10. package/tools/skills/vds-scripts-skill/references/integration-commands.md +17 -0
  11. package/tools/skills/vds-scripts-skill/references/platform-bootstrap.md +31 -0
  12. package/tools/skills/vds-scripts-skill/references/specialist-routing.md +14 -0
  13. package/tools/skills/vds-scripts-skill/references/validation-commands.md +15 -0
  14. package/tools/skills/vsaf-build/SKILL.md +32 -2
  15. package/tools/skills/vsaf-ship/SKILL.md +41 -10
  16. package/tools/skills/vsaf-test/SKILL.md +8 -0
  17. package/tools/vds-scripts/.mcp.json +11 -0
  18. package/tools/vds-scripts/.secrets.baseline +133 -0
  19. package/tools/vds-scripts/AGENTS.md +152 -0
  20. package/tools/vds-scripts/CLAUDE.md +101 -0
  21. package/tools/vds-scripts/CLI_COMMAND_OPTIMIZATION.md +156 -0
  22. package/tools/vds-scripts/PACKAGE_P125B_IMPLEMENTATION_SUMMARY.md +131 -0
  23. package/tools/vds-scripts/PROJECT_COMPLETION_SUMMARY.md +45 -0
  24. package/tools/vds-scripts/README.md +97 -0
  25. package/tools/vds-scripts/bitbucket_manifest_mapping.toml +34 -0
  26. package/tools/vds-scripts/bitbucket_orchestrator/ARCHITECTURE_ANALYSIS.md +258 -0
  27. package/tools/vds-scripts/bitbucket_orchestrator/BITBUCKET_API_PRACTICES.md +393 -0
  28. package/tools/vds-scripts/bitbucket_orchestrator/EVALUATION_REPORT.md +61 -0
  29. package/tools/vds-scripts/bitbucket_orchestrator/FEATURES.md +908 -0
  30. package/tools/vds-scripts/bitbucket_orchestrator/README.md +687 -0
  31. package/tools/vds-scripts/bitbucket_orchestrator/pyproject.toml +40 -0
  32. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/__init__.py +20 -0
  33. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py +657 -0
  34. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/cli.py +2108 -0
  35. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/client.py +2534 -0
  36. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/config.py +171 -0
  37. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/errors.py +67 -0
  38. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/factory.py +185 -0
  39. package/tools/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/protocols.py +244 -0
  40. package/tools/vds-scripts/bitbucket_orchestrator/tests/__init__.py +8 -0
  41. package/tools/vds-scripts/bitbucket_orchestrator/tests/conftest.py +65 -0
  42. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_advanced_search.py +151 -0
  43. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_async_client.py +546 -0
  44. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_branch_permissions.py +145 -0
  45. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_cli.py +115 -0
  46. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client.py +157 -0
  47. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_branch_conditions.py +79 -0
  48. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_code_advanced.py +163 -0
  49. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_code_file.py +32 -0
  50. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_deployment_environments.py +194 -0
  51. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_issues.py +164 -0
  52. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_pipelines_advanced.py +179 -0
  53. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_pr_blockers.py +119 -0
  54. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_client_repository_variables.py +156 -0
  55. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_code.py +98 -0
  56. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_code_advanced.py +282 -0
  57. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_code_insights.py +335 -0
  58. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_conditions.py +147 -0
  59. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_config.py +131 -0
  60. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_deployment_env.py +352 -0
  61. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_factory.py +371 -0
  62. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_fork_operations.py +204 -0
  63. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_issue_cli.py +261 -0
  64. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_pipeline_advanced.py +270 -0
  65. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_pr_blocker.py +204 -0
  66. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_protocols.py +334 -0
  67. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_repo_settings.py +343 -0
  68. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_repo_variables.py +270 -0
  69. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_webhooks.py +189 -0
  70. package/tools/vds-scripts/bitbucket_orchestrator/tests/test_workspace.py +233 -0
  71. package/tools/vds-scripts/bitbucket_orchestrator/uv.lock +742 -0
  72. package/tools/vds-scripts/confluence_orchestrator/Dockerfile +19 -0
  73. package/tools/vds-scripts/confluence_orchestrator/README.md +412 -0
  74. package/tools/vds-scripts/confluence_orchestrator/SYNC_SCRIPTS.md +127 -0
  75. package/tools/vds-scripts/confluence_orchestrator/SYNC_STANDARDIZATION.md +108 -0
  76. package/tools/vds-scripts/confluence_orchestrator/pyproject.toml +48 -0
  77. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/__init__.py +20 -0
  78. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/cli.py +2532 -0
  79. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/config.py +175 -0
  80. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content.py +290 -0
  81. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content_v2.py +94 -0
  82. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/crawl_tree.py +1835 -0
  83. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/errors.py +80 -0
  84. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/eventing.py +109 -0
  85. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/http.py +1114 -0
  86. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/orchestration.py +165 -0
  87. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/reporting.py +78 -0
  88. package/tools/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/tree.py +121 -0
  89. package/tools/vds-scripts/confluence_orchestrator/sync_pdfs_from_markdown.py +213 -0
  90. package/tools/vds-scripts/confluence_orchestrator/sync_pdfs_to_confluence.py +305 -0
  91. package/tools/vds-scripts/confluence_orchestrator/sync_png_attachments.py +305 -0
  92. package/tools/vds-scripts/confluence_orchestrator/tests/__init__.py +0 -0
  93. package/tools/vds-scripts/confluence_orchestrator/tests/conftest.py +8 -0
  94. package/tools/vds-scripts/confluence_orchestrator/tests/test_advanced_content.py +224 -0
  95. package/tools/vds-scripts/confluence_orchestrator/tests/test_advanced_search.py +188 -0
  96. package/tools/vds-scripts/confluence_orchestrator/tests/test_cache_management.py +247 -0
  97. package/tools/vds-scripts/confluence_orchestrator/tests/test_cli.py +499 -0
  98. package/tools/vds-scripts/confluence_orchestrator/tests/test_config.py +83 -0
  99. package/tools/vds-scripts/confluence_orchestrator/tests/test_content.py +186 -0
  100. package/tools/vds-scripts/confluence_orchestrator/tests/test_content_flags.py +27 -0
  101. package/tools/vds-scripts/confluence_orchestrator/tests/test_crawl_tree.py +2250 -0
  102. package/tools/vds-scripts/confluence_orchestrator/tests/test_draft_management.py +223 -0
  103. package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing.py +71 -0
  104. package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing_chaos.py +37 -0
  105. package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing_rate_limit.py +44 -0
  106. package/tools/vds-scripts/confluence_orchestrator/tests/test_eventing_timeout.py +49 -0
  107. package/tools/vds-scripts/confluence_orchestrator/tests/test_export.py +230 -0
  108. package/tools/vds-scripts/confluence_orchestrator/tests/test_history.py +204 -0
  109. package/tools/vds-scripts/confluence_orchestrator/tests/test_http.py +117 -0
  110. package/tools/vds-scripts/confluence_orchestrator/tests/test_orchestration.py +91 -0
  111. package/tools/vds-scripts/confluence_orchestrator/tests/test_reporting.py +24 -0
  112. package/tools/vds-scripts/confluence_orchestrator/tests/test_search_cql.py +34 -0
  113. package/tools/vds-scripts/confluence_orchestrator/tests/test_space_management.py +237 -0
  114. package/tools/vds-scripts/confluence_orchestrator/tests/test_space_permissions.py +332 -0
  115. package/tools/vds-scripts/confluence_orchestrator/tests/test_user_group_management.py +388 -0
  116. package/tools/vds-scripts/confluence_orchestrator/uv.lock +1023 -0
  117. package/tools/vds-scripts/git_orchestrator/ENHANCEMENT_SUMMARY.md +119 -0
  118. package/tools/vds-scripts/git_orchestrator/README.md +280 -0
  119. package/tools/vds-scripts/git_orchestrator/VERIFICATION_REPORT.md +152 -0
  120. package/tools/vds-scripts/git_orchestrator/pyproject.toml +35 -0
  121. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__init__.py +7 -0
  122. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__main__.py +4 -0
  123. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/cli.py +847 -0
  124. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/logging_config.py +63 -0
  125. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/manifest.py +129 -0
  126. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/orchestrator.py +819 -0
  127. package/tools/vds-scripts/git_orchestrator/src/vds_git_orchestrator/reporting.py +53 -0
  128. package/tools/vds-scripts/git_orchestrator/tests/__init__.py +0 -0
  129. package/tools/vds-scripts/git_orchestrator/tests/test_cli_settings.py +21 -0
  130. package/tools/vds-scripts/git_orchestrator/tests/test_integration.py +74 -0
  131. package/tools/vds-scripts/git_orchestrator/tests/test_manifest.py +79 -0
  132. package/tools/vds-scripts/git_orchestrator/tests/test_orchestrator.py +204 -0
  133. package/tools/vds-scripts/git_orchestrator/tests/test_public_api.py +236 -0
  134. package/tools/vds-scripts/git_orchestrator/tests/test_resilience.py +345 -0
  135. package/tools/vds-scripts/git_orchestrator/uv.lock +271 -0
  136. package/tools/vds-scripts/jira_orchestrator/README.md +770 -0
  137. package/tools/vds-scripts/jira_orchestrator/pyproject.toml +39 -0
  138. package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/__init__.py +1 -0
  139. package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/adapter.py +1320 -0
  140. package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/cli.py +2271 -0
  141. package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/config.py +138 -0
  142. package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/errors.py +67 -0
  143. package/tools/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/reporting.py +65 -0
  144. package/tools/vds-scripts/jira_orchestrator/tests/__init__.py +1 -0
  145. package/tools/vds-scripts/jira_orchestrator/tests/conftest.py +86 -0
  146. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_agile_list_payloads.py +54 -0
  147. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_bulk_operations.py +69 -0
  148. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_components.py +57 -0
  149. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_createmeta.py +45 -0
  150. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_dashboard.py +117 -0
  151. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_issue_properties.py +54 -0
  152. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_permissions_compat.py +42 -0
  153. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_reindex.py +42 -0
  154. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_remote_links.py +76 -0
  155. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_transitions.py +91 -0
  156. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_user_management.py +110 -0
  157. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_version_management.py +133 -0
  158. package/tools/vds-scripts/jira_orchestrator/tests/test_adapter_watchers.py +41 -0
  159. package/tools/vds-scripts/jira_orchestrator/tests/test_advanced_search.py +164 -0
  160. package/tools/vds-scripts/jira_orchestrator/tests/test_agile.py +256 -0
  161. package/tools/vds-scripts/jira_orchestrator/tests/test_application_properties.py +193 -0
  162. package/tools/vds-scripts/jira_orchestrator/tests/test_backlog.py +91 -0
  163. package/tools/vds-scripts/jira_orchestrator/tests/test_bulk_operations.py +277 -0
  164. package/tools/vds-scripts/jira_orchestrator/tests/test_cli.py +106 -0
  165. package/tools/vds-scripts/jira_orchestrator/tests/test_components.py +106 -0
  166. package/tools/vds-scripts/jira_orchestrator/tests/test_config.py +164 -0
  167. package/tools/vds-scripts/jira_orchestrator/tests/test_dashboard.py +122 -0
  168. package/tools/vds-scripts/jira_orchestrator/tests/test_discover_fields.py +207 -0
  169. package/tools/vds-scripts/jira_orchestrator/tests/test_filter_management.py +333 -0
  170. package/tools/vds-scripts/jira_orchestrator/tests/test_issue_archiving.py +164 -0
  171. package/tools/vds-scripts/jira_orchestrator/tests/test_issue_links.py +257 -0
  172. package/tools/vds-scripts/jira_orchestrator/tests/test_issue_properties.py +171 -0
  173. package/tools/vds-scripts/jira_orchestrator/tests/test_link_types.py +314 -0
  174. package/tools/vds-scripts/jira_orchestrator/tests/test_parse_set.py +37 -0
  175. package/tools/vds-scripts/jira_orchestrator/tests/test_permissions.py +273 -0
  176. package/tools/vds-scripts/jira_orchestrator/tests/test_reindex.py +81 -0
  177. package/tools/vds-scripts/jira_orchestrator/tests/test_remote_links.py +254 -0
  178. package/tools/vds-scripts/jira_orchestrator/tests/test_security_schemes.py +170 -0
  179. package/tools/vds-scripts/jira_orchestrator/tests/test_transitions_changelog.py +114 -0
  180. package/tools/vds-scripts/jira_orchestrator/tests/test_user_management.py +226 -0
  181. package/tools/vds-scripts/jira_orchestrator/tests/test_version_management.py +339 -0
  182. package/tools/vds-scripts/jira_orchestrator/tests/test_watchers.py +101 -0
  183. package/tools/vds-scripts/jira_orchestrator/tests/test_worklog.py +223 -0
  184. package/tools/vds-scripts/jira_orchestrator/uv.lock +738 -0
  185. package/tools/vds-scripts/mcp_server/Dockerfile +34 -0
  186. package/tools/vds-scripts/mcp_server/README.md +140 -0
  187. package/tools/vds-scripts/mcp_server/pyproject.toml +42 -0
  188. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/__init__.py +4 -0
  189. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/config.py +36 -0
  190. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/server.py +66 -0
  191. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/__init__.py +14 -0
  192. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/bitbucket_tools.py +47 -0
  193. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/confluence_tools.py +59 -0
  194. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/git_tools.py +71 -0
  195. package/tools/vds-scripts/mcp_server/src/vds_mcp_server/tools/jira_tools.py +63 -0
  196. package/tools/vds-scripts/mcp_server/tests/__init__.py +2 -0
  197. package/tools/vds-scripts/mcp_server/tests/conftest.py +29 -0
  198. package/tools/vds-scripts/mcp_server/tests/unit/__init__.py +2 -0
  199. package/tools/vds-scripts/mcp_server/tests/unit/test_bitbucket_tools.py +25 -0
  200. package/tools/vds-scripts/mcp_server/tests/unit/test_confluence_tools.py +25 -0
  201. package/tools/vds-scripts/mcp_server/tests/unit/test_git_tools.py +32 -0
  202. package/tools/vds-scripts/mcp_server/tests/unit/test_jira_tools.py +32 -0
  203. package/tools/vds-scripts/mcp_server/tests/verification/__init__.py +2 -0
  204. package/tools/vds-scripts/mcp_server/tests/verification/test_mcp_confluence_tools.py +40 -0
  205. package/tools/vds-scripts/mcp_server/tests/verification/test_mcp_jira_tools.py +37 -0
  206. package/tools/vds-scripts/mcp_server/tests/verification/test_mcp_tool_registration.py +47 -0
  207. package/tools/vds-scripts/mcp_server/uv.lock +1032 -0
  208. package/tools/vds-scripts/mypy.ini +5 -0
  209. package/tools/vds-scripts/pyproject.toml +29 -0
  210. package/tools/vds-scripts/repo-manifest.yaml +273 -0
  211. package/tools/vds-scripts/repo-manifest.yaml.example +25 -0
  212. package/tools/vds-scripts/scripts/BRD-Validation-API.postman_collection.json +706 -0
  213. package/tools/vds-scripts/scripts/BRD-Validation-README.md +308 -0
  214. package/tools/vds-scripts/scripts/README.md +162 -0
  215. package/tools/vds-scripts/scripts/bootstrap_uv.sh +30 -0
  216. package/tools/vds-scripts/scripts/brd-validation-environment.json +51 -0
  217. package/tools/vds-scripts/scripts/brd-validation-test-results.json +13023 -0
  218. package/tools/vds-scripts/scripts/brd_coverage_report.json +276 -0
  219. package/tools/vds-scripts/scripts/create_memory_session.py +35 -0
  220. package/tools/vds-scripts/scripts/deployment/load_docker_images_offline.sh +90 -0
  221. package/tools/vds-scripts/scripts/final_completion_report.md +139 -0
  222. package/tools/vds-scripts/scripts/folder_structure_report.json +321 -0
  223. package/tools/vds-scripts/scripts/generate_completion_report.py +125 -0
  224. package/tools/vds-scripts/scripts/generate_intellij_modules.py +150 -0
  225. package/tools/vds-scripts/scripts/link_integrity_report.json +807 -0
  226. package/tools/vds-scripts/scripts/move_audit_artifact_pages.py +255 -0
  227. package/tools/vds-scripts/scripts/move_audit_artifact_pages_rest.py +165 -0
  228. package/tools/vds-scripts/scripts/move_wrong_dept_pages.py +216 -0
  229. package/tools/vds-scripts/scripts/save_intellij_memories.py +120 -0
  230. package/tools/vds-scripts/scripts/save_memories_to_vds_ai.py +83 -0
  231. package/tools/vds-scripts/scripts/save_memories_vds_style.py +129 -0
  232. package/tools/vds-scripts/scripts/search_intellij_memories.py +50 -0
  233. package/tools/vds-scripts/scripts/setup_intellij_workspace.py +65 -0
  234. package/tools/vds-scripts/scripts/target-state-automation/README.md +89 -0
  235. package/tools/vds-scripts/scripts/target-state-automation/confluence_sync_coordinator.sh +27 -0
  236. package/tools/vds-scripts/scripts/target-state-automation/coordination.sh +114 -0
  237. package/tools/vds-scripts/scripts/target-state-automation/diagram_coordinator.sh +25 -0
  238. package/tools/vds-scripts/scripts/target-state-automation/docs_root.sh +22 -0
  239. package/tools/vds-scripts/scripts/target-state-automation/generate_diagrams.sh +22 -0
  240. package/tools/vds-scripts/scripts/target-state-automation/markdown_coordinator.sh +25 -0
  241. package/tools/vds-scripts/scripts/target-state-automation/progress_dashboard.sh +17 -0
  242. package/tools/vds-scripts/scripts/target-state-automation/schema_coordinator.sh +25 -0
  243. package/tools/vds-scripts/scripts/target-state-automation/sync_confluence.sh +30 -0
  244. package/tools/vds-scripts/scripts/target-state-automation/update_dependencies.sh +19 -0
  245. package/tools/vds-scripts/scripts/target-state-automation/validate_links.sh +86 -0
  246. package/tools/vds-scripts/scripts/target-state-automation/validate_markdown.sh +52 -0
  247. package/tools/vds-scripts/scripts/target-state-automation/validate_schemas.sh +26 -0
  248. package/tools/vds-scripts/scripts/target-state-automation/validate_structure.sh +98 -0
  249. package/tools/vds-scripts/scripts/update_modules_xml.py +190 -0
  250. package/tools/vds-scripts/scripts/uv-workspace-alignment-verification-2026-03-25.md +128 -0
  251. package/tools/vds-scripts/scripts/validate_brd_coverage.py +179 -0
  252. package/tools/vds-scripts/scripts/validate_folder_structure.py +240 -0
  253. package/tools/vds-scripts/scripts/validate_link_integrity.py +272 -0
  254. package/tools/vds-scripts/scripts/vds_sh_helpers.sh +180 -0
  255. package/tools/vds-scripts/scripts/verification/phase2_portable_paths_ubuntu_docker.sh +26 -0
  256. package/tools/vds-scripts/scripts/worktree_uv.sh +48 -0
  257. package/tools/vds-scripts/uv.lock +8 -0
  258. package/tools/vds-scripts/vds_cli/README.md +126 -0
  259. package/tools/vds-scripts/vds_cli/VERIFICATION_REPORT.md +41 -0
  260. package/tools/vds-scripts/vds_cli/pyproject.toml +38 -0
  261. package/tools/vds-scripts/vds_cli/src/vds_cli/__init__.py +3 -0
  262. package/tools/vds-scripts/vds_cli/src/vds_cli/cli.py +173 -0
  263. package/tools/vds-scripts/vds_cli/src/vds_cli/docs_sync.py +1203 -0
  264. package/tools/vds-scripts/vds_cli/src/vds_cli/env.py +41 -0
  265. package/tools/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/__init__.py +3 -0
  266. package/tools/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/google_sheets_orchestrator.py +198 -0
  267. package/tools/vds-scripts/vds_cli/src/vds_cli/router.py +93 -0
  268. package/tools/vds-scripts/vds_cli/src/vds_cli/sync_api.py +647 -0
  269. package/tools/vds-scripts/vds_cli/src/vds_cli/sync_service.py +266 -0
  270. package/tools/vds-scripts/vds_cli/tests/__init__.py +2 -0
  271. package/tools/vds-scripts/vds_cli/tests/conftest.py +49 -0
  272. package/tools/vds-scripts/vds_cli/tests/unit/__init__.py +2 -0
  273. package/tools/vds-scripts/vds_cli/tests/unit/test_cli.py +143 -0
  274. package/tools/vds-scripts/vds_cli/tests/unit/test_docs_sync.py +422 -0
  275. package/tools/vds-scripts/vds_cli/tests/unit/test_env.py +51 -0
  276. package/tools/vds-scripts/vds_cli/tests/unit/test_router.py +72 -0
  277. package/tools/vds-scripts/vds_cli/tests/unit/test_sync_api.py +357 -0
  278. package/tools/vds-scripts/vds_cli/tests/unit/test_sync_service.py +160 -0
  279. package/tools/vds-scripts/vds_cli/tests/verification/__init__.py +2 -0
  280. package/tools/vds-scripts/vds_cli/tests/verification/test_bitbucket_real.py +33 -0
  281. package/tools/vds-scripts/vds_cli/tests/verification/test_confluence_real.py +35 -0
  282. package/tools/vds-scripts/vds_cli/tests/verification/test_jira_real.py +41 -0
  283. package/tools/vds-scripts/vds_cli/uv.lock +524 -0
  284. package/tools/vds-scripts/vds_cli_common/README.md +190 -0
  285. package/tools/vds-scripts/vds_cli_common/pyproject.toml +92 -0
  286. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/__init__.py +34 -0
  287. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/completers.py +139 -0
  288. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/context.py +201 -0
  289. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/env.py +119 -0
  290. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/errors.py +318 -0
  291. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/output.py +284 -0
  292. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/paths.py +78 -0
  293. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/testing.py +213 -0
  294. package/tools/vds-scripts/vds_cli_common/src/vds_cli_common/version.py +85 -0
  295. package/tools/vds-scripts/vds_cli_common/tests/__init__.py +1 -0
  296. package/tools/vds-scripts/vds_cli_common/tests/test_completers.py +148 -0
  297. package/tools/vds-scripts/vds_cli_common/tests/test_context.py +192 -0
  298. package/tools/vds-scripts/vds_cli_common/tests/test_env.py +102 -0
  299. package/tools/vds-scripts/vds_cli_common/tests/test_errors.py +186 -0
  300. package/tools/vds-scripts/vds_cli_common/tests/test_output.py +229 -0
  301. package/tools/vds-scripts/vds_cli_common/tests/test_paths.py +61 -0
  302. package/tools/vds-scripts/vds_cli_common/tests/test_testing.py +138 -0
  303. package/tools/vds-scripts/vds_cli_common/tests/test_version.py +64 -0
@@ -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"]