@ngocsangairvds/vsaf 4.1.8 → 4.1.9

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 (1065) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/dist/commands/skill.js +1 -1
  3. package/packages/cli/dist/commands/skill.js.map +1 -1
  4. package/skills/vds-skill/_shared/config-check.js +0 -76
  5. package/skills/vds-skill/_shared/credentials.js +0 -139
  6. package/skills/vds-skill/create-bitbucket-pr/SKILL.md +0 -57
  7. package/skills/vds-skill/create-bitbucket-pr/scripts/create-pr.js +0 -125
  8. package/skills/vds-skill/create-jira-epic/SKILL.md +0 -55
  9. package/skills/vds-skill/create-jira-epic/scripts/create-epic.js +0 -120
  10. package/skills/vds-skill/install-deps.mjs +0 -567
  11. package/skills/vds-skill/pack.yaml +0 -24
  12. package/skills/vds-skill/pull/SKILL.md +0 -38
  13. package/skills/vds-skill/pull/scripts/pull.js +0 -59
  14. package/skills/vds-skill/push-prd/SKILL.md +0 -227
  15. package/skills/vds-skill/push-srs/SKILL.md +0 -116
  16. package/skills/vds-skill/search-confluence/SKILL.md +0 -53
  17. package/skills/vds-skill/search-confluence/scripts/search.js +0 -114
  18. package/skills/vds-skill/vds-scripts/.claude/phase7-CLOSURE.md +0 -100
  19. package/skills/vds-skill/vds-scripts/.dockerignore +0 -62
  20. package/skills/vds-skill/vds-scripts/.github/ISSUE_TEMPLATE/cli-change.md +0 -92
  21. package/skills/vds-skill/vds-scripts/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -48
  22. package/skills/vds-skill/vds-scripts/.github/workflows/chaos-smoke.yml +0 -266
  23. package/skills/vds-skill/vds-scripts/.github/workflows/confluence-sync.yml +0 -44
  24. package/skills/vds-skill/vds-scripts/.github/workflows/docs-confluence-evidence.yml +0 -170
  25. package/skills/vds-skill/vds-scripts/.github/workflows/docs-quality.yml +0 -59
  26. package/skills/vds-skill/vds-scripts/.github/workflows/lint-and-test.yml +0 -90
  27. package/skills/vds-skill/vds-scripts/.github/workflows/scheduler-load-smoke.yml +0 -104
  28. package/skills/vds-skill/vds-scripts/.github/workflows/telegram-bridge-ci.yml +0 -131
  29. package/skills/vds-skill/vds-scripts/.graphifyignore +0 -29
  30. package/skills/vds-skill/vds-scripts/.importlinter +0 -86
  31. package/skills/vds-skill/vds-scripts/.mcp.json +0 -11
  32. package/skills/vds-skill/vds-scripts/.pre-commit-config.yaml +0 -62
  33. package/skills/vds-skill/vds-scripts/.ruffignore +0 -3
  34. package/skills/vds-skill/vds-scripts/.secrets.baseline +0 -133
  35. package/skills/vds-skill/vds-scripts/AGENTS.md +0 -250
  36. package/skills/vds-skill/vds-scripts/AGENTS.vi.md +0 -92
  37. package/skills/vds-skill/vds-scripts/ECOSYSTEM-CHANGELOG.md +0 -52
  38. package/skills/vds-skill/vds-scripts/ECOSYSTEM-DOCS.md +0 -602
  39. package/skills/vds-skill/vds-scripts/ECOSYSTEM_ALIGNMENT.md +0 -133
  40. package/skills/vds-skill/vds-scripts/Makefile +0 -119
  41. package/skills/vds-skill/vds-scripts/README.md +0 -103
  42. package/skills/vds-skill/vds-scripts/bitbucket_manifest_mapping.toml +0 -34
  43. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/ARCHITECTURE_ANALYSIS.md +0 -258
  44. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/BITBUCKET_API_PRACTICES.md +0 -393
  45. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/EVALUATION_REPORT.md +0 -61
  46. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/FEATURES.md +0 -908
  47. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/README.md +0 -817
  48. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/pyproject.toml +0 -49
  49. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/__init__.py +0 -50
  50. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py +0 -641
  51. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/cli.py +0 -2271
  52. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/client.py +0 -2693
  53. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/config.py +0 -186
  54. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/errors.py +0 -34
  55. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/factory.py +0 -185
  56. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/parsers.py +0 -113
  57. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/protocols.py +0 -244
  58. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/repo_ops.py +0 -325
  59. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/__init__.py +0 -8
  60. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/conftest.py +0 -65
  61. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_advanced_search.py +0 -155
  62. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_async_client.py +0 -505
  63. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_branch_permissions.py +0 -172
  64. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_cli.py +0 -113
  65. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_cli_archive.py +0 -122
  66. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_cli_clone.py +0 -131
  67. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client.py +0 -207
  68. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_archive.py +0 -73
  69. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_branch_conditions.py +0 -101
  70. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_code_advanced.py +0 -180
  71. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_code_file.py +0 -33
  72. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_deployment_environments.py +0 -193
  73. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_issues.py +0 -163
  74. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_pipelines_advanced.py +0 -171
  75. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_pr_blockers.py +0 -118
  76. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_repository_variables.py +0 -155
  77. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_code.py +0 -98
  78. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_code_advanced.py +0 -279
  79. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_code_insights.py +0 -334
  80. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_conditions.py +0 -149
  81. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_config.py +0 -297
  82. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_deployment_env.py +0 -352
  83. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_errors.py +0 -67
  84. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_factory.py +0 -352
  85. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_fork_operations.py +0 -203
  86. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_issue_cli.py +0 -262
  87. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_pipeline_advanced.py +0 -265
  88. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_pr_blocker.py +0 -206
  89. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_protocols.py +0 -336
  90. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_ops_archive.py +0 -169
  91. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_ops_clone.py +0 -115
  92. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_ops_parsing.py +0 -149
  93. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_settings.py +0 -336
  94. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_variables.py +0 -266
  95. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_webhooks.py +0 -188
  96. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_workspace.py +0 -234
  97. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/unit/__init__.py +0 -0
  98. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/unit/test_parsers.py +0 -254
  99. package/skills/vds-skill/vds-scripts/brd_orchestrator/README.md +0 -29
  100. package/skills/vds-skill/vds-scripts/brd_orchestrator/pyproject.toml +0 -63
  101. package/skills/vds-skill/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/__init__.py +0 -17
  102. package/skills/vds-skill/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/cli.py +0 -187
  103. package/skills/vds-skill/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/validator.py +0 -121
  104. package/skills/vds-skill/vds-scripts/brd_orchestrator/tests/__init__.py +0 -0
  105. package/skills/vds-skill/vds-scripts/brd_orchestrator/tests/test_cli.py +0 -62
  106. package/skills/vds-skill/vds-scripts/brd_orchestrator/tests/test_validator.py +0 -33
  107. package/skills/vds-skill/vds-scripts/code/code_evidence_pack.json +0 -435
  108. package/skills/vds-skill/vds-scripts/confluence_orchestrator/Dockerfile +0 -19
  109. package/skills/vds-skill/vds-scripts/confluence_orchestrator/README.md +0 -479
  110. package/skills/vds-skill/vds-scripts/confluence_orchestrator/SYNC_SCRIPTS.md +0 -127
  111. package/skills/vds-skill/vds-scripts/confluence_orchestrator/SYNC_STANDARDIZATION.md +0 -108
  112. package/skills/vds-skill/vds-scripts/confluence_orchestrator/pyproject.toml +0 -50
  113. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/__init__.py +0 -56
  114. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/async_client.py +0 -100
  115. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/cli.py +0 -3160
  116. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/config.py +0 -215
  117. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content.py +0 -368
  118. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content_v2.py +0 -144
  119. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/crawl_tree.py +0 -1833
  120. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/errors.py +0 -44
  121. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/eventing.py +0 -111
  122. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/http.py +0 -1850
  123. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/orchestration.py +0 -166
  124. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/protocols.py +0 -61
  125. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/reporting.py +0 -78
  126. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/tree.py +0 -122
  127. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/tree_copier.py +0 -431
  128. package/skills/vds-skill/vds-scripts/confluence_orchestrator/sync_pdfs_from_markdown.py +0 -203
  129. package/skills/vds-skill/vds-scripts/confluence_orchestrator/sync_pdfs_to_confluence.py +0 -299
  130. package/skills/vds-skill/vds-scripts/confluence_orchestrator/sync_png_attachments.py +0 -299
  131. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/conftest.py +0 -46
  132. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_advanced_content.py +0 -252
  133. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_advanced_search.py +0 -193
  134. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_async_client.py +0 -104
  135. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_cache_management.py +0 -246
  136. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_cli.py +0 -716
  137. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_config.py +0 -130
  138. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_content.py +0 -192
  139. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_content_flags.py +0 -27
  140. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_content_labels.py +0 -94
  141. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_crawl_tree.py +0 -2252
  142. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_degraded_write_safety.py +0 -176
  143. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_draft_management.py +0 -225
  144. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_errors.py +0 -75
  145. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing.py +0 -73
  146. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing_chaos.py +0 -37
  147. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing_rate_limit.py +0 -44
  148. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing_timeout.py +0 -49
  149. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_export.py +0 -231
  150. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_history.py +0 -217
  151. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_http.py +0 -375
  152. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_orchestration.py +0 -93
  153. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_reporting.py +0 -24
  154. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_search_cql.py +0 -36
  155. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_space_management.py +0 -236
  156. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_space_permissions.py +0 -384
  157. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_tree_copier.py +0 -644
  158. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_tree_copier_remap.py +0 -289
  159. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_user_group_management.py +0 -387
  160. package/skills/vds-skill/vds-scripts/diagram_generator/README.md +0 -663
  161. package/skills/vds-skill/vds-scripts/diagram_generator/ci_validate.sh +0 -16
  162. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.png +0 -0
  163. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.puml +0 -23
  164. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.png +0 -0
  165. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.puml +0 -21
  166. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.png +0 -0
  167. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.puml +0 -14
  168. package/skills/vds-skill/vds-scripts/diagram_generator/examples/github-actions-validate.yml +0 -39
  169. package/skills/vds-skill/vds-scripts/diagram_generator/generate_all_diagrams.py +0 -827
  170. package/skills/vds-skill/vds-scripts/diagram_generator/generate_insurance_c4_diagrams.py +0 -261
  171. package/skills/vds-skill/vds-scripts/diagram_generator/generate_insurance_c4_quick.py +0 -486
  172. package/skills/vds-skill/vds-scripts/diagram_generator/pyproject.toml +0 -28
  173. package/skills/vds-skill/vds-scripts/diagram_generator/render_png.py +0 -59
  174. package/skills/vds-skill/vds-scripts/diagram_generator/src/vds_diagram_generator/__init__.py +0 -3
  175. package/skills/vds-skill/vds-scripts/diagram_generator/src/vds_diagram_generator/cli.py +0 -50
  176. package/skills/vds-skill/vds-scripts/diagram_generator/test_c4_hierarchical.py +0 -142
  177. package/skills/vds-skill/vds-scripts/diagram_generator/test_c4_quick.py +0 -131
  178. package/skills/vds-skill/vds-scripts/diagram_generator/tests/__init__.py +0 -0
  179. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_analyzer_completeness.py +0 -260
  180. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_c4_syntax_correctness.py +0 -138
  181. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_component_coverage.py +0 -182
  182. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_mermaid_output.py +0 -80
  183. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_png_generation.py +0 -112
  184. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_scenario_templates.py +0 -15
  185. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_sequence_accuracy.py +0 -93
  186. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_structurizr_export.py +0 -177
  187. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_style_consistency.py +0 -174
  188. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_usecase_generator.py +0 -201
  189. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_usecase_integration.py +0 -124
  190. package/skills/vds-skill/vds-scripts/docker/.dockerignore +0 -38
  191. package/skills/vds-skill/vds-scripts/docker/ADR.md +0 -392
  192. package/skills/vds-skill/vds-scripts/docker/Dockerfile +0 -68
  193. package/skills/vds-skill/vds-scripts/docker/MIGRATION.md +0 -453
  194. package/skills/vds-skill/vds-scripts/docker/README.md +0 -347
  195. package/skills/vds-skill/vds-scripts/docker/ROLLBACK.md +0 -596
  196. package/skills/vds-skill/vds-scripts/docker/compose.phase2-verification.yml +0 -31
  197. package/skills/vds-skill/vds-scripts/docker/docker-compose.cli.yml +0 -206
  198. package/skills/vds-skill/vds-scripts/docker/docker-compose.infra.yml +0 -276
  199. package/skills/vds-skill/vds-scripts/docker/docker-compose.services.yml +0 -425
  200. package/skills/vds-skill/vds-scripts/docker/infrastructure/init-schemas.sql +0 -177
  201. package/skills/vds-skill/vds-scripts/docker/infrastructure/pgbouncer/pgbouncer.ini +0 -75
  202. package/skills/vds-skill/vds-scripts/docker/infrastructure/pgbouncer/userlist.txt +0 -50
  203. package/skills/vds-skill/vds-scripts/docker/infrastructure/pgbouncer/userlist.txt.template +0 -36
  204. package/skills/vds-skill/vds-scripts/docs/.confluence-evidence/.gitkeep +0 -0
  205. package/skills/vds-skill/vds-scripts/docs/.confluence-evidence/PREFLIGHT.md +0 -132
  206. package/skills/vds-skill/vds-scripts/docs/.confluence-evidence/README.md +0 -84
  207. package/skills/vds-skill/vds-scripts/docs/.confluence.yaml +0 -157
  208. package/skills/vds-skill/vds-scripts/docs/.freshness.yaml +0 -54
  209. package/skills/vds-skill/vds-scripts/docs/README.md +0 -235
  210. package/skills/vds-skill/vds-scripts/docs/agents/README.md +0 -33
  211. package/skills/vds-skill/vds-scripts/docs/agents/explanation/data-flow.md +0 -132
  212. package/skills/vds-skill/vds-scripts/docs/agents/explanation/development-roadmap.md +0 -49
  213. package/skills/vds-skill/vds-scripts/docs/agents/explanation/features-overview.md +0 -62
  214. package/skills/vds-skill/vds-scripts/docs/agents/explanation/index.md +0 -36
  215. package/skills/vds-skill/vds-scripts/docs/agents/explanation/runtime-verification-and-gap-reporting.md +0 -127
  216. package/skills/vds-skill/vds-scripts/docs/agents/explanation/system-architecture.md +0 -139
  217. package/skills/vds-skill/vds-scripts/docs/agents/explanation/whats-new.md +0 -75
  218. package/skills/vds-skill/vds-scripts/docs/agents/explanation/who-ecosystem-introduction.md +0 -65
  219. package/skills/vds-skill/vds-scripts/docs/agents/explanation/who-ecosystem-model.md +0 -41
  220. package/skills/vds-skill/vds-scripts/docs/agents/how-to/02-using-vds-ai-memory.md +0 -98
  221. package/skills/vds-skill/vds-scripts/docs/agents/how-to/03-memory-cross-agent.md +0 -241
  222. package/skills/vds-skill/vds-scripts/docs/agents/how-to/04-using-progress-reports.md +0 -240
  223. package/skills/vds-skill/vds-scripts/docs/agents/how-to/08-semantic-search.md +0 -46
  224. package/skills/vds-skill/vds-scripts/docs/agents/how-to/apply-phase3-migration.md +0 -148
  225. package/skills/vds-skill/vds-scripts/docs/agents/how-to/choose-the-right-command-or-skill.md +0 -34
  226. package/skills/vds-skill/vds-scripts/docs/agents/how-to/contribute-new-orchestrator.md +0 -149
  227. package/skills/vds-skill/vds-scripts/docs/agents/how-to/decision-tree.md +0 -63
  228. package/skills/vds-skill/vds-scripts/docs/agents/how-to/first-audit-run.md +0 -83
  229. package/skills/vds-skill/vds-scripts/docs/agents/how-to/index.md +0 -49
  230. package/skills/vds-skill/vds-scripts/docs/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +0 -314
  231. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +0 -165
  232. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +0 -138
  233. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +0 -130
  234. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +0 -142
  235. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +0 -140
  236. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +0 -135
  237. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase131-all-project-preparation.md +0 -211
  238. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase131-bounded-parallel-analysis.md +0 -123
  239. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase131-confluence-upload-recovery.md +0 -204
  240. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase132-department-preparation.md +0 -144
  241. package/skills/vds-skill/vds-scripts/docs/agents/how-to/run-ecosystem-daily-report.md +0 -213
  242. package/skills/vds-skill/vds-scripts/docs/agents/how-to/tips-and-tricks.md +0 -138
  243. package/skills/vds-skill/vds-scripts/docs/agents/how-to/troubleshooting-guide.md +0 -221
  244. package/skills/vds-skill/vds-scripts/docs/agents/reference/agent-operational-contract.md +0 -162
  245. package/skills/vds-skill/vds-scripts/docs/agents/reference/alignment-phase179-report.md +0 -144
  246. package/skills/vds-skill/vds-scripts/docs/agents/reference/audit-triage-playbook.md +0 -256
  247. package/skills/vds-skill/vds-scripts/docs/agents/reference/backup-restore.md +0 -132
  248. package/skills/vds-skill/vds-scripts/docs/agents/reference/bitbucket-orchestrator.md +0 -56
  249. package/skills/vds-skill/vds-scripts/docs/agents/reference/brd-orchestrator.md +0 -52
  250. package/skills/vds-skill/vds-scripts/docs/agents/reference/capability-coverage-review.md +0 -51
  251. package/skills/vds-skill/vds-scripts/docs/agents/reference/ci-workflows.md +0 -98
  252. package/skills/vds-skill/vds-scripts/docs/agents/reference/circular-dependency-orchestrator.md +0 -55
  253. package/skills/vds-skill/vds-scripts/docs/agents/reference/cli-commands.md +0 -583
  254. package/skills/vds-skill/vds-scripts/docs/agents/reference/cli-development-standards.md +0 -41
  255. package/skills/vds-skill/vds-scripts/docs/agents/reference/cli-help-matrix.md +0 -84
  256. package/skills/vds-skill/vds-scripts/docs/agents/reference/common-errors.md +0 -126
  257. package/skills/vds-skill/vds-scripts/docs/agents/reference/configuration-reference.md +0 -128
  258. package/skills/vds-skill/vds-scripts/docs/agents/reference/confluence-orchestrator.md +0 -56
  259. package/skills/vds-skill/vds-scripts/docs/agents/reference/confluence-sync-target.md +0 -111
  260. package/skills/vds-skill/vds-scripts/docs/agents/reference/confluence-sync.md +0 -46
  261. package/skills/vds-skill/vds-scripts/docs/agents/reference/db-query-orchestrator.md +0 -93
  262. package/skills/vds-skill/vds-scripts/docs/agents/reference/diagrams-orchestrator.md +0 -52
  263. package/skills/vds-skill/vds-scripts/docs/agents/reference/ecosystem-daily-report.md +0 -229
  264. package/skills/vds-skill/vds-scripts/docs/agents/reference/elastic-orchestrator.md +0 -57
  265. package/skills/vds-skill/vds-scripts/docs/agents/reference/env-git-helper.md +0 -216
  266. package/skills/vds-skill/vds-scripts/docs/agents/reference/evolution-orchestrator.md +0 -113
  267. package/skills/vds-skill/vds-scripts/docs/agents/reference/excel-orchestrator.md +0 -51
  268. package/skills/vds-skill/vds-scripts/docs/agents/reference/git-orchestrator.md +0 -62
  269. package/skills/vds-skill/vds-scripts/docs/agents/reference/google-sheets-orchestrator.md +0 -51
  270. package/skills/vds-skill/vds-scripts/docs/agents/reference/grafana-orchestrator.md +0 -52
  271. package/skills/vds-skill/vds-scripts/docs/agents/reference/hexagonal-orchestrator.md +0 -64
  272. package/skills/vds-skill/vds-scripts/docs/agents/reference/index.md +0 -36
  273. package/skills/vds-skill/vds-scripts/docs/agents/reference/infrastructure-v2.15.md +0 -67
  274. package/skills/vds-skill/vds-scripts/docs/agents/reference/intellij-orchestrator.md +0 -50
  275. package/skills/vds-skill/vds-scripts/docs/agents/reference/jira-orchestrator.md +0 -60
  276. package/skills/vds-skill/vds-scripts/docs/agents/reference/links-orchestrator.md +0 -57
  277. package/skills/vds-skill/vds-scripts/docs/agents/reference/lint-cli.md +0 -99
  278. package/skills/vds-skill/vds-scripts/docs/agents/reference/lsp-orchestrator.md +0 -51
  279. package/skills/vds-skill/vds-scripts/docs/agents/reference/markdown-orchestrator.md +0 -53
  280. package/skills/vds-skill/vds-scripts/docs/agents/reference/mcp-orchestrator.md +0 -88
  281. package/skills/vds-skill/vds-scripts/docs/agents/reference/memory-orchestrator.md +0 -53
  282. package/skills/vds-skill/vds-scripts/docs/agents/reference/metabase-orchestrator.md +0 -51
  283. package/skills/vds-skill/vds-scripts/docs/agents/reference/migration-playbook.md +0 -71
  284. package/skills/vds-skill/vds-scripts/docs/agents/reference/multi-agent-orchestrator.md +0 -52
  285. package/skills/vds-skill/vds-scripts/docs/agents/reference/openapi-orchestrator.md +0 -57
  286. package/skills/vds-skill/vds-scripts/docs/agents/reference/orchestrator-architecture.md +0 -194
  287. package/skills/vds-skill/vds-scripts/docs/agents/reference/orchestrator-comparison-matrix.md +0 -79
  288. package/skills/vds-skill/vds-scripts/docs/agents/reference/orchestrator-index.md +0 -73
  289. package/skills/vds-skill/vds-scripts/docs/agents/reference/pdf-orchestrator.md +0 -57
  290. package/skills/vds-skill/vds-scripts/docs/agents/reference/portable-paths-and-config.md +0 -0
  291. package/skills/vds-skill/vds-scripts/docs/agents/reference/portable-paths-validation-matrix.md +0 -129
  292. package/skills/vds-skill/vds-scripts/docs/agents/reference/progress-orchestrator.md +0 -51
  293. package/skills/vds-skill/vds-scripts/docs/agents/reference/progress-report-cli.md +0 -215
  294. package/skills/vds-skill/vds-scripts/docs/agents/reference/public-interface-orchestrator.md +0 -73
  295. package/skills/vds-skill/vds-scripts/docs/agents/reference/research-orchestrator.md +0 -53
  296. package/skills/vds-skill/vds-scripts/docs/agents/reference/schema-orchestrator.md +0 -57
  297. package/skills/vds-skill/vds-scripts/docs/agents/reference/search-tools.md +0 -34
  298. package/skills/vds-skill/vds-scripts/docs/agents/reference/skills-commands.md +0 -256
  299. package/skills/vds-skill/vds-scripts/docs/agents/reference/skills-reference.md +0 -32
  300. package/skills/vds-skill/vds-scripts/docs/agents/reference/sonarqube-orchestrator.md +0 -62
  301. package/skills/vds-skill/vds-scripts/docs/agents/reference/spec-orchestrator.md +0 -56
  302. package/skills/vds-skill/vds-scripts/docs/agents/reference/structure-orchestrator.md +0 -69
  303. package/skills/vds-skill/vds-scripts/docs/agents/reference/system-requirements.md +0 -76
  304. package/skills/vds-skill/vds-scripts/docs/agents/reference/tasks-orchestrator.md +0 -53
  305. package/skills/vds-skill/vds-scripts/docs/agents/reference/validation-and-sync-notes.md +0 -54
  306. package/skills/vds-skill/vds-scripts/docs/agents/reference/vds-ai-memory-api.md +0 -51
  307. package/skills/vds-skill/vds-scripts/docs/agents/reference/vds-cli-reference.md +0 -34
  308. package/skills/vds-skill/vds-scripts/docs/agents/reference/who-capability-inventory.md +0 -96
  309. package/skills/vds-skill/vds-scripts/docs/agents/reference/who-capability-routing-matrix.md +0 -14
  310. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/feature-progression-guide.md +0 -112
  311. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/index.md +0 -36
  312. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/quick-start.md +0 -50
  313. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/who-skills-and-scripts-onboarding.md +0 -47
  314. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/zero-to-productive-developer.md +0 -339
  315. package/skills/vds-skill/vds-scripts/docs/confluence/IMPLEMENTATION-SUMMARY.md +0 -78
  316. package/skills/vds-skill/vds-scripts/docs/confluence/SYNC-GUIDE.md +0 -47
  317. package/skills/vds-skill/vds-scripts/docs/deployment/offline-docker-image-load.md +0 -59
  318. package/skills/vds-skill/vds-scripts/docs/evolution-auto-run-rollout.md +0 -325
  319. package/skills/vds-skill/vds-scripts/docs/evolution-loop-deep-integration.md +0 -496
  320. package/skills/vds-skill/vds-scripts/docs/evolution-loop-integration-guide.md +0 -359
  321. package/skills/vds-skill/vds-scripts/docs/openspace-schema-snapshot.md +0 -73
  322. package/skills/vds-skill/vds-scripts/docs/operations/sla-mttr-policy.md +0 -44
  323. package/skills/vds-skill/vds-scripts/docs/p0-closure-evidence/SUMMARY.md +0 -58
  324. package/skills/vds-skill/vds-scripts/docs/p4-closure-evidence/.gitkeep +0 -0
  325. package/skills/vds-skill/vds-scripts/docs/p4-closure-evidence/smoke-20260427T024137Z-b95b586b.json +0 -15
  326. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/alembic-and-runtime-advisory-locks.md +0 -45
  327. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/dbos-listen-notify.md +0 -54
  328. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/pgbouncer-search-path-empirical.md +0 -110
  329. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/pgvector-set-local-audit.md +0 -51
  330. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/topology-decision-session-mode.md +0 -57
  331. package/skills/vds-skill/vds-scripts/docs/phases/CHANGELOG.md +0 -103
  332. package/skills/vds-skill/vds-scripts/docs/phases/PHASE_125_COMPLETION_AND_MERGE.md +0 -212
  333. package/skills/vds-skill/vds-scripts/docs/phases/phase125/IMPLEMENTATION_REPORT.md +0 -227
  334. package/skills/vds-skill/vds-scripts/docs/phases/phase125/TSK-125.10-11-implementation-summary.md +0 -196
  335. package/skills/vds-skill/vds-scripts/docs/phases/phase125/profile-patch-ollama-local-anthropic.md +0 -122
  336. package/skills/vds-skill/vds-scripts/docs/phases/phase125_completion_summary.md +0 -369
  337. package/skills/vds-skill/vds-scripts/docs/phases/phase125_llm_analysis_skill.md +0 -164
  338. package/skills/vds-skill/vds-scripts/docs/phases/phase125_merge_complete.md +0 -147
  339. package/skills/vds-skill/vds-scripts/docs/phases/phase125_skill_runtime_closure_20260321.md +0 -91
  340. package/skills/vds-skill/vds-scripts/docs/phases/phase2-portable-paths/closure-handoff-summary-2026-03-23.md +0 -290
  341. package/skills/vds-skill/vds-scripts/docs/phases/phase2-portable-paths/remaining-risk-register-2026-03-25.md +0 -143
  342. package/skills/vds-skill/vds-scripts/docs/phases/phase2-portable-paths/verification-evidence-2026-03-23.md +0 -135
  343. package/skills/vds-skill/vds-scripts/docs/v0-sunset-known-issues.md +0 -88
  344. package/skills/vds-skill/vds-scripts/docs/vi/TRANSLATION-BACKLOG.md +0 -72
  345. package/skills/vds-skill/vds-scripts/docs/vi/agents/README.md +0 -41
  346. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/features-overview.md +0 -29
  347. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/index.md +0 -14
  348. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/runtime-verification-and-gap-reporting.md +0 -129
  349. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/whats-new.md +0 -37
  350. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/who-ecosystem-introduction.md +0 -21
  351. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/who-ecosystem-model.md +0 -36
  352. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/02-using-vds-ai-memory.md +0 -100
  353. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/03-memory-cross-agent.md +0 -243
  354. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/04-using-progress-reports.md +0 -242
  355. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/08-semantic-search.md +0 -16
  356. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/choose-the-right-command-or-skill.md +0 -36
  357. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/decision-tree.md +0 -77
  358. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/first-audit-run.md +0 -85
  359. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/index.md +0 -21
  360. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +0 -156
  361. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +0 -174
  362. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +0 -147
  363. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +0 -139
  364. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +0 -151
  365. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +0 -149
  366. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +0 -144
  367. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase131-all-project-preparation.md +0 -213
  368. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase131-bounded-parallel-analysis.md +0 -125
  369. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase131-confluence-upload-recovery.md +0 -206
  370. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase132-department-preparation.md +0 -146
  371. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/tips-and-tricks.md +0 -34
  372. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/troubleshooting-guide.md +0 -36
  373. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/agent-operational-contract.md +0 -98
  374. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/audit-triage-playbook.md +0 -258
  375. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/bitbucket-orchestrator.md +0 -30
  376. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/brd-orchestrator.md +0 -29
  377. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/capability-coverage-review.md +0 -46
  378. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/circular-dependency-orchestrator.md +0 -29
  379. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/cli-commands.md +0 -409
  380. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/cli-development-standards.md +0 -19
  381. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/cli-help-matrix.md +0 -71
  382. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/common-errors.md +0 -133
  383. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/configuration-reference.md +0 -25
  384. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/confluence-orchestrator.md +0 -30
  385. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/db-query-orchestrator.md +0 -34
  386. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/diagrams-orchestrator.md +0 -31
  387. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/elastic-orchestrator.md +0 -30
  388. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/evolution-orchestrator.md +0 -31
  389. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/excel-orchestrator.md +0 -60
  390. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/git-orchestrator.md +0 -31
  391. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/google-sheets-orchestrator.md +0 -60
  392. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/grafana-orchestrator.md +0 -30
  393. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/hexagonal-orchestrator.md +0 -73
  394. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/index.md +0 -25
  395. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/intellij-orchestrator.md +0 -59
  396. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/jira-orchestrator.md +0 -32
  397. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/links-orchestrator.md +0 -66
  398. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/lsp-orchestrator.md +0 -60
  399. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/markdown-orchestrator.md +0 -62
  400. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/mcp-orchestrator.md +0 -34
  401. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/memory-orchestrator.md +0 -45
  402. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/metabase-orchestrator.md +0 -30
  403. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/multi-agent-orchestrator.md +0 -61
  404. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/openapi-orchestrator.md +0 -66
  405. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/orchestrator-architecture.md +0 -24
  406. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/orchestrator-index.md +0 -73
  407. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/pdf-orchestrator.md +0 -30
  408. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/portable-paths-and-config.md +0 -123
  409. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/portable-paths-validation-matrix.md +0 -131
  410. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/progress-orchestrator.md +0 -43
  411. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/progress-report-cli.md +0 -217
  412. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/public-interface-orchestrator.md +0 -82
  413. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/research-orchestrator.md +0 -45
  414. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/schema-orchestrator.md +0 -66
  415. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/search-tools.md +0 -19
  416. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/skills-reference.md +0 -27
  417. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/sonarqube-orchestrator.md +0 -71
  418. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/spec-orchestrator.md +0 -56
  419. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/structure-orchestrator.md +0 -78
  420. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/system-requirements.md +0 -30
  421. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/tasks-orchestrator.md +0 -45
  422. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/validation-and-sync-notes.md +0 -26
  423. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/vds-ai-memory-api.md +0 -53
  424. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/vds-cli-reference.md +0 -34
  425. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/who-capability-inventory.md +0 -98
  426. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/who-capability-routing-matrix.md +0 -16
  427. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/feature-progression-guide.md +0 -124
  428. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/index.md +0 -13
  429. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/quick-start.md +0 -30
  430. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/who-skills-and-scripts-onboarding.md +0 -42
  431. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/zero-to-productive-developer.md +0 -137
  432. package/skills/vds-skill/vds-scripts/elastic_orchestrator/README.md +0 -450
  433. package/skills/vds-skill/vds-scripts/elastic_orchestrator/pyproject.toml +0 -97
  434. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/__init__.py +0 -81
  435. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/cli.py +0 -652
  436. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/client.py +0 -743
  437. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/config.py +0 -208
  438. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/errors.py +0 -34
  439. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/py.typed +0 -0
  440. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/__init__.py +0 -0
  441. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/conftest.py +0 -227
  442. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_client.py +0 -990
  443. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_config.py +0 -268
  444. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_e2e_verification.py +0 -272
  445. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_errors.py +0 -78
  446. package/skills/vds-skill/vds-scripts/excel_orchestrator/README.md +0 -288
  447. package/skills/vds-skill/vds-scripts/excel_orchestrator/RESEARCH_BASED_UPDATES_REPORT.md +0 -261
  448. package/skills/vds-skill/vds-scripts/excel_orchestrator/add_essential_missing_effort.py +0 -255
  449. package/skills/vds-skill/vds-scripts/excel_orchestrator/adjust_effort_complexity.py +0 -184
  450. package/skills/vds-skill/vds-scripts/excel_orchestrator/brd_analysis_and_task_breakdown.py +0 -632
  451. package/skills/vds-skill/vds-scripts/excel_orchestrator/brd_analysis_comprehensive.py +0 -1029
  452. package/skills/vds-skill/vds-scripts/excel_orchestrator/check_overlaps_and_brd_coverage.py +0 -570
  453. package/skills/vds-skill/vds-scripts/excel_orchestrator/clean_remarks_column.py +0 -127
  454. package/skills/vds-skill/vds-scripts/excel_orchestrator/comprehensive_brd_check.py +0 -322
  455. package/skills/vds-skill/vds-scripts/excel_orchestrator/create_buffered_summary.py +0 -119
  456. package/skills/vds-skill/vds-scripts/excel_orchestrator/create_service_totals_sheet.py +0 -118
  457. package/skills/vds-skill/vds-scripts/excel_orchestrator/examples/basic_operations.py +0 -85
  458. package/skills/vds-skill/vds-scripts/excel_orchestrator/expand_all_tasks.py +0 -341
  459. package/skills/vds-skill/vds-scripts/excel_orchestrator/expand_tasks.py +0 -304
  460. package/skills/vds-skill/vds-scripts/excel_orchestrator/fill_brd_references.py +0 -347
  461. package/skills/vds-skill/vds-scripts/excel_orchestrator/fill_remarks_and_colors.py +0 -132
  462. package/skills/vds-skill/vds-scripts/excel_orchestrator/finalize_brd_and_cleanup.py +0 -295
  463. package/skills/vds-skill/vds-scripts/excel_orchestrator/finalize_brd_coverage.py +0 -327
  464. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_all_formulas.py +0 -99
  465. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_detail_presentation.py +0 -113
  466. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_presentation_and_effort.py +0 -116
  467. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_presentation_consistency.py +0 -231
  468. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_remarks_matching.py +0 -179
  469. package/skills/vds-skill/vds-scripts/excel_orchestrator/group_tasks_by_service_id.py +0 -210
  470. package/skills/vds-skill/vds-scripts/excel_orchestrator/increase_brd_coverage.py +0 -497
  471. package/skills/vds-skill/vds-scripts/excel_orchestrator/increase_effort_complexity.py +0 -155
  472. package/skills/vds-skill/vds-scripts/excel_orchestrator/organize_and_deduplicate.py +0 -273
  473. package/skills/vds-skill/vds-scripts/excel_orchestrator/pyproject.toml +0 -64
  474. package/skills/vds-skill/vds-scripts/excel_orchestrator/rebuild_all_formulas.py +0 -146
  475. package/skills/vds-skill/vds-scripts/excel_orchestrator/remove_base_multiplier_and_check_duplicates.py +0 -310
  476. package/skills/vds-skill/vds-scripts/excel_orchestrator/remove_duplicate_brd_tasks.py +0 -137
  477. package/skills/vds-skill/vds-scripts/excel_orchestrator/research_based_updates.py +0 -457
  478. package/skills/vds-skill/vds-scripts/excel_orchestrator/restore_e_values.py +0 -172
  479. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/__init__.py +0 -5
  480. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/cli.py +0 -746
  481. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/config.py +0 -74
  482. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/converters.py +0 -226
  483. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/errors.py +0 -88
  484. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/excel_client.py +0 -443
  485. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/formatters.py +0 -211
  486. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/logging.py +0 -57
  487. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/source_contract.py +0 -29
  488. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/target_state_status.py +0 -837
  489. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/ulnc_alignment.py +0 -1291
  490. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/validators.py +0 -164
  491. package/skills/vds-skill/vds-scripts/excel_orchestrator/sync_detail_and_total_sheets.py +0 -211
  492. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/__init__.py +0 -1
  493. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/conftest.py +0 -36
  494. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_cli.py +0 -383
  495. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_excel_client.py +0 -129
  496. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_ulnc_alignment.py +0 -373
  497. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_validators.py +0 -64
  498. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_api_database_effort.py +0 -261
  499. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_buffers_inline.py +0 -115
  500. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_complex_services_and_add_new.py +0 -336
  501. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_responsibility_and_fix_rows.py +0 -208
  502. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_task_breakdown_vietnamese.py +0 -309
  503. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_vietnamese_and_responsibility.py +0 -415
  504. package/skills/vds-skill/vds-scripts/excel_orchestrator/verify_brd_coverage_comprehensive.py +0 -401
  505. package/skills/vds-skill/vds-scripts/git_orchestrator/ENHANCEMENT_SUMMARY.md +0 -119
  506. package/skills/vds-skill/vds-scripts/git_orchestrator/README.md +0 -286
  507. package/skills/vds-skill/vds-scripts/git_orchestrator/VERIFICATION_REPORT.md +0 -152
  508. package/skills/vds-skill/vds-scripts/git_orchestrator/pyproject.toml +0 -37
  509. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__init__.py +0 -30
  510. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__main__.py +0 -4
  511. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/branch_probe.py +0 -271
  512. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/cli.py +0 -892
  513. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/logging_config.py +0 -63
  514. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/manifest.py +0 -249
  515. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/orchestrator.py +0 -1647
  516. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/protocols.py +0 -35
  517. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/reporting.py +0 -55
  518. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/__init__.py +0 -0
  519. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_cli_settings.py +0 -19
  520. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_integration.py +0 -79
  521. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_manifest.py +0 -79
  522. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_orchestrator.py +0 -207
  523. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_public_api.py +0 -235
  524. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_resilience.py +0 -343
  525. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/unit/__init__.py +0 -0
  526. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/unit/test_branch_probe.py +0 -327
  527. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/unit/test_protocols.py +0 -132
  528. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/README.md +0 -241
  529. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/pyproject.toml +0 -45
  530. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/__init__.py +0 -69
  531. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/cli.py +0 -568
  532. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/client.py +0 -186
  533. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/config.py +0 -46
  534. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/errors.py +0 -41
  535. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/__init__.py +0 -1
  536. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/conftest.py +0 -1
  537. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/__init__.py +0 -1
  538. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/test_cli.py +0 -212
  539. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/test_client.py +0 -24
  540. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/test_config.py +0 -16
  541. package/skills/vds-skill/vds-scripts/grafana_orchestrator/README.md +0 -572
  542. package/skills/vds-skill/vds-scripts/grafana_orchestrator/pyproject.toml +0 -102
  543. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/__init__.py +0 -78
  544. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/cli.py +0 -455
  545. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/client.py +0 -700
  546. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/config.py +0 -243
  547. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/errors.py +0 -34
  548. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/py.typed +0 -1
  549. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/__init__.py +0 -1
  550. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/conftest.py +0 -308
  551. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/test_client.py +0 -458
  552. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/test_config.py +0 -203
  553. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/test_errors.py +0 -78
  554. package/skills/vds-skill/vds-scripts/jira_orchestrator/README.md +0 -864
  555. package/skills/vds-skill/vds-scripts/jira_orchestrator/pyproject.toml +0 -43
  556. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/__init__.py +0 -65
  557. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/adapter.py +0 -1685
  558. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/cli.py +0 -2806
  559. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/config.py +0 -168
  560. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/errors.py +0 -34
  561. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/reporting.py +0 -66
  562. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/__init__.py +0 -1
  563. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/conftest.py +0 -86
  564. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_agile_list_payloads.py +0 -54
  565. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_bulk_operations.py +0 -91
  566. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_components.py +0 -56
  567. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_createmeta.py +0 -45
  568. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_dashboard.py +0 -119
  569. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_issue_properties.py +0 -53
  570. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_permissions_compat.py +0 -41
  571. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_reindex.py +0 -42
  572. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_remote_links.py +0 -75
  573. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_transitions.py +0 -90
  574. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_user_management.py +0 -116
  575. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_version_management.py +0 -181
  576. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_watchers.py +0 -43
  577. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_advanced_search.py +0 -179
  578. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_agile.py +0 -304
  579. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_application_properties.py +0 -243
  580. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_backlog.py +0 -91
  581. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_bulk_operations.py +0 -403
  582. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_cli.py +0 -108
  583. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_components.py +0 -119
  584. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_config.py +0 -166
  585. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_dashboard.py +0 -122
  586. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_discover_fields.py +0 -207
  587. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_errors.py +0 -72
  588. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_filter_management.py +0 -411
  589. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_issue_archiving.py +0 -179
  590. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_issue_links.py +0 -257
  591. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_issue_properties.py +0 -189
  592. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_link_types.py +0 -407
  593. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_parse_set.py +0 -37
  594. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_permissions.py +0 -343
  595. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_reindex.py +0 -81
  596. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_remote_links.py +0 -269
  597. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_security_schemes.py +0 -202
  598. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_transitions_changelog.py +0 -109
  599. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_user_management.py +0 -246
  600. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_version_management.py +0 -503
  601. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_watchers.py +0 -116
  602. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_worklog.py +0 -243
  603. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/README.md +0 -864
  604. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/pyproject.toml +0 -43
  605. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/__init__.py +0 -65
  606. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/adapter.py +0 -1689
  607. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/cli.py +0 -2799
  608. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/config.py +0 -137
  609. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/errors.py +0 -34
  610. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/reporting.py +0 -65
  611. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/__init__.py +0 -1
  612. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/conftest.py +0 -86
  613. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_agile_list_payloads.py +0 -54
  614. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_bulk_operations.py +0 -101
  615. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_components.py +0 -64
  616. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_createmeta.py +0 -45
  617. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_dashboard.py +0 -135
  618. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_issue_properties.py +0 -63
  619. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_permissions_compat.py +0 -42
  620. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_reindex.py +0 -42
  621. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_remote_links.py +0 -89
  622. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_transitions.py +0 -91
  623. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_user_management.py +0 -130
  624. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_version_management.py +0 -189
  625. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_watchers.py +0 -49
  626. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_advanced_search.py +0 -213
  627. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_agile.py +0 -334
  628. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_application_properties.py +0 -261
  629. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_backlog.py +0 -91
  630. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_bulk_operations.py +0 -443
  631. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_cli.py +0 -106
  632. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_components.py +0 -133
  633. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_config.py +0 -166
  634. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_dashboard.py +0 -130
  635. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_discover_fields.py +0 -207
  636. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_errors.py +0 -61
  637. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_filter_management.py +0 -478
  638. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_issue_archiving.py +0 -181
  639. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_issue_links.py +0 -257
  640. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_issue_properties.py +0 -203
  641. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_link_types.py +0 -426
  642. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_parse_set.py +0 -37
  643. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_permissions.py +0 -358
  644. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_reindex.py +0 -81
  645. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_remote_links.py +0 -292
  646. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_security_schemes.py +0 -218
  647. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_transitions_changelog.py +0 -121
  648. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_user_management.py +0 -283
  649. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_version_management.py +0 -561
  650. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_watchers.py +0 -128
  651. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_worklog.py +0 -265
  652. package/skills/vds-skill/vds-scripts/llms.txt +0 -159
  653. package/skills/vds-skill/vds-scripts/markdown_orchestrator/README.md +0 -72
  654. package/skills/vds-skill/vds-scripts/markdown_orchestrator/pyproject.toml +0 -39
  655. package/skills/vds-skill/vds-scripts/markdown_orchestrator/src/vds_markdown_orchestrator/__init__.py +0 -5
  656. package/skills/vds-skill/vds-scripts/markdown_orchestrator/src/vds_markdown_orchestrator/cli.py +0 -102
  657. package/skills/vds-skill/vds-scripts/mcp_server/Dockerfile +0 -63
  658. package/skills/vds-skill/vds-scripts/mcp_server/README.md +0 -140
  659. package/skills/vds-skill/vds-scripts/mcp_server/pyproject.toml +0 -41
  660. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/__init__.py +0 -3
  661. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/config.py +0 -36
  662. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/server.py +0 -111
  663. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/__init__.py +0 -15
  664. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/bitbucket_tools.py +0 -47
  665. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/confluence_tools.py +0 -53
  666. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/git_tools.py +0 -71
  667. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/jira_tools.py +0 -63
  668. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/vidp_tools.py +0 -64
  669. package/skills/vds-skill/vds-scripts/mcp_server/tests/__init__.py +0 -1
  670. package/skills/vds-skill/vds-scripts/mcp_server/tests/conftest.py +0 -31
  671. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/__init__.py +0 -1
  672. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_bitbucket_tools.py +0 -28
  673. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_confluence_tools.py +0 -28
  674. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_git_tools.py +0 -35
  675. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_jira_tools.py +0 -35
  676. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/__init__.py +0 -6
  677. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/conftest.py +0 -51
  678. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/test_mcp_confluence_tools.py +0 -40
  679. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/test_mcp_jira_tools.py +0 -39
  680. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/test_mcp_tool_registration.py +0 -50
  681. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.dockerignore +0 -93
  682. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.env.example +0 -40
  683. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.ruff_rules.py +0 -350
  684. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.yamllint.yml +0 -43
  685. package/skills/vds-skill/vds-scripts/pdf_orchestrator/DEVELOPMENT_PLAN.md +0 -80
  686. package/skills/vds-skill/vds-scripts/pdf_orchestrator/Dockerfile +0 -87
  687. package/skills/vds-skill/vds-scripts/pdf_orchestrator/README.md +0 -608
  688. package/skills/vds-skill/vds-scripts/pdf_orchestrator/cli_verification_test/test.md +0 -6
  689. package/skills/vds-skill/vds-scripts/pdf_orchestrator/cli_verification_test/test.pdf +0 -0
  690. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/alertmanager.yml +0 -83
  691. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/prometheus.prod.yml +0 -98
  692. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/prometheus.yml +0 -40
  693. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/redis.conf +0 -78
  694. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/COMPETITIVE_ANALYSIS_REPORT.md +0 -309
  695. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/FEATURES_GUIDE.md +0 -518
  696. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/MULTI_USER_DEPLOYMENT_GUIDE.md +0 -615
  697. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/USER_GUIDE.md +0 -829
  698. package/skills/vds-skill/vds-scripts/pdf_orchestrator/pyproject.toml +0 -87
  699. package/skills/vds-skill/vds-scripts/pdf_orchestrator/pytest.ini +0 -71
  700. package/skills/vds-skill/vds-scripts/pdf_orchestrator/ruff.toml +0 -6
  701. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/debug_security_report.py +0 -59
  702. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/demo_library_selector.py +0 -109
  703. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/generate_project_stats.py +0 -52
  704. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/generate_styled_pdf.py +0 -95
  705. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/migrate_render_pdfs.py +0 -285
  706. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/setup_team.bat +0 -283
  707. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/setup_team.sh +0 -324
  708. package/skills/vds-skill/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/__init__.py +0 -5
  709. package/skills/vds-skill/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/cli.py +0 -542
  710. package/skills/vds-skill/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/config.py +0 -33
  711. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/README.md +0 -650
  712. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/__init__.py +0 -0
  713. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/conftest.py +0 -520
  714. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/requirements.txt +0 -51
  715. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/run_tests.py +0 -659
  716. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/test_config.py +0 -36
  717. package/skills/vds-skill/vds-scripts/platform_core/pyproject.toml +0 -49
  718. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/__init__.py +0 -16
  719. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/alembic/__init__.py +0 -18
  720. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/alembic/runtime.py +0 -139
  721. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/config.py +0 -88
  722. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/credentials.py +0 -40
  723. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/env.py +0 -24
  724. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/errors.py +0 -127
  725. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/__init__.py +0 -18
  726. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/auth.py +0 -32
  727. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/errors.py +0 -47
  728. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/pagination.py +0 -65
  729. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/retry.py +0 -62
  730. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/stack.py +0 -61
  731. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/logging.py +0 -132
  732. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/protocols.py +0 -77
  733. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/serialization.py +0 -80
  734. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/severity.py +0 -175
  735. package/skills/vds-skill/vds-scripts/platform_core/tests/__init__.py +0 -0
  736. package/skills/vds-skill/vds-scripts/platform_core/tests/conftest.py +0 -1
  737. package/skills/vds-skill/vds-scripts/platform_core/tests/test_alembic_runtime.py +0 -300
  738. package/skills/vds-skill/vds-scripts/platform_core/tests/test_auth.py +0 -84
  739. package/skills/vds-skill/vds-scripts/platform_core/tests/test_config.py +0 -83
  740. package/skills/vds-skill/vds-scripts/platform_core/tests/test_credentials.py +0 -73
  741. package/skills/vds-skill/vds-scripts/platform_core/tests/test_env.py +0 -56
  742. package/skills/vds-skill/vds-scripts/platform_core/tests/test_errors.py +0 -201
  743. package/skills/vds-skill/vds-scripts/platform_core/tests/test_errors_http.py +0 -74
  744. package/skills/vds-skill/vds-scripts/platform_core/tests/test_http_settings.py +0 -116
  745. package/skills/vds-skill/vds-scripts/platform_core/tests/test_logging.py +0 -148
  746. package/skills/vds-skill/vds-scripts/platform_core/tests/test_pagination.py +0 -153
  747. package/skills/vds-skill/vds-scripts/platform_core/tests/test_protocols.py +0 -132
  748. package/skills/vds-skill/vds-scripts/platform_core/tests/test_retry.py +0 -151
  749. package/skills/vds-skill/vds-scripts/platform_core/tests/test_serialization.py +0 -92
  750. package/skills/vds-skill/vds-scripts/platform_core/tests/test_severity.py +0 -178
  751. package/skills/vds-skill/vds-scripts/platform_core/tests/test_stack.py +0 -130
  752. package/skills/vds-skill/vds-scripts/platform_core/uv.lock +0 -341
  753. package/skills/vds-skill/vds-scripts/pyproject.toml +0 -145
  754. package/skills/vds-skill/vds-scripts/pyrightconfig.json +0 -82
  755. package/skills/vds-skill/vds-scripts/repo-manifest.yaml +0 -380
  756. package/skills/vds-skill/vds-scripts/repo-manifest.yaml.example +0 -25
  757. package/skills/vds-skill/vds-scripts/ruff.toml +0 -100
  758. package/skills/vds-skill/vds-scripts/scripts/BRD-Validation-API.postman_collection.json +0 -706
  759. package/skills/vds-skill/vds-scripts/scripts/BRD-Validation-README.md +0 -308
  760. package/skills/vds-skill/vds-scripts/scripts/README.md +0 -271
  761. package/skills/vds-skill/vds-scripts/scripts/_validate_alias_phase2.py +0 -137
  762. package/skills/vds-skill/vds-scripts/scripts/audit-cli-patterns.sh +0 -135
  763. package/skills/vds-skill/vds-scripts/scripts/audit-dashboard.sh +0 -525
  764. package/skills/vds-skill/vds-scripts/scripts/backup.sh +0 -123
  765. package/skills/vds-skill/vds-scripts/scripts/bootstrap_uv.sh +0 -69
  766. package/skills/vds-skill/vds-scripts/scripts/brd-validation-environment.json +0 -51
  767. package/skills/vds-skill/vds-scripts/scripts/brd-validation-test-results.json +0 -13023
  768. package/skills/vds-skill/vds-scripts/scripts/brd_coverage_report.json +0 -276
  769. package/skills/vds-skill/vds-scripts/scripts/check-future-annotations.py +0 -22
  770. package/skills/vds-skill/vds-scripts/scripts/check-invalid-symlinks.py +0 -183
  771. package/skills/vds-skill/vds-scripts/scripts/check-no-debug-markers.py +0 -21
  772. package/skills/vds-skill/vds-scripts/scripts/check-no-unittest.py +0 -21
  773. package/skills/vds-skill/vds-scripts/scripts/ci/assert_no_openspace_commits.sh +0 -37
  774. package/skills/vds-skill/vds-scripts/scripts/ci/verify_branch_protection.sh +0 -64
  775. package/skills/vds-skill/vds-scripts/scripts/closure/phase1_check.sh +0 -483
  776. package/skills/vds-skill/vds-scripts/scripts/closure/phase2_check.sh +0 -500
  777. package/skills/vds-skill/vds-scripts/scripts/create_memory_session.py +0 -36
  778. package/skills/vds-skill/vds-scripts/scripts/deploy-bootstrap.sh +0 -201
  779. package/skills/vds-skill/vds-scripts/scripts/deployment/load_docker_images_offline.sh +0 -90
  780. package/skills/vds-skill/vds-scripts/scripts/dev/cli_smoke.sh +0 -259
  781. package/skills/vds-skill/vds-scripts/scripts/final_completion_report.md +0 -139
  782. package/skills/vds-skill/vds-scripts/scripts/folder_structure_report.json +0 -321
  783. package/skills/vds-skill/vds-scripts/scripts/generate_completion_report.py +0 -132
  784. package/skills/vds-skill/vds-scripts/scripts/generate_intellij_modules.py +0 -154
  785. package/skills/vds-skill/vds-scripts/scripts/init-pgbouncer-userlist.sh +0 -154
  786. package/skills/vds-skill/vds-scripts/scripts/link_integrity_report.json +0 -807
  787. package/skills/vds-skill/vds-scripts/scripts/move_audit_artifact_pages.py +0 -252
  788. package/skills/vds-skill/vds-scripts/scripts/move_audit_artifact_pages_rest.py +0 -165
  789. package/skills/vds-skill/vds-scripts/scripts/move_wrong_dept_pages.py +0 -235
  790. package/skills/vds-skill/vds-scripts/scripts/openspace_bootstrap.sh +0 -56
  791. package/skills/vds-skill/vds-scripts/scripts/openspace_common.sh +0 -75
  792. package/skills/vds-skill/vds-scripts/scripts/openspace_doctor.sh +0 -61
  793. package/skills/vds-skill/vds-scripts/scripts/openspace_sync_shadow.sh +0 -65
  794. package/skills/vds-skill/vds-scripts/scripts/phase7-baseline.sh +0 -77
  795. package/skills/vds-skill/vds-scripts/scripts/preflight/env_check.sh +0 -102
  796. package/skills/vds-skill/vds-scripts/scripts/repair_autopay_reports.sh +0 -173
  797. package/skills/vds-skill/vds-scripts/scripts/rollback_drill.sh +0 -659
  798. package/skills/vds-skill/vds-scripts/scripts/run-audit-in-tmux.sh +0 -286
  799. package/skills/vds-skill/vds-scripts/scripts/run-department-audit.sh +0 -495
  800. package/skills/vds-skill/vds-scripts/scripts/run-project-audit.sh +0 -267
  801. package/skills/vds-skill/vds-scripts/scripts/save_intellij_memories.py +0 -112
  802. package/skills/vds-skill/vds-scripts/scripts/save_memories_to_vds_ai.py +0 -81
  803. package/skills/vds-skill/vds-scripts/scripts/save_memories_vds_style.py +0 -133
  804. package/skills/vds-skill/vds-scripts/scripts/search_intellij_memories.py +0 -48
  805. package/skills/vds-skill/vds-scripts/scripts/setup_intellij_workspace.py +0 -71
  806. package/skills/vds-skill/vds-scripts/scripts/smoke-test-deploy.sh +0 -137
  807. package/skills/vds-skill/vds-scripts/scripts/smoke_deploy_lib.py +0 -205
  808. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/README.md +0 -89
  809. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/confluence_sync_coordinator.sh +0 -27
  810. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/coordination.sh +0 -114
  811. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/diagram_coordinator.sh +0 -25
  812. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/docs_root.sh +0 -22
  813. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/generate_diagrams.sh +0 -22
  814. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/markdown_coordinator.sh +0 -25
  815. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/progress_dashboard.sh +0 -17
  816. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/schema_coordinator.sh +0 -25
  817. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/sync_confluence.sh +0 -30
  818. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/update_dependencies.sh +0 -19
  819. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_links.sh +0 -86
  820. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_markdown.sh +0 -52
  821. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_schemas.sh +0 -26
  822. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_structure.sh +0 -98
  823. package/skills/vds-skill/vds-scripts/scripts/tests/__init__.py +0 -1
  824. package/skills/vds-skill/vds-scripts/scripts/tests/test_dockerfile_correctness.py +0 -815
  825. package/skills/vds-skill/vds-scripts/scripts/tests/test_makefile_loadouts.py +0 -560
  826. package/skills/vds-skill/vds-scripts/scripts/tests/test_smoke_deploy.py +0 -313
  827. package/skills/vds-skill/vds-scripts/scripts/tests/test_verify_alembic.py +0 -581
  828. package/skills/vds-skill/vds-scripts/scripts/tests/test_verify_infra_topology.py +0 -254
  829. package/skills/vds-skill/vds-scripts/scripts/update_modules_xml.py +0 -194
  830. package/skills/vds-skill/vds-scripts/scripts/uv-workspace-alignment-verification-2026-03-25.md +0 -128
  831. package/skills/vds-skill/vds-scripts/scripts/uv-workspace-alignment-verification-2026-04-18.md +0 -100
  832. package/skills/vds-skill/vds-scripts/scripts/validate-cli-standardization.sh +0 -188
  833. package/skills/vds-skill/vds-scripts/scripts/validate_brd_coverage.py +0 -197
  834. package/skills/vds-skill/vds-scripts/scripts/validate_folder_structure.py +0 -234
  835. package/skills/vds-skill/vds-scripts/scripts/validate_link_integrity.py +0 -274
  836. package/skills/vds-skill/vds-scripts/scripts/vami017-caller-compat-report.md +0 -62
  837. package/skills/vds-skill/vds-scripts/scripts/vami017-phase-b-scaffold-notes.md +0 -79
  838. package/skills/vds-skill/vds-scripts/scripts/vds_sh_helpers.sh +0 -180
  839. package/skills/vds-skill/vds-scripts/scripts/verification/phase2_portable_paths_ubuntu_docker.sh +0 -26
  840. package/skills/vds-skill/vds-scripts/scripts/verify-infra-topology.py +0 -868
  841. package/skills/vds-skill/vds-scripts/scripts/verify-memory-cli-e2e.sh +0 -598
  842. package/skills/vds-skill/vds-scripts/scripts/verify-worktree-features.sh +0 -306
  843. package/skills/vds-skill/vds-scripts/scripts/worktree-add.sh +0 -128
  844. package/skills/vds-skill/vds-scripts/scripts/worktree-remove.sh +0 -112
  845. package/skills/vds-skill/vds-scripts/scripts/worktree_compose.sh +0 -269
  846. package/skills/vds-skill/vds-scripts/scripts/worktree_uv.sh +0 -77
  847. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/IMPLEMENTATION_AUDIT.md +0 -376
  848. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/README.md +0 -507
  849. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/pyproject.toml +0 -106
  850. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/scripts/ensure_symlink.sh +0 -38
  851. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/__init__.py +0 -164
  852. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/batch.py +0 -212
  853. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/cli.py +0 -1407
  854. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/client.py +0 -608
  855. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/config.py +0 -260
  856. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/diff.py +0 -220
  857. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/errors.py +0 -34
  858. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/external_sca.py +0 -932
  859. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/portfolio.py +0 -225
  860. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/pr.py +0 -505
  861. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/reports.py +0 -342
  862. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/scanner.py +0 -351
  863. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/webhooks.py +0 -269
  864. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/__init__.py +0 -0
  865. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/conftest.py +0 -134
  866. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_batch.py +0 -419
  867. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_config.py +0 -145
  868. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_errors.py +0 -78
  869. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_external_sca.py +0 -466
  870. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_pr.py +0 -471
  871. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_reports.py +0 -511
  872. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_webhooks.py +0 -660
  873. package/skills/vds-skill/vds-scripts/uv.lock +0 -5046
  874. package/skills/vds-skill/vds-scripts/vds_agent_core/CHANGELOG.md +0 -36
  875. package/skills/vds-skill/vds-scripts/vds_agent_core/README.md +0 -453
  876. package/skills/vds-skill/vds-scripts/vds_agent_core/docs/PHASE9A_ASSESSMENT.md +0 -50
  877. package/skills/vds-skill/vds-scripts/vds_agent_core/docs/embedding.md +0 -468
  878. package/skills/vds-skill/vds-scripts/vds_agent_core/pyproject.toml +0 -51
  879. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/__init__.py +0 -29
  880. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/__init__.py +0 -26
  881. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/hooks.py +0 -119
  882. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/loop.py +0 -864
  883. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/tools.py +0 -41
  884. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/config.py +0 -252
  885. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/__init__.py +0 -55
  886. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/_cascade.py +0 -143
  887. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/budget.py +0 -353
  888. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/cache.py +0 -373
  889. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/embedding.py +0 -815
  890. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/provider.py +0 -173
  891. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/schemas.py +0 -45
  892. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/__init__.py +0 -77
  893. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/decorators.py +0 -258
  894. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/jsonl_exporter.py +0 -236
  895. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/tracer.py +0 -497
  896. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/profiles.py +0 -2015
  897. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/runtime/__init__.py +0 -0
  898. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/runtime/agent_id.py +0 -60
  899. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/security/__init__.py +0 -13
  900. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/security/credentials.py +0 -106
  901. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/__init__.py +0 -1
  902. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/executor.py +0 -238
  903. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/manager.py +0 -381
  904. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/policy.py +0 -568
  905. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/workflows/__init__.py +0 -19
  906. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/workflows/langgraph_runner.py +0 -102
  907. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/workflows/protocols.py +0 -81
  908. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/__init__.py +0 -0
  909. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/conftest.py +0 -62
  910. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/__init__.py +0 -0
  911. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/test_audit_loop_hooks_integration.py +0 -135
  912. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/test_audit_observability_integration.py +0 -246
  913. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/test_public_api_stability.py +0 -91
  914. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/__init__.py +0 -0
  915. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/__init__.py +0 -0
  916. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_call_site_parallelism.py +0 -30
  917. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_dimension_guardrail.py +0 -25
  918. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_drop_in_provider_extensibility.py +0 -76
  919. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding.py +0 -393
  920. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding_cache.py +0 -302
  921. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding_extra.py +0 -696
  922. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding_subclass.py +0 -49
  923. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_no_provider_leakage_in_env.py +0 -34
  924. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_provider_auto_route.py +0 -48
  925. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_runtime_log_clean.py +0 -111
  926. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_w7_logic_fixes.py +0 -219
  927. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/__init__.py +0 -0
  928. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_embedding_block_parser.py +0 -194
  929. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_env_resolver_allowlist.py +0 -141
  930. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_profile_authorization.py +0 -158
  931. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_profiles_w3_extra.py +0 -547
  932. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_real_audit_profile_compat.py +0 -129
  933. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/runtime/__init__.py +0 -0
  934. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/runtime/test_for_agent.py +0 -322
  935. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/runtime/test_w9_cascade_edges.py +0 -369
  936. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/security/__init__.py +0 -0
  937. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/security/test_credentials.py +0 -132
  938. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_agent_loop.py +0 -663
  939. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_agent_loop_coverage.py +0 -429
  940. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_agents_hooks_defaults.py +0 -22
  941. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_budget.py +0 -155
  942. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_budget_coverage.py +0 -264
  943. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_budget_tracking_only.py +0 -71
  944. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_cache.py +0 -251
  945. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_cache_context.py +0 -62
  946. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_config.py +0 -155
  947. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_langgraph_runner.py +0 -45
  948. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_langgraph_runner_coverage.py +0 -98
  949. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_llm_cache_deep.py +0 -113
  950. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_decorators.py +0 -697
  951. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_hooks.py +0 -217
  952. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_jsonl_exporter.py +0 -542
  953. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_jsonl_wiring.py +0 -313
  954. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_tracer.py +0 -896
  955. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_profiles.py +0 -1571
  956. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_profiles_coverage.py +0 -444
  957. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_provider.py +0 -316
  958. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_schemas.py +0 -63
  959. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_executor.py +0 -297
  960. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_manager.py +0 -370
  961. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_manager_coverage.py +0 -364
  962. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_policy.py +0 -402
  963. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_rubric.py +0 -47
  964. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_tools.py +0 -51
  965. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_workflow_protocols.py +0 -136
  966. package/skills/vds-skill/vds-scripts/vds_cli/README.md +0 -201
  967. package/skills/vds-skill/vds-scripts/vds_cli/VERIFICATION_REPORT.md +0 -41
  968. package/skills/vds-skill/vds-scripts/vds_cli/pyproject.toml +0 -50
  969. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/__init__.py +0 -3
  970. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/assets/git-credential-helper.py +0 -235
  971. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/cli.py +0 -1158
  972. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/commands/__init__.py +0 -1
  973. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/commands/lint_cli.py +0 -389
  974. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/confluence_sync.py +0 -846
  975. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/consumption/__init__.py +0 -7
  976. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/consumption/funnel.py +0 -105
  977. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/consumption/scanner.py +0 -211
  978. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/freshness/report.py +0 -90
  979. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/types.py +0 -27
  980. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs_cmd.py +0 -672
  981. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs_metrics.py +0 -75
  982. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs_sync.py +0 -1171
  983. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/ecosystem/__init__.py +0 -39
  984. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/ecosystem/report.py +0 -439
  985. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/ecosystem_docs.py +0 -164
  986. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/env.py +0 -111
  987. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/env_git_helper.py +0 -281
  988. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/__init__.py +0 -3
  989. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/google_sheets_orchestrator.py +0 -173
  990. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/router.py +0 -232
  991. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/skills_cmd.py +0 -274
  992. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/sync_api.py +0 -613
  993. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/sync_service.py +0 -283
  994. package/skills/vds-skill/vds-scripts/vds_cli/tests/conftest.py +0 -62
  995. package/skills/vds-skill/vds-scripts/vds_cli/tests/test_env_git_helper_lifecycle.py +0 -261
  996. package/skills/vds-skill/vds-scripts/vds_cli/tests/test_git_credential_helper.py +0 -240
  997. package/skills/vds-skill/vds-scripts/vds_cli/tests/test_router_help_proxy.py +0 -43
  998. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_cli.py +0 -264
  999. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_cli_DOC004.py +0 -110
  1000. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_confluence_sync.py +0 -315
  1001. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_confluence_sync_wave7.py +0 -375
  1002. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_consumption_funnel.py +0 -106
  1003. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_consumption_scanner.py +0 -144
  1004. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_cmd.py +0 -89
  1005. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_cmd_wave8.py +0 -161
  1006. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_metrics.py +0 -16
  1007. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_quality_score.py +0 -61
  1008. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_sync.py +0 -417
  1009. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_ecosystem_cli_dashboard.py +0 -667
  1010. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_ecosystem_cli_dashboard_rendering.py +0 -143
  1011. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_ecosystem_docs.py +0 -63
  1012. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_env.py +0 -85
  1013. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_freshness_report.py +0 -125
  1014. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_lint_cli.py +0 -224
  1015. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_router.py +0 -101
  1016. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_skills_cmd.py +0 -419
  1017. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_sync_api.py +0 -357
  1018. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_sync_service.py +0 -170
  1019. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/conftest.py +0 -51
  1020. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/test_bitbucket_real.py +0 -32
  1021. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/test_confluence_real.py +0 -32
  1022. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/test_jira_real.py +0 -40
  1023. package/skills/vds-skill/vds-scripts/vds_cli_common/README.md +0 -190
  1024. package/skills/vds-skill/vds-scripts/vds_cli_common/pyproject.toml +0 -96
  1025. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/__init__.py +0 -36
  1026. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/app.py +0 -55
  1027. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/completers.py +0 -139
  1028. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/context.py +0 -201
  1029. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/env.py +0 -163
  1030. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/errors.py +0 -440
  1031. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/migrate_sdlc_config.py +0 -210
  1032. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/output.py +0 -284
  1033. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/paths.py +0 -78
  1034. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/testing.py +0 -211
  1035. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/version.py +0 -85
  1036. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/__init__.py +0 -0
  1037. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_app.py +0 -126
  1038. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_completers.py +0 -148
  1039. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_context.py +0 -192
  1040. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_env.py +0 -235
  1041. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_errors.py +0 -275
  1042. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_migrate_sdlc_config.py +0 -257
  1043. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_output.py +0 -229
  1044. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_paths.py +0 -61
  1045. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_testing.py +0 -138
  1046. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_version.py +0 -64
  1047. package/skills/vds-skill/vds-scripts/vidp_orchestrator/README.md +0 -31
  1048. package/skills/vds-skill/vds-scripts/vidp_orchestrator/pyproject.toml +0 -50
  1049. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/__init__.py +0 -26
  1050. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/cli.py +0 -246
  1051. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/client.py +0 -104
  1052. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/config.py +0 -82
  1053. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.json +0 -3
  1054. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.py +0 -130
  1055. package/skills/vds-skill/vds-scripts-skill/.openskills.json +0 -6
  1056. package/skills/vds-skill/vds-scripts-skill/QUALITY.md +0 -44
  1057. package/skills/vds-skill/vds-scripts-skill/SKILL.md +0 -132
  1058. package/skills/vds-skill/vds-scripts-skill/references/audit-commands.md +0 -171
  1059. package/skills/vds-skill/vds-scripts-skill/references/capability-index.md +0 -34
  1060. package/skills/vds-skill/vds-scripts-skill/references/development-commands.md +0 -12
  1061. package/skills/vds-skill/vds-scripts-skill/references/google-sheets.md +0 -71
  1062. package/skills/vds-skill/vds-scripts-skill/references/integration-commands.md +0 -17
  1063. package/skills/vds-skill/vds-scripts-skill/references/platform-bootstrap.md +0 -31
  1064. package/skills/vds-skill/vds-scripts-skill/references/specialist-routing.md +0 -14
  1065. package/skills/vds-skill/vds-scripts-skill/references/validation-commands.md +0 -15
@@ -1,2799 +0,0 @@
1
- """Typer CLI for Jira using the SDK-only adapter."""
2
-
3
- from __future__ import annotations
4
-
5
- import json
6
- import logging
7
- import re
8
- import sys
9
- from collections.abc import Sequence
10
- from datetime import UTC, datetime
11
- from pathlib import Path
12
- from typing import Any
13
-
14
- import structlog
15
- import typer
16
- from vds_platform_core.logging import configure_structlog
17
-
18
- from .adapter import JiraAdapter
19
- from .config import JiraViettelMoneySettings, SettingsError, load_settings
20
- from .errors import VDSClientError, AuthError
21
- from .reporting import RunSummary, write_reports
22
-
23
- app = typer.Typer(add_completion=False, help="Jira operations orchestrator (SDK-only)")
24
- logger = logging.getLogger("jira_cli")
25
-
26
- APP_NAME = "vds-jira-orchestrator"
27
- APP_VERSION = "2025.11.0"
28
-
29
- _REPORT_DIR = (Path(__file__).resolve().parents[3] / "reports" / "jira_runs").resolve()
30
-
31
-
32
- def _emit_json(payload: Any) -> None:
33
- text = json.dumps(payload, indent=2, sort_keys=True)
34
- if sys.stdout.isatty():
35
- typer.echo(text)
36
- else:
37
- sys.stdout.write(text + "\n")
38
-
39
-
40
- def _parse_set(items: Sequence[str], *, allow_scalar_json: bool = False) -> dict[str, Any]:
41
- out: dict[str, Any] = {}
42
- for raw in items:
43
- if "=" not in raw:
44
- raise typer.BadParameter(f"Invalid --set item '{raw}', expected key=value")
45
- k, v = raw.split("=", 1)
46
- k = k.strip()
47
- v = v.strip()
48
- if not k:
49
- raise typer.BadParameter(f"Invalid key in --set '{raw}'")
50
-
51
- # Try parsing value as JSON for complex field structures (e.g., customfields)
52
- try:
53
- val = json.loads(v)
54
- if isinstance(val, (dict, list)) or allow_scalar_json:
55
- out[k] = val
56
- else:
57
- out[k] = v
58
- except json.JSONDecodeError:
59
- # Fallback to string if not valid JSON
60
- out[k] = v
61
-
62
- return out
63
-
64
-
65
- # ---------------------------------------------------------------------------
66
- # Field metadata helpers
67
- # ---------------------------------------------------------------------------
68
-
69
-
70
- def _normalize_allowed_values(field_info: dict[str, Any]) -> list[dict[str, str]]:
71
- allowed_values: list[dict[str, str]] = []
72
- for raw in field_info.get("allowedValues", []) or []:
73
- if not isinstance(raw, dict):
74
- continue
75
- value = raw.get("value") or raw.get("name") or raw.get("displayName")
76
- if value is None:
77
- continue
78
- allowed_values.append({"id": str(raw.get("id") or ""), "value": str(value)})
79
- return allowed_values
80
-
81
-
82
- def _merge_allowed_values_from_editmeta(raw_fields: dict[str, Any], editmeta_fields: dict[str, Any]) -> None:
83
- for field_id, field_info in raw_fields.items():
84
- if not isinstance(field_info, dict):
85
- continue
86
- if field_info.get("allowedValues"):
87
- continue
88
- edit_info = editmeta_fields.get(field_id)
89
- if not isinstance(edit_info, dict):
90
- continue
91
- if not edit_info.get("allowedValues"):
92
- continue
93
- merged = dict(field_info)
94
- merged["allowedValues"] = edit_info["allowedValues"]
95
- raw_fields[field_id] = merged
96
-
97
-
98
- def _build_field_data(field_id: str, field_info: dict[str, Any]) -> dict[str, Any]:
99
- field_name = str(field_info.get("name") or "")
100
- field_data = {
101
- "id": field_id,
102
- "name": field_name,
103
- "type": field_info.get("schema", {}).get("type", "unknown"),
104
- "required": bool(field_info.get("required", False)),
105
- "is_custom": field_id.startswith("customfield_"),
106
- }
107
- allowed_values = _normalize_allowed_values(field_info)
108
- if allowed_values:
109
- field_data["allowedValues"] = allowed_values
110
- return field_data
111
-
112
-
113
- def _field_matches_filter(field_id: str, field_name: str, field_filter: str) -> bool:
114
- token = field_filter.strip().lower()
115
- if not token:
116
- return True
117
- return token in field_name.lower() or token in field_id.lower()
118
-
119
-
120
- def _collect_fields(
121
- raw_fields: dict[str, Any],
122
- *,
123
- field_filter: str | None,
124
- include_system: bool,
125
- ) -> list[dict[str, Any]]:
126
- fields: list[dict[str, Any]] = []
127
- for field_id, field_info in raw_fields.items():
128
- field_name = str(field_info.get("name") or "")
129
- if field_filter and not _field_matches_filter(field_id, field_name, field_filter):
130
- continue
131
- is_custom = field_id.startswith("customfield_")
132
- if not include_system and not is_custom:
133
- continue
134
- fields.append(_build_field_data(field_id, field_info))
135
- return fields
136
-
137
-
138
- def _extract_createmeta_fields(meta: dict[str, Any], project: str, issuetype: str) -> dict[str, Any]:
139
- found_project = None
140
- for p in meta.get("projects", []) or []:
141
- project_key = str(p.get("key", ""))
142
- project_id = str(p.get("id", ""))
143
- if project_key.lower() == project.lower() or project_id == project:
144
- found_project = p
145
- break
146
- if not found_project:
147
- raise typer.BadParameter(f"Project '{project}' not found in metadata response")
148
-
149
- found_issuetype = None
150
- for it in found_project.get("issuetypes", []) or []:
151
- it_name = str(it.get("name", ""))
152
- it_id = str(it.get("id", ""))
153
- if it_name.lower() == issuetype.lower() or it_id == issuetype:
154
- found_issuetype = it
155
- break
156
- if not found_issuetype:
157
- available_types = [it.get("name") for it in found_project.get("issuetypes", [])]
158
- raise typer.BadParameter(
159
- f"Issue type '{issuetype}' not found in project '{project}'. Available types: {available_types}"
160
- )
161
-
162
- return found_issuetype.get("fields", {})
163
-
164
-
165
- def _extract_required_field_ref(message: str) -> str | None:
166
- match = re.search(r"(?:Field ['\"])?(.+?)(?:['\"])? is required", message, re.IGNORECASE)
167
- if not match:
168
- return None
169
- return match.group(1).strip()
170
-
171
-
172
- def _extract_error_field_refs(message: str) -> list[str]:
173
- refs: set[str] = set()
174
- required_ref = _extract_required_field_ref(message)
175
- if required_ref:
176
- refs.add(required_ref)
177
-
178
- for ref in re.findall(r"customfield_\d+", message, re.IGNORECASE):
179
- refs.add(ref)
180
-
181
- errors_match = re.search(r"errors\s*[:=]\s*{([^}]+)}", message, re.IGNORECASE)
182
- if errors_match:
183
- for key in re.findall(r"[\"']([A-Za-z][A-Za-z0-9_]+)[\"']\s*:", errors_match.group(1)):
184
- if key not in {"errorMessages", "errors"}:
185
- refs.add(key)
186
-
187
- return [ref for ref in sorted(refs) if ref]
188
-
189
-
190
- def _match_fields_by_refs(fields: list[dict[str, Any]], refs: Sequence[str]) -> list[dict[str, Any]]:
191
- matched: list[dict[str, Any]] = []
192
- seen: set[str] = set()
193
- for ref in refs:
194
- token = ref.strip().lower()
195
- if not token:
196
- continue
197
- for field in fields:
198
- field_id = str(field.get("id") or "")
199
- field_name = str(field.get("name") or "")
200
- if token in field_id.lower() or token in field_name.lower():
201
- if field_id and field_id in seen:
202
- continue
203
- matched.append(field)
204
- if field_id:
205
- seen.add(field_id)
206
- return matched
207
-
208
-
209
- def _format_allowed_values(allowed_values: list[dict[str, str]], limit: int = 20) -> str:
210
- if not allowed_values:
211
- return ""
212
- parts: list[str] = []
213
- for item in allowed_values[:limit]:
214
- value = item.get("value") or ""
215
- ident = item.get("id") or ""
216
- if ident:
217
- parts.append(f"{value} (id: {ident})")
218
- else:
219
- parts.append(value)
220
- if len(allowed_values) > limit:
221
- parts.append(f"... (+{len(allowed_values) - limit} more)")
222
- return ", ".join([p for p in parts if p])
223
-
224
-
225
- # ---------------------------------------------------------------------------
226
- # Remote link helpers
227
- # ---------------------------------------------------------------------------
228
-
229
-
230
- def _build_remote_link_payload(
231
- *,
232
- url: str | None,
233
- title: str | None,
234
- summary: str | None,
235
- relationship: str | None,
236
- global_id: str | None,
237
- application_type: str | None,
238
- application_name: str | None,
239
- icon_url: str | None,
240
- icon_title: str | None,
241
- data_file: Path | None,
242
- ) -> dict[str, Any]:
243
- if data_file:
244
- if not data_file.exists():
245
- raise typer.BadParameter(f"Data file not found: {data_file}")
246
- try:
247
- with data_file.open() as f:
248
- parsed = json.load(f)
249
- except json.JSONDecodeError as exc:
250
- raise typer.BadParameter(f"Invalid JSON in {data_file}: {exc}") from exc
251
- if not isinstance(parsed, dict):
252
- raise typer.BadParameter("Remote link data file must contain a JSON object")
253
- return parsed
254
-
255
- if not url:
256
- raise typer.BadParameter("--url required when --data-file is not provided")
257
-
258
- payload: dict[str, Any] = {"object": {"url": url}}
259
-
260
- if title:
261
- payload["object"]["title"] = title
262
- if summary:
263
- payload["object"]["summary"] = summary
264
- if icon_url:
265
- icon: dict[str, Any] = {"url16x16": icon_url}
266
- if icon_title:
267
- icon["title"] = icon_title
268
- payload["object"]["icon"] = icon
269
- if relationship:
270
- payload["relationship"] = relationship
271
- if global_id:
272
- payload["globalId"] = global_id
273
- if application_type or application_name:
274
- if not (application_type and application_name):
275
- raise typer.BadParameter("--application-type and --application-name must be provided together")
276
- payload["application"] = {"type": application_type, "name": application_name}
277
-
278
- return payload
279
-
280
-
281
- # Global state for report directory and markdown flag
282
- _report_dir_global: Path = _REPORT_DIR
283
- _markdown_global: bool = True
284
- _reports_global: bool = True
285
-
286
-
287
- @app.callback(invoke_without_command=True)
288
- def main(
289
- report_dir: Path | None = typer.Option(None, help=f"Directory for run reports (default: {_REPORT_DIR})"),
290
- markdown: bool = typer.Option(True, help="Emit Markdown summaries alongside JSON reports"),
291
- reports: bool = typer.Option(True, "--reports/--no-reports", help="Persist run reports to disk"),
292
- json_only: bool = typer.Option(
293
- False,
294
- "--json-only",
295
- help="Emit JSON to stdout only (disables reports and markdown)",
296
- ),
297
- structured_logs: bool = typer.Option(
298
- False, "--structured-logs/--no-structured-logs", help="Emit structured JSON logs to stderr"
299
- ),
300
- version: bool = typer.Option(
301
- False,
302
- "--version",
303
- help="Show vds-jira-orchestrator version and exit",
304
- is_eager=True,
305
- ),
306
- ) -> None:
307
- if version:
308
- typer.echo(f"{APP_NAME} {APP_VERSION}")
309
- raise typer.Exit() from None
310
- global _report_dir_global, _markdown_global, _reports_global # noqa: PLW0603
311
- if json_only:
312
- markdown = False
313
- reports = False
314
- _report_dir_global = report_dir.resolve() if report_dir else _REPORT_DIR
315
- _markdown_global = markdown
316
- _reports_global = reports
317
- if structured_logs or json_only:
318
- configure_structlog(json_logs=structured_logs, quiet=json_only and not structured_logs, cache_logger=structured_logs)
319
- if structured_logs:
320
- global logger # noqa: PLW0603
321
- logger = structlog.get_logger("jira_cli") # type: ignore[assignment]
322
-
323
-
324
- def _record_summary(
325
- *, command: str, args: list[str], exit_code: int, started_at: datetime, finished_at: datetime
326
- ) -> None:
327
- global _report_dir_global, _markdown_global # noqa: PLW0603
328
- summary = RunSummary(
329
- command=command,
330
- args=args,
331
- exit_code=exit_code,
332
- duration_ms=int((finished_at - started_at).total_seconds() * 1000),
333
- started_at=started_at,
334
- finished_at=finished_at,
335
- )
336
- if _reports_global:
337
- write_reports(summary, base_dir=_report_dir_global, include_markdown=_markdown_global)
338
-
339
-
340
- @app.command("projects")
341
- def cmd_projects(
342
- search: str | None = typer.Option(
343
- None,
344
- "--search",
345
- "-s",
346
- help="Case-insensitive substring filter on project name or key",
347
- ),
348
- limit: int | None = typer.Option(
349
- None,
350
- "--limit",
351
- "-l",
352
- help="Maximum number of projects to return (applied after filtering)",
353
- ),
354
- ) -> None:
355
- started_at = datetime.now(UTC)
356
- code = 0
357
- args_summary = []
358
- if search:
359
- args_summary.append(f"search={search}")
360
- if limit is not None:
361
- args_summary.append(f"limit={limit}")
362
- try:
363
- s = load_settings(strict=True)
364
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
365
- payload = adapter.list_projects()
366
-
367
- if search:
368
- needle = search.lower()
369
- payload = [p for p in payload if needle in p.get("name", "").lower() or needle in p.get("key", "").lower()]
370
- if limit is not None:
371
- payload = payload[:limit]
372
-
373
- _emit_json({"count": len(payload), "projects": payload})
374
- except (AuthError, VDSClientError, SettingsError) as exc:
375
- code = 1
376
- logger.error("projects_failed %s", exc)
377
- typer.echo(f"Error: {exc}", err=True)
378
- finally:
379
- finished_at = datetime.now(UTC)
380
- _record_summary(
381
- command="projects",
382
- args=args_summary,
383
- exit_code=code,
384
- started_at=started_at,
385
- finished_at=finished_at,
386
- )
387
- if code != 0:
388
- raise typer.Exit(code=code) from None
389
-
390
-
391
- @app.command("component")
392
- def cmd_component(
393
- action: str = typer.Argument(..., help="Action: list, get, create, update, delete"),
394
- project_key: str | None = typer.Option(None, "--project-key", "-P", help="Project key (for list)"),
395
- component_id: str | None = typer.Option(None, "--component-id", "-c", help="Component ID (for get/update/delete)"),
396
- name: str | None = typer.Option(None, "--name", help="Component name (for create/update)"),
397
- description: str | None = typer.Option(None, "--description", help="Component description"),
398
- lead_account_id: str | None = typer.Option(None, "--lead-account-id", help="Account ID of component lead"),
399
- assignee_type: str | None = typer.Option(
400
- None, "--assignee-type", help="Assignee type (e.g., PROJECT_LEAD, COMPONENT_LEAD)"
401
- ),
402
- is_assignee_type_valid: bool | None = typer.Option(
403
- None, "--assignee-valid/--no-assignee-valid", help="Assignee validity flag"
404
- ),
405
- data_file: Path | None = typer.Option(None, "--data-file", help="JSON file for component payload"),
406
- yes: bool = typer.Option(False, "--yes", help="Confirm write operations (create/update/delete)"),
407
- ) -> None:
408
- """Manage project components."""
409
- started_at = datetime.now(UTC)
410
- code = 0
411
- summary_args = [
412
- action,
413
- f"project_key={project_key}",
414
- f"component_id={component_id}",
415
- f"data_file={data_file}",
416
- ]
417
-
418
- def _build_payload() -> dict[str, Any]:
419
- if data_file:
420
- if not data_file.exists():
421
- raise typer.BadParameter(f"Data file not found: {data_file}")
422
- try:
423
- parsed = json.loads(data_file.read_text())
424
- except json.JSONDecodeError as exc:
425
- raise typer.BadParameter(f"Invalid JSON in {data_file}: {exc}") from exc
426
- if not isinstance(parsed, dict):
427
- raise typer.BadParameter("--data-file must contain a JSON object")
428
- return parsed
429
- payload: dict[str, Any] = {}
430
- if name:
431
- payload["name"] = name
432
- if description is not None:
433
- payload["description"] = description
434
- if lead_account_id:
435
- payload["leadAccountId"] = lead_account_id
436
- if assignee_type:
437
- payload["assigneeType"] = assignee_type
438
- if is_assignee_type_valid is not None:
439
- payload["isAssigneeTypeValid"] = is_assignee_type_valid
440
- if not payload:
441
- raise typer.BadParameter("Provide --data-file or at least one field option for create/update")
442
- return payload
443
-
444
- try:
445
- s = load_settings(strict=True)
446
- s.require_basic_or_token()
447
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
448
-
449
- if action == "list":
450
- if not project_key:
451
- raise typer.BadParameter("--project-key required for list")
452
- project = adapter.get_project(project_key, expand="components")
453
- components = project.get("components", []) if isinstance(project, dict) else []
454
- _emit_json({"count": len(components), "components": components})
455
-
456
- elif action == "get":
457
- if not component_id:
458
- raise typer.BadParameter("--component-id required for get")
459
- payload = adapter.get_component(component_id)
460
- _emit_json(payload)
461
-
462
- elif action == "create":
463
- if not yes:
464
- raise typer.BadParameter("--yes required for create")
465
- payload = _build_payload()
466
- if (
467
- not project_key
468
- and "project" not in payload
469
- and "projectId" not in payload
470
- and "projectKey" not in payload
471
- ):
472
- raise typer.BadParameter(
473
- "--project-key required (or include project/projectId in --data-file) for create"
474
- )
475
- if project_key and "project" not in payload and "projectId" not in payload:
476
- payload["project"] = project_key
477
- result = adapter.create_component(payload)
478
- _emit_json(result)
479
-
480
- elif action == "update":
481
- if not yes:
482
- raise typer.BadParameter("--yes required for update")
483
- if not component_id:
484
- raise typer.BadParameter("--component-id required for update")
485
- payload = _build_payload()
486
- result = adapter.update_component(payload, component_id)
487
- _emit_json(result)
488
-
489
- elif action == "delete":
490
- if not yes:
491
- raise typer.BadParameter("--yes required for delete")
492
- if not component_id:
493
- raise typer.BadParameter("--component-id required for delete")
494
- adapter.delete_component(component_id)
495
- _emit_json({"status": "deleted", "component_id": component_id})
496
-
497
- else:
498
- raise typer.BadParameter(f"Unknown action: {action}")
499
-
500
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
501
- code = 1
502
- logger.error("component_command_failed %s", exc)
503
- typer.echo(f"Error: {exc}", err=True)
504
- finally:
505
- finished_at = datetime.now(UTC)
506
- _record_summary(
507
- command="component",
508
- args=summary_args,
509
- exit_code=code,
510
- started_at=started_at,
511
- finished_at=finished_at,
512
- )
513
- if code != 0:
514
- raise typer.Exit(code=code) from None
515
-
516
-
517
- @app.command("version")
518
- def cmd_version(
519
- action: str = typer.Argument(..., help="Action: list, create, update"),
520
- project_key: str | None = typer.Option(None, "--project-key", "-P", help="Project key (for list/create)"),
521
- project_id: str | None = typer.Option(None, "--project-id", help="Project ID (for create)"),
522
- version_id: str | None = typer.Option(None, "--version-id", help="Version ID (for update)"),
523
- name: str | None = typer.Option(None, "--name", help="Version name (for create/update)"),
524
- description: str | None = typer.Option(None, "--description", help="Version description (for update)"),
525
- start: int | None = typer.Option(None, "--start", help="Start index for pagination (for list)"),
526
- limit: int | None = typer.Option(None, "--limit", help="Limit for pagination (for list)"),
527
- order_by: str | None = typer.Option(
528
- None, "--order-by", help="Order by field: sequence, name, startDate, releaseDate (for list)"
529
- ),
530
- query: str | None = typer.Option(None, "--query", help="Query filter (for list)"),
531
- status: str | None = typer.Option(None, "--status", help="Status filter (for list)"),
532
- archived: bool | None = typer.Option(None, "--archived/--no-archived", help="Archived flag (for create/update)"),
533
- released: bool | None = typer.Option(None, "--released/--no-released", help="Released flag (for create/update)"),
534
- start_date: str | None = typer.Option(None, "--start-date", help="Start date (YYYY-MM-DD) (for update)"),
535
- release_date: str | None = typer.Option(None, "--release-date", help="Release date (YYYY-MM-DD) (for update)"),
536
- yes: bool = typer.Option(False, "--yes", help="Confirm write operations (create/update)"),
537
- ) -> None:
538
- """Manage project versions."""
539
- started_at = datetime.now(UTC)
540
- code = 0
541
- summary_args = [
542
- action,
543
- f"project_key={project_key}",
544
- f"project_id={project_id}",
545
- f"version_id={version_id}",
546
- f"name={name}",
547
- ]
548
-
549
- try:
550
- s = load_settings(strict=True)
551
- s.require_basic_or_token()
552
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
553
-
554
- if action == "list":
555
- if not project_key:
556
- raise typer.BadParameter("--project-key required for list")
557
- payload = adapter.get_project_versions_paginated(
558
- project_key=project_key,
559
- start=start,
560
- limit=limit,
561
- order_by=order_by,
562
- query=query,
563
- status=status,
564
- )
565
- _emit_json(payload)
566
-
567
- elif action == "create":
568
- if not yes:
569
- raise typer.BadParameter("Refusing to create version without --yes")
570
- if not project_key:
571
- raise typer.BadParameter("--project-key required for create")
572
- if not project_id:
573
- raise typer.BadParameter("--project-id required for create")
574
- if not name:
575
- raise typer.BadParameter("--name required for create")
576
- result = adapter.add_version(
577
- key=project_key,
578
- project_id=project_id,
579
- version=name,
580
- is_archived=archived if archived is not None else False,
581
- is_released=released if released is not None else False,
582
- )
583
- _emit_json(result)
584
-
585
- elif action == "update":
586
- if not yes:
587
- raise typer.BadParameter("Refusing to update version without --yes")
588
- if not version_id:
589
- raise typer.BadParameter("--version-id required for update")
590
- # At least one field must be provided for update
591
- if not any(
592
- [name, description is not None, archived is not None, released is not None, start_date, release_date]
593
- ):
594
- raise typer.BadParameter(
595
- "At least one update field required (--name, --description, --archived, --released, --start-date, --release-date)"
596
- )
597
- result = adapter.update_version(
598
- version=version_id,
599
- name=name,
600
- description=description,
601
- is_archived=archived,
602
- is_released=released,
603
- start_date=start_date,
604
- release_date=release_date,
605
- )
606
- _emit_json(result)
607
-
608
- else:
609
- raise typer.BadParameter(f"Unknown action: {action}")
610
-
611
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
612
- code = 1
613
- logger.error("version_command_failed %s", exc)
614
- typer.echo(f"Error: {exc}", err=True)
615
- finally:
616
- finished_at = datetime.now(UTC)
617
- _record_summary(
618
- command="version",
619
- args=summary_args,
620
- exit_code=code,
621
- started_at=started_at,
622
- finished_at=finished_at,
623
- )
624
- if code != 0:
625
- raise typer.Exit(code=code) from None
626
-
627
-
628
- @app.command("search")
629
- def cmd_search(
630
- jql: str = typer.Argument(..., help="JQL query string"),
631
- limit: int = typer.Option(25, "--limit", help="Number of results"),
632
- fields: str | None = typer.Option(None, "--fields", help="Comma separated fields"),
633
- start: int = typer.Option(0, "--start", help="Start index for pagination (advanced search)"),
634
- advanced: bool = typer.Option(False, "--advanced", help="Use advanced search with pagination"),
635
- json_only: bool = typer.Option(False, "--json-only", help="Emit JSON payload for this command"),
636
- ) -> None:
637
- """Search issues using JQL. Use --advanced for pagination support."""
638
- started_at = datetime.now(UTC)
639
- code = 0
640
- try:
641
- s = load_settings(strict=True)
642
- s.require_basic_or_token()
643
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
644
-
645
- fields_list = [f.strip() for f in fields.split(",")] if fields else None
646
- if advanced or start > 0:
647
- payload = adapter.search_issues_advanced(jql, start=start, limit=limit, fields=fields_list)
648
- else:
649
- payload = adapter.jql(jql, limit=limit, fields=fields_list)
650
- _emit_json(payload)
651
- except (AuthError, VDSClientError) as exc:
652
- code = 1
653
- logger.error("search_failed %s", exc)
654
- typer.echo(f"Error: {exc}", err=True)
655
- finally:
656
- finished_at = datetime.now(UTC)
657
- args_list = [jql, f"limit={limit}"]
658
- if start > 0:
659
- args_list.append(f"start={start}")
660
- if advanced:
661
- args_list.append("advanced=True")
662
- if json_only:
663
- args_list.append("json_only=True")
664
- _record_summary(
665
- command="search",
666
- args=args_list,
667
- exit_code=code,
668
- started_at=started_at,
669
- finished_at=finished_at,
670
- )
671
- if code != 0:
672
- raise typer.Exit(code=code) from None
673
-
674
-
675
- @app.command("search-by-filter")
676
- def cmd_search_by_filter(
677
- filter_id: int = typer.Argument(..., help="Filter ID"),
678
- limit: int = typer.Option(50, "--limit", help="Number of results"),
679
- fields: str | None = typer.Option(None, "--fields", help="Comma separated fields"),
680
- start: int = typer.Option(0, "--start", help="Start index for pagination"),
681
- ) -> None:
682
- """Search issues using a saved filter."""
683
- started_at = datetime.now(UTC)
684
- code = 0
685
- try:
686
- s = load_settings(strict=True)
687
- s.require_basic_or_token()
688
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
689
-
690
- fields_list = [f.strip() for f in fields.split(",")] if fields else None
691
- payload = adapter.search_issues_by_filter(filter_id, start=start, limit=limit, fields=fields_list)
692
- _emit_json(payload)
693
- except (AuthError, VDSClientError) as exc:
694
- code = 1
695
- logger.error("search_by_filter_failed %s", exc)
696
- typer.echo(f"Error: {exc}", err=True)
697
- finally:
698
- finished_at = datetime.now(UTC)
699
- args_list = [str(filter_id), f"limit={limit}"]
700
- if start > 0:
701
- args_list.append(f"start={start}")
702
- _record_summary(
703
- command="search-by-filter",
704
- args=args_list,
705
- exit_code=code,
706
- started_at=started_at,
707
- finished_at=finished_at,
708
- )
709
- if code != 0:
710
- raise typer.Exit(code=code) from None
711
-
712
-
713
- @app.command("issue")
714
- def cmd_issue(
715
- key: str = typer.Argument(..., help="Issue key (e.g., NTTC-123)"),
716
- ) -> None:
717
- started_at = datetime.now(UTC)
718
- code = 0
719
- try:
720
- s = load_settings(strict=True)
721
- s.require_basic_or_token()
722
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
723
- payload = adapter.get_issue(key)
724
- _emit_json(payload)
725
- except (AuthError, VDSClientError) as exc:
726
- code = 1
727
- logger.error("issue_failed %s", exc)
728
- typer.echo(f"Error: {exc}", err=True)
729
- finally:
730
- finished_at = datetime.now(UTC)
731
- _record_summary(command="issue", args=[key], exit_code=code, started_at=started_at, finished_at=finished_at)
732
- if code != 0:
733
- raise typer.Exit(code=code) from None
734
-
735
-
736
- @app.command("bulk-update")
737
- def cmd_bulk_update(
738
- issue_keys: str = typer.Option(..., "--issue-keys", help="Comma-separated issue keys (e.g., NTTC-1,NTTC-2)"),
739
- fields: str | None = typer.Option(None, "--fields", help="JSON string or '*all' for all fields"),
740
- fields_file: Path | None = typer.Option(None, "--fields-file", help="JSON file containing field updates"),
741
- yes: bool = typer.Option(False, "--yes", help="Confirm bulk update operation"),
742
- ) -> None:
743
- """Bulk update multiple issues."""
744
- started_at = datetime.now(UTC)
745
- code = 0
746
- summary_args = [f"issue_keys={issue_keys}", f"fields_file={fields_file}"]
747
-
748
- def _load_fields() -> str:
749
- if fields_file:
750
- if not fields_file.exists():
751
- raise typer.BadParameter(f"Fields file not found: {fields_file}")
752
- try:
753
- parsed = json.loads(fields_file.read_text())
754
- return json.dumps(parsed)
755
- except json.JSONDecodeError as exc:
756
- raise typer.BadParameter(f"Invalid JSON in {fields_file}: {exc}") from exc
757
- if fields:
758
- # Validate JSON if provided
759
- if fields != "*all":
760
- try:
761
- json.loads(fields)
762
- except json.JSONDecodeError as exc:
763
- raise typer.BadParameter(f"Invalid JSON in --fields: {exc}") from exc
764
- return fields
765
- return "*all"
766
-
767
- try:
768
- if not yes:
769
- raise typer.BadParameter("Refusing to bulk update issues without --yes")
770
- s = load_settings(strict=True)
771
- s.require_basic_or_token()
772
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
773
-
774
- key_list = [k.strip() for k in issue_keys.split(",") if k.strip()]
775
- if not key_list:
776
- raise typer.BadParameter("At least one issue key required in --issue-keys")
777
- fields_value = _load_fields()
778
- result = adapter.bulk_update_issue_field(key_list=key_list, fields=fields_value)
779
- _emit_json(result)
780
-
781
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
782
- code = 1
783
- logger.error("bulk_update_failed %s", exc)
784
- typer.echo(f"Error: {exc}", err=True)
785
- finally:
786
- finished_at = datetime.now(UTC)
787
- _record_summary(
788
- command="bulk-update",
789
- args=summary_args,
790
- exit_code=code,
791
- started_at=started_at,
792
- finished_at=finished_at,
793
- )
794
- if code != 0:
795
- raise typer.Exit(code=code) from None
796
-
797
-
798
- @app.command("field-append")
799
- def cmd_field_append(
800
- issue_key: str = typer.Option(..., "--issue-key", "-k", help="Issue key (e.g., NTTC-123)"),
801
- field: str = typer.Option(..., "--field", help="Field ID (e.g., customfield_10000)"),
802
- value: str | None = typer.Option(None, "--value", help="JSON string value to append"),
803
- value_file: Path | None = typer.Option(None, "--value-file", help="JSON file containing value to append"),
804
- no_notify: bool = typer.Option(False, "--no-notify", help="Don't notify users"),
805
- yes: bool = typer.Option(False, "--yes", help="Confirm field append operation"),
806
- ) -> None:
807
- """Append value to issue field (for multi-select fields)."""
808
- started_at = datetime.now(UTC)
809
- code = 0
810
- summary_args = [f"issue_key={issue_key}", f"field={field}", f"value_file={value_file}"]
811
-
812
- def _load_value() -> dict[str, Any]:
813
- if value_file:
814
- if not value_file.exists():
815
- raise typer.BadParameter(f"Value file not found: {value_file}")
816
- try:
817
- parsed = json.loads(value_file.read_text())
818
- if not isinstance(parsed, dict):
819
- raise typer.BadParameter("--value-file must contain a JSON object")
820
- return parsed
821
- except json.JSONDecodeError as exc:
822
- raise typer.BadParameter(f"Invalid JSON in {value_file}: {exc}") from exc
823
- if not value:
824
- raise typer.BadParameter("Provide --value or --value-file")
825
- try:
826
- parsed = json.loads(value)
827
- if not isinstance(parsed, dict):
828
- raise typer.BadParameter("--value must be a JSON object")
829
- return parsed
830
- except json.JSONDecodeError as exc:
831
- raise typer.BadParameter(f"Invalid JSON in --value: {exc}") from exc
832
-
833
- try:
834
- if not yes:
835
- raise typer.BadParameter("Refusing to append field value without --yes")
836
- s = load_settings(strict=True)
837
- s.require_basic_or_token()
838
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
839
-
840
- value_dict = _load_value()
841
- result = adapter.issue_field_value_append(
842
- issue_id_or_key=issue_key, field=field, value=value_dict, notify_users=not no_notify
843
- )
844
- _emit_json(result)
845
-
846
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
847
- code = 1
848
- logger.error("field_append_failed %s", exc)
849
- typer.echo(f"Error: {exc}", err=True)
850
- finally:
851
- finished_at = datetime.now(UTC)
852
- _record_summary(
853
- command="field-append",
854
- args=summary_args,
855
- exit_code=code,
856
- started_at=started_at,
857
- finished_at=finished_at,
858
- )
859
- if code != 0:
860
- raise typer.Exit(code=code) from None
861
-
862
-
863
- @app.command("issue-archive")
864
- def cmd_issue_archive(
865
- issue_key: str = typer.Option(..., "--issue-key", "-k", help="Issue key (e.g., NTTC-123)"),
866
- yes: bool = typer.Option(False, "--yes", help="Confirm archive operation"),
867
- ) -> None:
868
- """Archive an issue."""
869
- started_at = datetime.now(UTC)
870
- code = 0
871
- summary_args = [f"issue_key={issue_key}"]
872
-
873
- try:
874
- if not yes:
875
- raise typer.BadParameter("Refusing to archive issue without --yes")
876
- s = load_settings(strict=True)
877
- s.require_basic_or_token()
878
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
879
-
880
- adapter.issue_archive(issue_key)
881
- _emit_json({"status": "archived", "issue_key": issue_key})
882
-
883
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
884
- code = 1
885
- logger.error("issue_archive_failed %s", exc)
886
- typer.echo(f"Error: {exc}", err=True)
887
- finally:
888
- finished_at = datetime.now(UTC)
889
- _record_summary(
890
- command="issue-archive",
891
- args=summary_args,
892
- exit_code=code,
893
- started_at=started_at,
894
- finished_at=finished_at,
895
- )
896
- if code != 0:
897
- raise typer.Exit(code=code) from None
898
-
899
-
900
- @app.command("issue-restore")
901
- def cmd_issue_restore(
902
- issue_key: str = typer.Option(..., "--issue-key", "-k", help="Issue key (e.g., NTTC-123)"),
903
- yes: bool = typer.Option(False, "--yes", help="Confirm restore operation"),
904
- ) -> None:
905
- """Restore an archived issue."""
906
- started_at = datetime.now(UTC)
907
- code = 0
908
- summary_args = [f"issue_key={issue_key}"]
909
-
910
- try:
911
- if not yes:
912
- raise typer.BadParameter("Refusing to restore issue without --yes")
913
- s = load_settings(strict=True)
914
- s.require_basic_or_token()
915
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
916
-
917
- adapter.issue_restore(issue_key)
918
- _emit_json({"status": "restored", "issue_key": issue_key})
919
-
920
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
921
- code = 1
922
- logger.error("issue_restore_failed %s", exc)
923
- typer.echo(f"Error: {exc}", err=True)
924
- finally:
925
- finished_at = datetime.now(UTC)
926
- _record_summary(
927
- command="issue-restore",
928
- args=summary_args,
929
- exit_code=code,
930
- started_at=started_at,
931
- finished_at=finished_at,
932
- )
933
- if code != 0:
934
- raise typer.Exit(code=code) from None
935
-
936
-
937
- @app.command("property")
938
- def cmd_property(
939
- action: str = typer.Argument(..., help="Action: get, set"),
940
- property_id: str | None = typer.Option(None, "--property-id", help="Property ID (for set)"),
941
- key: str | None = typer.Option(None, "--key", help="Property key (for get)"),
942
- permission_level: str | None = typer.Option(None, "--permission-level", help="Permission level (for get)"),
943
- key_filter: str | None = typer.Option(None, "--key-filter", help="Key filter pattern (for get)"),
944
- value: str | None = typer.Option(None, "--value", help="Property value (for set)"),
945
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation (for set)"),
946
- ) -> None:
947
- """Manage JIRA application properties."""
948
- started_at = datetime.now(UTC)
949
- code = 0
950
- summary_args = [action]
951
-
952
- try:
953
- s = load_settings(strict=True)
954
- s.require_basic_or_token()
955
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
956
-
957
- if action == "get":
958
- summary_args.extend([f"key={key}", f"permission_level={permission_level}", f"key_filter={key_filter}"])
959
- payload = adapter.get_property(key=key, permission_level=permission_level, key_filter=key_filter)
960
- _emit_json(payload)
961
-
962
- elif action == "set":
963
- if not yes:
964
- raise typer.BadParameter("Refusing to set property without --yes")
965
- if not property_id:
966
- raise typer.BadParameter("--property-id required for set")
967
- if value is None:
968
- raise typer.BadParameter("--value required for set")
969
- summary_args.extend([f"property_id={property_id}", f"value={value}"])
970
- adapter.set_property(property_id, value)
971
- _emit_json({"status": "set", "property_id": property_id, "value": value})
972
-
973
- else:
974
- raise typer.BadParameter(f"Unknown action: {action}")
975
-
976
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
977
- code = 1
978
- logger.error("property_failed %s", exc)
979
- typer.echo(f"Error: {exc}", err=True)
980
- finally:
981
- finished_at = datetime.now(UTC)
982
- _record_summary(
983
- command="property",
984
- args=summary_args,
985
- exit_code=code,
986
- started_at=started_at,
987
- finished_at=finished_at,
988
- )
989
- if code != 0:
990
- raise typer.Exit(code=code) from None
991
-
992
-
993
- @app.command("settings")
994
- def cmd_settings(
995
- action: str = typer.Argument(..., help="Action: advanced"),
996
- ) -> None:
997
- """Manage JIRA settings."""
998
- started_at = datetime.now(UTC)
999
- code = 0
1000
- summary_args = [action]
1001
-
1002
- try:
1003
- s = load_settings(strict=True)
1004
- s.require_basic_or_token()
1005
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1006
-
1007
- if action == "advanced":
1008
- payload = adapter.get_advanced_settings()
1009
- _emit_json(payload)
1010
- else:
1011
- raise typer.BadParameter(f"Unknown action: {action}")
1012
-
1013
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1014
- code = 1
1015
- logger.error("settings_failed %s", exc)
1016
- typer.echo(f"Error: {exc}", err=True)
1017
- finally:
1018
- finished_at = datetime.now(UTC)
1019
- _record_summary(
1020
- command="settings",
1021
- args=summary_args,
1022
- exit_code=code,
1023
- started_at=started_at,
1024
- finished_at=finished_at,
1025
- )
1026
- if code != 0:
1027
- raise typer.Exit(code=code) from None
1028
-
1029
-
1030
- @app.command("create")
1031
- def cmd_create(
1032
- project: str = typer.Option(..., "--project", help="Project key"),
1033
- issuetype: str = typer.Option(..., "--issuetype", help="Issue type name (e.g., Task, Bug)"),
1034
- summary: str = typer.Option(..., "--summary", help="Summary"),
1035
- description: str | None = typer.Option(None, "--description", help="Description"),
1036
- assignee: str | None = typer.Option(None, "--assignee", help="Assignee username (Server/DC)"),
1037
- labels: str | None = typer.Option(None, "--labels", help="Comma-separated labels"),
1038
- set_field: list[str] = typer.Option(
1039
- [], "--set", help="Additional key=value field pairs (e.g., customfield_12345=10001)"
1040
- ),
1041
- set_json: bool = typer.Option(
1042
- False,
1043
- "--set-json",
1044
- help="Allow JSON scalar values (e.g., true, 1) in --set (default: objects/arrays only)",
1045
- ),
1046
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1047
- dry_run: bool = typer.Option(False, "--dry-run", help="Validate payload without sending"),
1048
- ) -> None:
1049
- started_at = datetime.now(UTC)
1050
- code = 0
1051
- args = [f"project={project}", f"issuetype={issuetype}"]
1052
- try:
1053
- if not yes and not dry_run:
1054
- raise typer.BadParameter("Refusing to create without --yes (or use --dry-run)")
1055
-
1056
- s = load_settings(strict=True)
1057
- s.require_basic_or_token()
1058
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1059
-
1060
- label_list = [x.strip() for x in labels.split(",")] if labels else None
1061
- extras = _parse_set(set_field, allow_scalar_json=set_json) if set_field else {}
1062
-
1063
- # Build core payload
1064
- payload = {
1065
- "project": {"key": project},
1066
- "summary": summary,
1067
- "issuetype": {"name": issuetype},
1068
- }
1069
- if description:
1070
- payload["description"] = description
1071
- if assignee:
1072
- payload["assignee"] = {"name": assignee}
1073
- if label_list:
1074
- payload["labels"] = label_list
1075
- if extras:
1076
- payload.update(extras)
1077
-
1078
- if dry_run:
1079
- typer.echo(f"[DRY RUN] Validating payload for {project} / {issuetype}...", err=True)
1080
-
1081
- # Basic validation: Check if required fields from metadata are present
1082
- # This is "best effort" validation
1083
- field_name_map: dict[str, str] = {}
1084
- try:
1085
- meta = adapter.get_createmeta(project_key=project, expand="projects.issuetypes.fields")
1086
-
1087
- # Find project and issuetype
1088
- found_it = None
1089
- if "projects" in meta:
1090
- for p in meta["projects"]:
1091
- project_key = str(p.get("key", ""))
1092
- project_id = str(p.get("id", ""))
1093
- if project_key.lower() == project.lower() or project_id == project:
1094
- for it in p.get("issuetypes", []):
1095
- it_name = str(it.get("name", ""))
1096
- it_id = str(it.get("id", ""))
1097
- if it_name.lower() == issuetype.lower() or it_id == issuetype:
1098
- found_it = it
1099
- break
1100
-
1101
- if found_it:
1102
- missing = []
1103
- fields_meta = found_it.get("fields", {})
1104
- field_name_map = {
1105
- fid: str(fmeta.get("name"))
1106
- for fid, fmeta in fields_meta.items()
1107
- if isinstance(fmeta, dict) and fmeta.get("name")
1108
- }
1109
- for fid, fmeta in fields_meta.items():
1110
- if fmeta.get("required") and not fmeta.get("hasDefaultValue"):
1111
- # Check if field is in payload
1112
- # Note: Payload keys might be field IDs (customfield_X) or system names (summary)
1113
- # We need to check both
1114
- fname = fmeta.get("name", "").lower()
1115
- if fid not in payload and fname not in payload:
1116
- # Special case mapping for standard fields that might match
1117
- is_present = False
1118
- if fid == "issuetype" or fid == "project":
1119
- is_present = True
1120
-
1121
- if not is_present:
1122
- missing.append(f"{fmeta.get('name')} ({fid})")
1123
-
1124
- if missing:
1125
- typer.echo("[DRY RUN] ⚠️ Warning: The following REQUIRED fields appear missing:", err=True)
1126
- for m in missing:
1127
- typer.echo(f" - {m}", err=True)
1128
- typer.echo("Tip: Use --set to provide them.", err=True)
1129
- else:
1130
- typer.echo("[DRY RUN] ✅ All required fields appear to be present.", err=True)
1131
- except Exception as e:
1132
- typer.echo(f"[DRY RUN] Metadata validation skipped due to warning: {e}", err=True)
1133
-
1134
- output = {"dry_run": True, "payload": payload}
1135
- if field_name_map:
1136
- output["field_name_map"] = field_name_map
1137
- _emit_json(output)
1138
- return
1139
-
1140
- # Execute creation
1141
- res = adapter.create_issue(
1142
- project_key=project,
1143
- summary=summary,
1144
- issuetype=issuetype,
1145
- description=description,
1146
- assignee=assignee,
1147
- labels=label_list or [],
1148
- extra_fields=extras,
1149
- )
1150
- _emit_json(res)
1151
-
1152
- except VDSClientError as exc:
1153
- code = 1
1154
- msg = str(exc)
1155
- logger.error("create_failed %s", exc)
1156
- typer.echo(f"Error: {exc}", err=True)
1157
-
1158
- required_ref = _extract_required_field_ref(msg)
1159
- field_refs = _extract_error_field_refs(msg)
1160
- matched_fields: list[dict[str, Any]] = []
1161
-
1162
- if field_refs:
1163
- try:
1164
- meta = adapter.get_createmeta(project_key=project, issuetype=issuetype)
1165
- raw_fields = _extract_createmeta_fields(meta, project, issuetype)
1166
- all_fields = _collect_fields(raw_fields, field_filter=None, include_system=True)
1167
- matched_fields = _match_fields_by_refs(all_fields, field_refs)
1168
- except Exception:
1169
- matched_fields = []
1170
-
1171
- if matched_fields:
1172
- typer.echo("\n--- Field Details ---", err=True)
1173
- for field_data in matched_fields:
1174
- field_name = field_data.get("name") or ""
1175
- field_id = field_data.get("id") or ""
1176
- typer.echo(f"Field: {field_name} (id: {field_id})", err=True)
1177
- allowed_values = field_data.get("allowedValues") or []
1178
- allowed_text = _format_allowed_values(allowed_values)
1179
- if allowed_text:
1180
- typer.echo(f" Allowed values: {allowed_text}", err=True)
1181
-
1182
- if required_ref:
1183
- set_field_ref = required_ref
1184
- if matched_fields:
1185
- for field_data in matched_fields:
1186
- field_id = str(field_data.get("id") or "")
1187
- field_name = str(field_data.get("name") or "")
1188
- if required_ref.lower() in field_id.lower() or required_ref.lower() in field_name.lower():
1189
- if field_id:
1190
- set_field_ref = field_id
1191
- break
1192
- typer.echo("\n--- Troubleshooting Guide ---", err=True)
1193
- typer.echo(f"It looks like a required field '{required_ref}' is missing.", err=True)
1194
- typer.echo("To find the correct ID and allowed values, run:", err=True)
1195
- typer.echo(
1196
- f" vds-cli jira discover-fields --project {project} --issuetype {issuetype} "
1197
- f'--include-system --field "{required_ref}"',
1198
- err=True,
1199
- )
1200
- typer.echo("\nThen use --set to provide the value:", err=True)
1201
- typer.echo(f' --set \'{set_field_ref}={{"value": "..."}}\'', err=True)
1202
-
1203
- except (AuthError, typer.BadParameter) as exc:
1204
- code = 1
1205
- logger.error("create_failed %s", exc)
1206
- typer.echo(f"Error: {exc}", err=True)
1207
- finally:
1208
- finished_at = datetime.now(UTC)
1209
- _record_summary(
1210
- command="create",
1211
- args=args + [f"set_json={set_json}", f"dry_run={dry_run}", f"yes={yes}"],
1212
- exit_code=code,
1213
- started_at=started_at,
1214
- finished_at=finished_at,
1215
- )
1216
- if code != 0:
1217
- raise typer.Exit(code=code) from None
1218
-
1219
-
1220
- @app.command("update")
1221
- def cmd_update(
1222
- key: str = typer.Argument(..., help="Issue key"),
1223
- set_field: list[str] = typer.Option([], "--set", help="key=value pairs to update (repeatable)"),
1224
- set_json: bool = typer.Option(
1225
- False,
1226
- "--set-json",
1227
- help="Allow JSON scalar values (e.g., true, 1) in --set (default: objects/arrays only)",
1228
- ),
1229
- add_label: list[str] = typer.Option([], "--add-label", help="Labels to add"),
1230
- remove_label: list[str] = typer.Option([], "--remove-label", help="Labels to remove"),
1231
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1232
- dry_run: bool = typer.Option(False, "--dry-run", help="Validate payload without sending"),
1233
- ) -> None:
1234
- started_at = datetime.now(UTC)
1235
- code = 0
1236
- try:
1237
- if not yes and not dry_run:
1238
- raise typer.BadParameter("Refusing to update without --yes (or use --dry-run)")
1239
- s = load_settings(strict=True)
1240
- s.require_basic_or_token()
1241
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1242
- fields: dict[str, Any] = _parse_set(set_field, allow_scalar_json=set_json)
1243
- if add_label or remove_label:
1244
- current = adapter.get_issue(key)
1245
- cur_labels = list(current.get("fields", {}).get("labels") or [])
1246
- if add_label:
1247
- cur_labels = sorted(set(cur_labels + add_label))
1248
- if remove_label:
1249
- cur_labels = [label for label in cur_labels if label not in set(remove_label)]
1250
- fields["labels"] = cur_labels
1251
- if dry_run and not yes:
1252
- _emit_json({"dry_run": True, "request": {"key": key, "fields": fields}})
1253
- else:
1254
- res = adapter.update_issue_fields(key, fields)
1255
- _emit_json(res)
1256
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1257
- code = 1
1258
- logger.error("update_failed %s", exc)
1259
- typer.echo(f"Error: {exc}", err=True)
1260
- finally:
1261
- finished_at = datetime.now(UTC)
1262
- _record_summary(
1263
- command="update",
1264
- args=[key]
1265
- + set_field
1266
- + [
1267
- f"set_json={set_json}",
1268
- f"add_label={add_label}",
1269
- f"remove_label={remove_label}",
1270
- f"dry_run={dry_run}",
1271
- f"yes={yes}",
1272
- ],
1273
- exit_code=code,
1274
- started_at=started_at,
1275
- finished_at=finished_at,
1276
- )
1277
- if code != 0:
1278
- raise typer.Exit(code=code) from None
1279
-
1280
-
1281
- @app.command("comment")
1282
- def cmd_comment(
1283
- key: str = typer.Argument(..., help="Issue key"),
1284
- message: str = typer.Option(..., "--message", help="Comment message"),
1285
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1286
- ) -> None:
1287
- started_at = datetime.now(UTC)
1288
- code = 0
1289
- try:
1290
- if not yes:
1291
- raise typer.BadParameter("Refusing to comment without --yes")
1292
- s = load_settings(strict=True)
1293
- s.require_basic_or_token()
1294
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1295
- res = adapter.add_comment(key, message)
1296
- _emit_json(res)
1297
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1298
- code = 1
1299
- logger.error("comment_failed %s", exc)
1300
- typer.echo(f"Error: {exc}", err=True)
1301
- finally:
1302
- finished_at = datetime.now(UTC)
1303
- _record_summary(command="comment", args=[key], exit_code=code, started_at=started_at, finished_at=finished_at)
1304
- if code != 0:
1305
- raise typer.Exit(code=code) from None
1306
-
1307
-
1308
- @app.command("transition")
1309
- def cmd_transition(
1310
- key: str = typer.Argument(..., help="Issue key"),
1311
- to: str = typer.Option(..., "--to", help="Target status name"),
1312
- admin: bool = typer.Option(False, "--admin", help="Acknowledge administrative action"),
1313
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1314
- ) -> None:
1315
- started_at = datetime.now(UTC)
1316
- code = 0
1317
- try:
1318
- if not (admin and yes):
1319
- raise typer.BadParameter("Refusing to transition without --admin and --yes")
1320
- s = load_settings(strict=True)
1321
- s.require_basic_or_token()
1322
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1323
- adapter.transition_issue(key, to)
1324
- _emit_json({"key": key, "transitioned_to": to})
1325
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1326
- code = 1
1327
- logger.error("transition_failed %s", exc)
1328
- typer.echo(f"Error: {exc}", err=True)
1329
- finally:
1330
- finished_at = datetime.now(UTC)
1331
- _record_summary(
1332
- command="transition", args=[key, f"to={to}"], exit_code=code, started_at=started_at, finished_at=finished_at
1333
- )
1334
- if code != 0:
1335
- raise typer.Exit(code=code) from None
1336
-
1337
-
1338
- @app.command("delete")
1339
- def cmd_delete(
1340
- key: str = typer.Argument(..., help="Issue key"),
1341
- yes: bool = typer.Option(False, "--yes", help="Confirm deletion"),
1342
- force: bool = typer.Option(False, "--force", help="Double confirm deletion"),
1343
- ) -> None:
1344
- started_at = datetime.now(UTC)
1345
- code = 0
1346
- try:
1347
- if not (yes and force):
1348
- raise typer.BadParameter("Refusing to delete without --yes and --force")
1349
- s = load_settings(strict=True)
1350
- s.require_basic_or_token()
1351
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1352
- adapter.delete_issue(key)
1353
- _emit_json({"deleted": key})
1354
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1355
- code = 1
1356
- logger.error("delete_failed %s", exc)
1357
- typer.echo(f"Error: {exc}", err=True)
1358
- finally:
1359
- finished_at = datetime.now(UTC)
1360
- _record_summary(command="delete", args=[key], exit_code=code, started_at=started_at, finished_at=finished_at)
1361
- if code != 0:
1362
- raise typer.Exit(code=code) from None
1363
-
1364
-
1365
- @app.command("createmeta")
1366
- def cmd_createmeta(
1367
- project: str = typer.Option(..., "--project", help="Project key"),
1368
- issuetype: str = typer.Option(..., "--issuetype", help="Issue type name"),
1369
- expand: str | None = typer.Option(None, "--expand", help="Expand options"),
1370
- ) -> None:
1371
- """Get create metadata for issue creation (field definitions, allowed values)."""
1372
- started_at = datetime.now(UTC)
1373
- code = 0
1374
- try:
1375
- s = load_settings(strict=True)
1376
- s.require_basic_or_token()
1377
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1378
- payload = adapter.get_createmeta(project_key=project, issuetype=issuetype, expand=expand)
1379
- _emit_json(payload)
1380
- except (AuthError, VDSClientError) as exc:
1381
- code = 1
1382
- logger.error("createmeta_failed %s", exc)
1383
- typer.echo(f"Error: {exc}", err=True)
1384
- finally:
1385
- finished_at = datetime.now(UTC)
1386
- _record_summary(
1387
- command="createmeta",
1388
- args=[f"project={project}", f"issuetype={issuetype}"],
1389
- exit_code=code,
1390
- started_at=started_at,
1391
- finished_at=finished_at,
1392
- )
1393
- if code != 0:
1394
- raise typer.Exit(code=code) from None
1395
-
1396
-
1397
- @app.command("custom-fields")
1398
- def cmd_custom_fields(
1399
- search: str | None = typer.Option(None, "--search", help="Search filter"),
1400
- start: int = typer.Option(1, "--start", help="Start index"),
1401
- limit: int = typer.Option(50, "--limit", help="Number of results"),
1402
- ) -> None:
1403
- """Get existing custom fields or find by filter."""
1404
- started_at = datetime.now(UTC)
1405
- code = 0
1406
- try:
1407
- s = load_settings(strict=True)
1408
- s.require_basic_or_token()
1409
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1410
- payload = adapter.get_custom_fields(search=search, start=start, limit=limit)
1411
- _emit_json({"count": len(payload), "custom_fields": payload})
1412
- except (AuthError, VDSClientError) as exc:
1413
- code = 1
1414
- logger.error("custom_fields_failed %s", exc)
1415
- typer.echo(f"Error: {exc}", err=True)
1416
- finally:
1417
- finished_at = datetime.now(UTC)
1418
- _record_summary(
1419
- command="custom-fields",
1420
- args=[f"search={search}", f"start={start}", f"limit={limit}"],
1421
- exit_code=code,
1422
- started_at=started_at,
1423
- finished_at=finished_at,
1424
- )
1425
- if code != 0:
1426
- raise typer.Exit(code=code) from None
1427
-
1428
-
1429
- @app.command("board")
1430
- def cmd_board(
1431
- action: str = typer.Argument(..., help="Action: list, get, create, delete, config, issues, properties, velocity"),
1432
- board_id: int | None = typer.Option(None, "--board-id", help="Board ID"),
1433
- filter_id: int | None = typer.Option(None, "--filter-id", help="Filter ID (for create/get-by-filter)"),
1434
- name: str | None = typer.Option(None, "--name", help="Board name (for create)"),
1435
- board_type: str | None = typer.Option(None, "--type", help="Board type: scrum, kanban (for create)"),
1436
- project_key: str | None = typer.Option(None, "--project", help="Project key (for list)"),
1437
- limit: int = typer.Option(50, "--limit", help="Number of results"),
1438
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1439
- ) -> None:
1440
- """Agile board operations."""
1441
- started_at = datetime.now(UTC)
1442
- code = 0
1443
- try:
1444
- s = load_settings(strict=True)
1445
- s.require_basic_or_token()
1446
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1447
-
1448
- if action == "list":
1449
- payload = adapter.get_all_agile_boards(project_key=project_key, board_type=board_type, start=0, limit=limit)
1450
- _emit_json({"count": len(payload), "boards": payload})
1451
- elif action == "get":
1452
- if not board_id and not filter_id:
1453
- raise typer.BadParameter("Either --board-id or --filter-id required")
1454
- if filter_id:
1455
- payload = adapter.get_agile_board_by_filter_id(filter_id)
1456
- else:
1457
- payload = adapter.get_agile_board(board_id) # type: ignore[arg-type]
1458
- _emit_json(payload)
1459
- elif action == "create":
1460
- if not yes:
1461
- raise typer.BadParameter("Refusing to create without --yes")
1462
- if not name or not board_type or not filter_id:
1463
- raise typer.BadParameter("--name, --type, and --filter-id required for create")
1464
- payload = adapter.create_agile_board(name, board_type, filter_id)
1465
- _emit_json(payload)
1466
- elif action == "delete":
1467
- if not (yes and board_id):
1468
- raise typer.BadParameter("Refusing to delete without --yes and --board-id")
1469
- adapter.delete_agile_board(board_id) # type: ignore[arg-type]
1470
- _emit_json({"deleted": board_id})
1471
- elif action == "config":
1472
- if not board_id:
1473
- raise typer.BadParameter("--board-id required")
1474
- payload = adapter.get_agile_board_configuration(board_id) # type: ignore[arg-type]
1475
- _emit_json(payload)
1476
- elif action == "issues":
1477
- if not board_id:
1478
- raise typer.BadParameter("--board-id required")
1479
- payload = adapter.get_issues_for_board(board_id) # type: ignore[arg-type]
1480
- _emit_json({"count": len(payload), "issues": payload})
1481
- elif action == "properties":
1482
- if not board_id:
1483
- raise typer.BadParameter("--board-id required")
1484
- payload = adapter.get_agile_board_properties(board_id) # type: ignore[arg-type]
1485
- _emit_json({"count": len(payload), "properties": payload})
1486
- elif action == "velocity":
1487
- if not board_id:
1488
- raise typer.BadParameter("--board-id required")
1489
- payload = adapter.get_agile_board_refined_velocity(board_id) # type: ignore[arg-type]
1490
- _emit_json(payload)
1491
- else:
1492
- raise typer.BadParameter(f"Unknown action: {action}")
1493
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1494
- code = 1
1495
- logger.error("board_failed %s", exc)
1496
- typer.echo(f"Error: {exc}", err=True)
1497
- finally:
1498
- finished_at = datetime.now(UTC)
1499
- _record_summary(
1500
- command="board",
1501
- args=[action, f"board_id={board_id}", f"limit={limit}"],
1502
- exit_code=code,
1503
- started_at=started_at,
1504
- finished_at=finished_at,
1505
- )
1506
- if code != 0:
1507
- raise typer.Exit(code=code) from None
1508
-
1509
-
1510
- @app.command("epic")
1511
- def cmd_epic(
1512
- action: str = typer.Argument(..., help="Action: issues, list, issues-for-epic"),
1513
- epic_key: str | None = typer.Option(None, "--epic-key", help="Epic key (for issues)"),
1514
- board_id: int | None = typer.Option(None, "--board-id", help="Board ID (for list/issues-for-epic)"),
1515
- epic_id: int | None = typer.Option(None, "--epic-id", help="Epic ID (for issues-for-epic)"),
1516
- done: bool = typer.Option(False, "--done", help="Include done epics (for list)"),
1517
- limit: int = typer.Option(50, "--limit", help="Number of results"),
1518
- ) -> None:
1519
- """Epic operations."""
1520
- started_at = datetime.now(UTC)
1521
- code = 0
1522
- try:
1523
- s = load_settings(strict=True)
1524
- s.require_basic_or_token()
1525
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1526
-
1527
- if action == "issues":
1528
- if not epic_key:
1529
- raise typer.BadParameter("--epic-key required")
1530
- payload = adapter.epic_issues(epic_key)
1531
- _emit_json({"count": len(payload), "issues": payload})
1532
- elif action == "list":
1533
- if not board_id:
1534
- raise typer.BadParameter("--board-id required")
1535
- payload = adapter.get_epics(board_id, done=done, start=0, limit=limit) # type: ignore[arg-type]
1536
- _emit_json({"count": len(payload), "epics": payload})
1537
- elif action == "issues-for-epic":
1538
- if not board_id or not epic_id:
1539
- raise typer.BadParameter("--board-id and --epic-id required")
1540
- payload = adapter.get_issues_for_epic(
1541
- board_id, epic_id, jql="", validate_query="", fields="*all", expand="", start=0, limit=limit
1542
- ) # type: ignore[arg-type]
1543
- _emit_json({"count": len(payload), "issues": payload})
1544
- else:
1545
- raise typer.BadParameter(f"Unknown action: {action}")
1546
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1547
- code = 1
1548
- logger.error("epic_failed %s", exc)
1549
- typer.echo(f"Error: {exc}", err=True)
1550
- finally:
1551
- finished_at = datetime.now(UTC)
1552
- _record_summary(
1553
- command="epic",
1554
- args=[action, f"epic_key={epic_key}", f"board_id={board_id}"],
1555
- exit_code=code,
1556
- started_at=started_at,
1557
- finished_at=finished_at,
1558
- )
1559
- if code != 0:
1560
- raise typer.Exit(code=code) from None
1561
-
1562
-
1563
- @app.command("sprint")
1564
- def cmd_sprint(
1565
- action: str = typer.Argument(..., help="Action: list, issues, versions, create, rename, add-issues"),
1566
- board_id: int | None = typer.Option(None, "--board-id", help="Board ID"),
1567
- sprint_id: int | None = typer.Option(None, "--sprint-id", help="Sprint ID"),
1568
- state: str | None = typer.Option(None, "--state", help="Sprint state filter"),
1569
- sprint_name: str | None = typer.Option(None, "--name", help="Sprint name (for create/rename)"),
1570
- start_date: str | None = typer.Option(None, "--start-date", help="Start date (for create/rename)"),
1571
- end_date: str | None = typer.Option(None, "--end-date", help="End date (for create/rename)"),
1572
- goal: str | None = typer.Option(None, "--goal", help="Sprint goal (for create)"),
1573
- issues: str | None = typer.Option(None, "--issues", help="Comma-separated issue keys (for add-issues)"),
1574
- limit: int = typer.Option(50, "--limit", help="Number of results"),
1575
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1576
- ) -> None:
1577
- """Sprint operations."""
1578
- started_at = datetime.now(UTC)
1579
- code = 0
1580
- try:
1581
- s = load_settings(strict=True)
1582
- s.require_basic_or_token()
1583
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1584
-
1585
- if action == "list":
1586
- if not board_id:
1587
- raise typer.BadParameter("--board-id required")
1588
- payload = adapter.get_all_sprints_from_board(board_id, state=state, start=0, limit=limit) # type: ignore[arg-type]
1589
- _emit_json({"count": len(payload), "sprints": payload})
1590
- elif action == "issues":
1591
- if not board_id:
1592
- raise typer.BadParameter("--board-id required")
1593
- payload = adapter.get_all_issues_for_sprint_in_board(board_id, state=state, start=0, limit=limit) # type: ignore[arg-type]
1594
- _emit_json({"count": len(payload), "issues": payload})
1595
- elif action == "versions":
1596
- if not board_id:
1597
- raise typer.BadParameter("--board-id required")
1598
- payload = adapter.get_all_versions_from_board(board_id, start=0, limit=limit) # type: ignore[arg-type]
1599
- _emit_json({"count": len(payload), "versions": payload})
1600
- elif action == "create":
1601
- if not yes:
1602
- raise typer.BadParameter("Refusing to create without --yes")
1603
- if not sprint_name or not board_id:
1604
- raise typer.BadParameter("--name and --board-id required for create")
1605
- payload = adapter.create_sprint(
1606
- sprint_name,
1607
- board_id,
1608
- start_datetime=start_date,
1609
- end_datetime=end_date,
1610
- goal=goal, # type: ignore[arg-type]
1611
- )
1612
- _emit_json(payload)
1613
- elif action == "rename":
1614
- if not yes:
1615
- raise typer.BadParameter("Refusing to rename without --yes")
1616
- if not sprint_id:
1617
- raise typer.BadParameter("--sprint-id required")
1618
- payload = adapter.rename_sprint(sprint_id, name=sprint_name, start_date=start_date, end_date=end_date) # type: ignore[arg-type]
1619
- _emit_json(payload)
1620
- elif action == "add-issues":
1621
- if not yes:
1622
- raise typer.BadParameter("Refusing to add issues without --yes")
1623
- if not sprint_id or not issues:
1624
- raise typer.BadParameter("--sprint-id and --issues required")
1625
- issues_list = [i.strip() for i in issues.split(",")]
1626
- adapter.add_issues_to_sprint(sprint_id, issues_list) # type: ignore[arg-type]
1627
- _emit_json({"sprint_id": sprint_id, "issues_added": issues_list})
1628
- else:
1629
- raise typer.BadParameter(f"Unknown action: {action}")
1630
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1631
- code = 1
1632
- logger.error("sprint_failed %s", exc)
1633
- typer.echo(f"Error: {exc}", err=True)
1634
- finally:
1635
- finished_at = datetime.now(UTC)
1636
- _record_summary(
1637
- command="sprint",
1638
- args=[action, f"board_id={board_id}", f"sprint_id={sprint_id}"],
1639
- exit_code=code,
1640
- started_at=started_at,
1641
- finished_at=finished_at,
1642
- )
1643
- if code != 0:
1644
- raise typer.Exit(code=code) from None
1645
-
1646
-
1647
- @app.command("backlog")
1648
- def cmd_backlog(
1649
- action: str = typer.Argument(..., help="Action: move, add"),
1650
- issues: str = typer.Option(..., "--issues", help="Comma-separated issue keys"),
1651
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1652
- ) -> None:
1653
- """Backlog operations."""
1654
- started_at = datetime.now(UTC)
1655
- code = 0
1656
- try:
1657
- if not yes:
1658
- raise typer.BadParameter("Refusing to modify backlog without --yes")
1659
- s = load_settings(strict=True)
1660
- s.require_basic_or_token()
1661
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1662
- issues_list = [i.strip() for i in issues.split(",")]
1663
-
1664
- if action == "move":
1665
- adapter.move_issues_to_backlog(issues_list)
1666
- _emit_json({"action": "moved_to_backlog", "issues": issues_list})
1667
- elif action == "add":
1668
- adapter.add_issues_to_backlog(issues_list)
1669
- _emit_json({"action": "added_to_backlog", "issues": issues_list})
1670
- else:
1671
- raise typer.BadParameter(f"Unknown action: {action}")
1672
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1673
- code = 1
1674
- logger.error("backlog_failed %s", exc)
1675
- typer.echo(f"Error: {exc}", err=True)
1676
- finally:
1677
- finished_at = datetime.now(UTC)
1678
- _record_summary(
1679
- command="backlog",
1680
- args=[action, f"issues={issues}"],
1681
- exit_code=code,
1682
- started_at=started_at,
1683
- finished_at=finished_at,
1684
- )
1685
- if code != 0:
1686
- raise typer.Exit(code=code) from None
1687
-
1688
-
1689
- @app.command("worklog")
1690
- def cmd_worklog(
1691
- action: str = typer.Argument(..., help="Action: get, add, updated, deleted"),
1692
- issue_key: str | None = typer.Option(None, "--issue-key", help="Issue key (for get/add)"),
1693
- time_spent: str | None = typer.Option(None, "--time-spent", help="Time spent (e.g., '2h 30m') (for add)"),
1694
- comment: str | None = typer.Option(None, "--comment", help="Worklog comment (for add)"),
1695
- started: str | None = typer.Option(None, "--started", help="Start datetime in ISO format (for add)"),
1696
- time_sec: int | None = typer.Option(None, "--time-sec", help="Time in seconds (alternative to --time-spent)"),
1697
- since: str | None = typer.Option(None, "--since", help="Timestamp for updated/deleted (YYYY-MM-DD HH:mm or ISO)"),
1698
- expand: str | None = typer.Option(None, "--expand", help="Expand parameter (for updated)"),
1699
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1700
- ) -> None:
1701
- """Worklog operations."""
1702
- started_at = datetime.now(UTC)
1703
- code = 0
1704
- try:
1705
- s = load_settings(strict=True)
1706
- s.require_basic_or_token()
1707
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1708
-
1709
- if action == "get":
1710
- if not issue_key:
1711
- raise typer.BadParameter("--issue-key required for get")
1712
- payload = adapter.get_worklogs(issue_key)
1713
- _emit_json(payload)
1714
- elif action == "add":
1715
- if not yes:
1716
- raise typer.BadParameter("Refusing to add worklog without --yes")
1717
- if not issue_key:
1718
- raise typer.BadParameter("--issue-key required for add")
1719
- if not time_spent and time_sec is None:
1720
- raise typer.BadParameter("--time-spent or --time-sec required for add")
1721
- payload = adapter.issue_add_worklog(
1722
- issue_key=issue_key,
1723
- time_spent=time_spent or "",
1724
- comment=comment,
1725
- started=started,
1726
- time_sec=time_sec,
1727
- )
1728
- _emit_json(payload)
1729
- elif action == "updated":
1730
- if not since:
1731
- raise typer.BadParameter("--since required for updated")
1732
- payload = adapter.get_updated_worklogs(since, expand=expand)
1733
- _emit_json(payload)
1734
- elif action == "deleted":
1735
- if not since:
1736
- raise typer.BadParameter("--since required for deleted")
1737
- payload = adapter.get_deleted_worklogs(since)
1738
- _emit_json(payload)
1739
- else:
1740
- raise typer.BadParameter(f"Unknown action: {action}")
1741
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1742
- code = 1
1743
- logger.error("worklog_failed %s", exc)
1744
- typer.echo(f"Error: {exc}", err=True)
1745
- finally:
1746
- finished_at = datetime.now(UTC)
1747
- _record_summary(
1748
- command="worklog",
1749
- args=[action, f"issue_key={issue_key}", f"since={since}"],
1750
- exit_code=code,
1751
- started_at=started_at,
1752
- finished_at=finished_at,
1753
- )
1754
- if code != 0:
1755
- raise typer.Exit(code=code) from None
1756
-
1757
-
1758
- @app.command("transitions")
1759
- def cmd_transitions(
1760
- issue_key: str = typer.Argument(..., help="Issue key"),
1761
- ) -> None:
1762
- """Get available transitions for an issue."""
1763
- started_at = datetime.now(UTC)
1764
- code = 0
1765
- try:
1766
- s = load_settings(strict=True)
1767
- s.require_basic_or_token()
1768
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1769
-
1770
- payload = adapter.get_issue_transitions(issue_key)
1771
- _emit_json(payload)
1772
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1773
- code = 1
1774
- logger.error("transitions_failed %s", exc)
1775
- typer.echo(f"Error: {exc}", err=True)
1776
- finally:
1777
- finished_at = datetime.now(UTC)
1778
- _record_summary(
1779
- command="transitions",
1780
- args=[issue_key],
1781
- exit_code=code,
1782
- started_at=started_at,
1783
- finished_at=finished_at,
1784
- )
1785
- if code != 0:
1786
- raise typer.Exit(code=code) from None
1787
-
1788
-
1789
- @app.command("changelog")
1790
- def cmd_changelog(
1791
- action: str = typer.Argument(..., help="Action: get, status"),
1792
- issue_key: str = typer.Argument(..., help="Issue key"),
1793
- start: int | None = typer.Option(None, "--start", help="Start index for pagination"),
1794
- limit: int | None = typer.Option(None, "--limit", help="Limit for pagination"),
1795
- ) -> None:
1796
- """Get issue changelog (change history)."""
1797
- started_at = datetime.now(UTC)
1798
- code = 0
1799
- try:
1800
- s = load_settings(strict=True)
1801
- s.require_basic_or_token()
1802
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1803
-
1804
- if action == "get":
1805
- payload = adapter.get_issue_changelog(issue_key, start=start, limit=limit)
1806
- _emit_json(payload)
1807
- elif action == "status":
1808
- payload = adapter.get_issue_status_changelog(issue_key)
1809
- _emit_json(payload)
1810
- else:
1811
- raise typer.BadParameter(f"Unknown action: {action}")
1812
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1813
- code = 1
1814
- logger.error("changelog_failed %s", exc)
1815
- typer.echo(f"Error: {exc}", err=True)
1816
- finally:
1817
- finished_at = datetime.now(UTC)
1818
- _record_summary(
1819
- command="changelog",
1820
- args=[action, issue_key, f"start={start}", f"limit={limit}"],
1821
- exit_code=code,
1822
- started_at=started_at,
1823
- finished_at=finished_at,
1824
- )
1825
- if code != 0:
1826
- raise typer.Exit(code=code) from None
1827
-
1828
-
1829
- @app.command("filter")
1830
- def cmd_filter(
1831
- action: str = typer.Argument(..., help="Action: list, get, create, update, delete"),
1832
- filter_id: int | None = typer.Option(None, "--filter-id", help="Filter ID (for get, update, delete)"),
1833
- owner: str | None = typer.Option(None, "--owner", help="Owner username (for list)"),
1834
- name: str | None = typer.Option(None, "--name", help="Filter name (for create, update)"),
1835
- jql: str | None = typer.Option(None, "--jql", help="JQL query (for create, update)"),
1836
- description: str | None = typer.Option(None, "--description", help="Filter description (for create, update)"),
1837
- favourite: bool | None = typer.Option(
1838
- None, "--favourite/--no-favourite", help="Mark as favourite (for create, update)"
1839
- ),
1840
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation (for create, update, delete)"),
1841
- ) -> None:
1842
- """Filter management operations."""
1843
- started_at = datetime.now(UTC)
1844
- code = 0
1845
- try:
1846
- s = load_settings(strict=True)
1847
- s.require_basic_or_token()
1848
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1849
-
1850
- if action == "list":
1851
- payload = adapter.get_filters(owner=owner)
1852
- _emit_json({"filters": payload, "count": len(payload)})
1853
- elif action == "get":
1854
- if not filter_id:
1855
- raise typer.BadParameter("--filter-id required for get")
1856
- payload = adapter.get_filter(filter_id)
1857
- _emit_json(payload)
1858
- elif action == "create":
1859
- if not yes:
1860
- raise typer.BadParameter("Refusing to create filter without --yes")
1861
- if not name:
1862
- raise typer.BadParameter("--name required for create")
1863
- if not jql:
1864
- raise typer.BadParameter("--jql required for create")
1865
- payload = adapter.create_filter(
1866
- name=name, jql=jql, description=description, favourite=favourite if favourite is not None else False
1867
- )
1868
- _emit_json(payload)
1869
- elif action == "update":
1870
- if not yes:
1871
- raise typer.BadParameter("Refusing to update filter without --yes")
1872
- if not filter_id:
1873
- raise typer.BadParameter("--filter-id required for update")
1874
- if not (name or jql or description is not None or favourite is not None):
1875
- raise typer.BadParameter(
1876
- "At least one of --name, --jql, --description, or --favourite must be provided for update"
1877
- )
1878
- payload = adapter.update_filter(
1879
- filter_id=filter_id, name=name, jql=jql, description=description, favourite=favourite
1880
- )
1881
- _emit_json(payload)
1882
- elif action == "delete":
1883
- if not yes:
1884
- raise typer.BadParameter("Refusing to delete filter without --yes")
1885
- if not filter_id:
1886
- raise typer.BadParameter("--filter-id required for delete")
1887
- adapter.delete_filter(filter_id)
1888
- _emit_json({"status": "success", "filter_id": filter_id, "message": "Filter deleted"})
1889
- else:
1890
- raise typer.BadParameter(f"Unknown action: {action}")
1891
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1892
- code = 1
1893
- logger.error("filter_failed %s", exc)
1894
- typer.echo(f"Error: {exc}", err=True)
1895
- finally:
1896
- finished_at = datetime.now(UTC)
1897
- args_list: list[str] = [action]
1898
- if filter_id:
1899
- args_list.append(f"filter_id={filter_id}")
1900
- if owner:
1901
- args_list.append(f"owner={owner}")
1902
- if name:
1903
- args_list.append(f"name={name}")
1904
- if jql:
1905
- args_list.append(f"jql={jql}")
1906
- if description:
1907
- args_list.append(f"description={description}")
1908
- if favourite is not None:
1909
- args_list.append(f"favourite={favourite}")
1910
- _record_summary(
1911
- command="filter",
1912
- args=args_list,
1913
- exit_code=code,
1914
- started_at=started_at,
1915
- finished_at=finished_at,
1916
- )
1917
- if code != 0:
1918
- raise typer.Exit(code=code) from None
1919
-
1920
-
1921
- @app.command("dashboard")
1922
- def cmd_dashboard(
1923
- action: str = typer.Argument(..., help="Action: get, list"),
1924
- dashboard_id: str | None = typer.Option(None, "--dashboard-id", help="Dashboard ID (for get)"),
1925
- filter_str: str | None = typer.Option(None, "--filter", help="Filter string (for list)"),
1926
- start: int = typer.Option(0, "--start", help="Start index for pagination (for list)"),
1927
- limit: int = typer.Option(10, "--limit", help="Limit for pagination (for list)"),
1928
- ) -> None:
1929
- """Dashboard operations."""
1930
- started_at = datetime.now(UTC)
1931
- code = 0
1932
- try:
1933
- s = load_settings(strict=True)
1934
- s.require_basic_or_token()
1935
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1936
-
1937
- if action == "get":
1938
- if not dashboard_id:
1939
- raise typer.BadParameter("--dashboard-id required for get")
1940
- # Try to parse as int, otherwise use as string
1941
- try:
1942
- dashboard_id_int = int(dashboard_id)
1943
- payload = adapter.get_dashboard(dashboard_id_int)
1944
- except ValueError:
1945
- payload = adapter.get_dashboard(dashboard_id)
1946
- _emit_json(payload)
1947
- elif action == "list":
1948
- payload = adapter.get_dashboards(filter=filter_str or "", start=start, limit=limit)
1949
- _emit_json(payload)
1950
- else:
1951
- raise typer.BadParameter(f"Unknown action: {action}")
1952
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
1953
- code = 1
1954
- logger.error("dashboard_failed %s", exc)
1955
- typer.echo(f"Error: {exc}", err=True)
1956
- finally:
1957
- finished_at = datetime.now(UTC)
1958
- _record_summary(
1959
- command="dashboard",
1960
- args=[action, f"dashboard_id={dashboard_id}", f"filter={filter_str}", f"start={start}", f"limit={limit}"],
1961
- exit_code=code,
1962
- started_at=started_at,
1963
- finished_at=finished_at,
1964
- )
1965
- if code != 0:
1966
- raise typer.Exit(code=code) from None
1967
-
1968
-
1969
- @app.command("issue-link")
1970
- def cmd_issue_link(
1971
- action: str = typer.Argument(..., help="Action: create, delete"),
1972
- link_type: str | None = typer.Option(None, "--type", help="Issue link type name (e.g., Blocks)"),
1973
- inward_issue: str | None = typer.Option(
1974
- None, "--inward-issue", help="Inward issue key (the issue being blocked/related)"
1975
- ),
1976
- outward_issue: str | None = typer.Option(
1977
- None, "--outward-issue", help="Outward issue key (the issue that blocks/relates)"
1978
- ),
1979
- link_id: str | None = typer.Option(None, "--link-id", help="Issue link ID (required for delete)"),
1980
- comment: str | None = typer.Option(None, "--comment", help="Optional comment for the created link"),
1981
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
1982
- dry_run: bool = typer.Option(False, "--dry-run", help="Validate payload without sending"),
1983
- ) -> None:
1984
- """Issue-to-issue link operations."""
1985
- started_at = datetime.now(UTC)
1986
- code = 0
1987
- try:
1988
- s = load_settings(strict=True)
1989
- s.require_basic_or_token()
1990
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
1991
-
1992
- if action == "create":
1993
- if not yes and not dry_run:
1994
- raise typer.BadParameter("--yes required for create (or use --dry-run)")
1995
- if not link_type:
1996
- raise typer.BadParameter("--type required for create")
1997
- if not inward_issue:
1998
- raise typer.BadParameter("--inward-issue required for create")
1999
- if not outward_issue:
2000
- raise typer.BadParameter("--outward-issue required for create")
2001
-
2002
- # Atlassian semantics for "Blocks":
2003
- # - inwardIssue: issue on the "is blocked by" side (the blocker)
2004
- # - outwardIssue: issue on the "blocks" side (the blocked issue)
2005
- payload: dict[str, Any] = {
2006
- "type": {"name": link_type},
2007
- "inwardIssue": {"key": outward_issue},
2008
- "outwardIssue": {"key": inward_issue},
2009
- }
2010
- if comment:
2011
- payload["comment"] = {"body": comment}
2012
-
2013
- if dry_run and not yes:
2014
- _emit_json({"dry_run": True, "request": payload})
2015
- else:
2016
- result = adapter.create_issue_link(payload)
2017
- _emit_json(
2018
- {
2019
- "status": "created",
2020
- "type": link_type,
2021
- "inward_issue": inward_issue,
2022
- "outward_issue": outward_issue,
2023
- "result": result,
2024
- }
2025
- )
2026
- elif action == "delete":
2027
- if not yes and not dry_run:
2028
- raise typer.BadParameter("--yes required for delete (or use --dry-run)")
2029
- if not link_id:
2030
- raise typer.BadParameter("--link-id required for delete")
2031
-
2032
- parsed_link_id: str | int
2033
- try:
2034
- parsed_link_id = int(link_id)
2035
- except ValueError:
2036
- parsed_link_id = link_id
2037
-
2038
- if dry_run and not yes:
2039
- _emit_json({"dry_run": True, "request": {"action": "delete", "link_id": parsed_link_id}})
2040
- else:
2041
- adapter.remove_issue_link(parsed_link_id)
2042
- _emit_json({"status": "deleted", "link_id": parsed_link_id})
2043
- else:
2044
- raise typer.BadParameter(f"Unknown action: {action}")
2045
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2046
- code = 1
2047
- logger.error("issue_link_failed %s", exc)
2048
- typer.echo(f"Error: {exc}", err=True)
2049
- finally:
2050
- finished_at = datetime.now(UTC)
2051
- _record_summary(
2052
- command="issue-link",
2053
- args=[
2054
- action,
2055
- f"type={link_type}",
2056
- f"inward_issue={inward_issue}",
2057
- f"outward_issue={outward_issue}",
2058
- f"link_id={link_id}",
2059
- f"comment={comment}",
2060
- f"yes={yes}",
2061
- f"dry_run={dry_run}",
2062
- ],
2063
- exit_code=code,
2064
- started_at=started_at,
2065
- finished_at=finished_at,
2066
- )
2067
- if code != 0:
2068
- raise typer.Exit(code=code) from None
2069
-
2070
-
2071
- @app.command("link-type")
2072
- def cmd_link_type(
2073
- action: str = typer.Argument(..., help="Action: list, get, create, update, delete"),
2074
- link_type_id: str | None = typer.Option(None, "--link-type-id", help="Link type ID (for get, update, delete)"),
2075
- name: str | None = typer.Option(None, "--name", help="Link type name (for create, update)"),
2076
- inward: str | None = typer.Option(None, "--inward", help="Inward description (for create, update)"),
2077
- outward: str | None = typer.Option(None, "--outward", help="Outward description (for create, update)"),
2078
- data_file: Path | None = typer.Option(
2079
- None, "--data-file", help="JSON file with link type data (for create, update)"
2080
- ),
2081
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation (for create, update, delete)"),
2082
- ) -> None:
2083
- """Issue link type operations."""
2084
- started_at = datetime.now(UTC)
2085
- code = 0
2086
- try:
2087
- s = load_settings(strict=True)
2088
- s.require_basic_or_token()
2089
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2090
-
2091
- if action == "list":
2092
- payload = adapter.get_issue_link_types()
2093
- _emit_json({"count": len(payload), "link_types": payload})
2094
- elif action == "get":
2095
- if not link_type_id:
2096
- raise typer.BadParameter("--link-type-id required for get")
2097
- payload = adapter.get_issue_link_type(link_type_id)
2098
- _emit_json(payload)
2099
- elif action == "create":
2100
- if not yes:
2101
- raise typer.BadParameter("Refusing to create link type without --yes")
2102
- if data_file:
2103
- if not data_file.exists():
2104
- raise typer.BadParameter(f"Data file not found: {data_file}")
2105
- with data_file.open() as f:
2106
- data = json.load(f)
2107
- else:
2108
- if not name or not inward or not outward:
2109
- raise typer.BadParameter("--name, --inward, and --outward required for create (or use --data-file)")
2110
- data = {"name": name, "inward": inward, "outward": outward}
2111
- payload = adapter.create_issue_link_type(data)
2112
- _emit_json(payload)
2113
- elif action == "update":
2114
- if not yes:
2115
- raise typer.BadParameter("Refusing to update link type without --yes")
2116
- if not link_type_id:
2117
- raise typer.BadParameter("--link-type-id required for update")
2118
- if data_file:
2119
- if not data_file.exists():
2120
- raise typer.BadParameter(f"Data file not found: {data_file}")
2121
- with data_file.open() as f:
2122
- data = json.load(f)
2123
- else:
2124
- if not name or not inward or not outward:
2125
- raise typer.BadParameter("--name, --inward, and --outward required for update (or use --data-file)")
2126
- data = {"name": name, "inward": inward, "outward": outward}
2127
- payload = adapter.update_issue_link_type(link_type_id, data)
2128
- _emit_json(payload)
2129
- elif action == "delete":
2130
- if not yes:
2131
- raise typer.BadParameter("Refusing to delete link type without --yes")
2132
- if not link_type_id:
2133
- raise typer.BadParameter("--link-type-id required for delete")
2134
- adapter.delete_issue_link_type(link_type_id)
2135
- _emit_json({"status": "deleted", "link_type_id": link_type_id})
2136
- else:
2137
- raise typer.BadParameter(f"Unknown action: {action}")
2138
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2139
- code = 1
2140
- logger.error("link_type_failed %s", exc)
2141
- typer.echo(f"Error: {exc}", err=True)
2142
- finally:
2143
- finished_at = datetime.now(UTC)
2144
- _record_summary(
2145
- command="link-type",
2146
- args=[
2147
- action,
2148
- f"link_type_id={link_type_id}",
2149
- f"name={name}",
2150
- f"inward={inward}",
2151
- f"outward={outward}",
2152
- f"data_file={data_file}",
2153
- f"yes={yes}",
2154
- ],
2155
- exit_code=code,
2156
- started_at=started_at,
2157
- finished_at=finished_at,
2158
- )
2159
- if code != 0:
2160
- raise typer.Exit(code=code) from None
2161
-
2162
-
2163
- @app.command("remote-link")
2164
- def cmd_remote_link(
2165
- action: str = typer.Argument(..., help="Action: list, get, create, update, delete"),
2166
- issue_key: str = typer.Option(..., "--issue-key", "-k", help="Issue key (e.g., NTTC-123)"),
2167
- remote_link_id: str | None = typer.Option(
2168
- None, "--remote-link-id", "-r", help="Remote link ID (for get/update/delete)"
2169
- ),
2170
- url: str | None = typer.Option(None, "--url", help="Remote link target URL (for create/update)"),
2171
- title: str | None = typer.Option(None, "--title", help="Remote link title"),
2172
- summary: str | None = typer.Option(None, "--summary", help="Remote link summary/description"),
2173
- relationship: str | None = typer.Option(None, "--relationship", help="Relationship description"),
2174
- global_id: str | None = typer.Option(None, "--global-id", help="Global ID for remote link"),
2175
- application_type: str | None = typer.Option(None, "--application-type", help="Application type for remote link"),
2176
- application_name: str | None = typer.Option(None, "--application-name", help="Application name for remote link"),
2177
- icon_url: str | None = typer.Option(None, "--icon-url", help="Icon URL for the remote link object"),
2178
- icon_title: str | None = typer.Option(None, "--icon-title", help="Icon title for the remote link object"),
2179
- data_file: Path | None = typer.Option(None, "--data-file", help="JSON file describing the remote link payload"),
2180
- yes: bool = typer.Option(False, "--yes", help="Confirm write operations (create/update/delete)"),
2181
- ) -> None:
2182
- """Manage Jira issue remote links."""
2183
- started_at = datetime.now(UTC)
2184
- code = 0
2185
- summary_args: list[str] = [
2186
- action,
2187
- f"issue={issue_key}",
2188
- f"remote_link_id={remote_link_id}",
2189
- f"data_file={data_file}",
2190
- ]
2191
-
2192
- def _parse_remote_link_identifier(value: str | None) -> str | int | None:
2193
- if value is None:
2194
- return None
2195
- try:
2196
- return int(value)
2197
- except ValueError:
2198
- return value
2199
-
2200
- try:
2201
- s = load_settings(strict=True)
2202
- s.require_basic_or_token()
2203
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2204
-
2205
- if action == "list":
2206
- payload = adapter.get_issue_remote_links(issue_key)
2207
- _emit_json({"count": len(payload), "remote_links": payload})
2208
-
2209
- elif action == "get":
2210
- remote_id = _parse_remote_link_identifier(remote_link_id)
2211
- if remote_id is None:
2212
- raise typer.BadParameter("--remote-link-id required for get")
2213
- payload = adapter.get_issue_remote_link_by_id(issue_key, remote_id)
2214
- _emit_json(payload)
2215
-
2216
- elif action == "create":
2217
- if not yes:
2218
- raise typer.BadParameter("--yes required for create")
2219
- payload_data = _build_remote_link_payload(
2220
- url=url,
2221
- title=title,
2222
- summary=summary,
2223
- relationship=relationship,
2224
- global_id=global_id,
2225
- application_type=application_type,
2226
- application_name=application_name,
2227
- icon_url=icon_url,
2228
- icon_title=icon_title,
2229
- data_file=data_file,
2230
- )
2231
- result = adapter.create_or_update_issue_remote_link(issue_key, payload_data)
2232
- _emit_json(result)
2233
-
2234
- elif action == "update":
2235
- if not yes:
2236
- raise typer.BadParameter("--yes required for update")
2237
- remote_id = _parse_remote_link_identifier(remote_link_id)
2238
- if remote_id is None:
2239
- raise typer.BadParameter("--remote-link-id required for update")
2240
- payload_data = _build_remote_link_payload(
2241
- url=url,
2242
- title=title,
2243
- summary=summary,
2244
- relationship=relationship,
2245
- global_id=global_id,
2246
- application_type=application_type,
2247
- application_name=application_name,
2248
- icon_url=icon_url,
2249
- icon_title=icon_title,
2250
- data_file=data_file,
2251
- )
2252
- result = adapter.update_issue_remote_link_by_id(issue_key, remote_id, payload_data)
2253
- _emit_json(result)
2254
-
2255
- elif action == "delete":
2256
- if not yes:
2257
- raise typer.BadParameter("--yes required for delete")
2258
- remote_id = _parse_remote_link_identifier(remote_link_id)
2259
- if remote_id is None:
2260
- raise typer.BadParameter("--remote-link-id required for delete")
2261
- adapter.delete_issue_remote_link_by_id(issue_key, remote_id)
2262
- _emit_json({"status": "deleted", "issue": issue_key, "remote_link_id": remote_id})
2263
-
2264
- else:
2265
- raise typer.BadParameter(f"Unknown action: {action}")
2266
-
2267
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2268
- code = 1
2269
- logger.error("remote_link_command_failed %s", exc)
2270
- typer.echo(f"Error: {exc}", err=True)
2271
- finally:
2272
- finished_at = datetime.now(UTC)
2273
- _record_summary(
2274
- command="remote-link",
2275
- args=summary_args,
2276
- exit_code=code,
2277
- started_at=started_at,
2278
- finished_at=finished_at,
2279
- )
2280
- if code != 0:
2281
- raise typer.Exit(code=code) from None
2282
-
2283
-
2284
- @app.command("issue-property")
2285
- def cmd_issue_property(
2286
- action: str = typer.Argument(..., help="Action: list, get, set, delete"),
2287
- issue_key: str = typer.Option(..., "--issue-key", "-k", help="Issue key (e.g., NTTC-123)"),
2288
- property_key: str | None = typer.Option(
2289
- None, "--property-key", "-p", help="Property key (required for get/set/delete)"
2290
- ),
2291
- data_file: Path | None = typer.Option(None, "--data-file", help="JSON file containing property value (for set)"),
2292
- value: str | None = typer.Option(None, "--value", help="JSON string value (for set when no file provided)"),
2293
- yes: bool = typer.Option(False, "--yes", help="Confirm write operations (set/delete)"),
2294
- ) -> None:
2295
- """Manage Jira issue properties."""
2296
- started_at = datetime.now(UTC)
2297
- code = 0
2298
- summary_args = [
2299
- action,
2300
- f"issue={issue_key}",
2301
- f"property_key={property_key}",
2302
- f"data_file={data_file}",
2303
- ]
2304
-
2305
- def _load_value() -> dict[str, Any]:
2306
- if data_file:
2307
- if not data_file.exists():
2308
- raise typer.BadParameter(f"Data file not found: {data_file}")
2309
- try:
2310
- return json.loads(data_file.read_text())
2311
- except json.JSONDecodeError as exc:
2312
- raise typer.BadParameter(f"Invalid JSON in {data_file}: {exc}") from exc
2313
- if value is None:
2314
- raise typer.BadParameter("Provide --value or --data-file for set action")
2315
- try:
2316
- parsed = json.loads(value)
2317
- except json.JSONDecodeError as exc:
2318
- raise typer.BadParameter(f"Invalid JSON for --value: {exc}") from exc
2319
- if not isinstance(parsed, dict):
2320
- raise typer.BadParameter("--value must decode to a JSON object")
2321
- return parsed
2322
-
2323
- try:
2324
- s = load_settings(strict=True)
2325
- s.require_basic_or_token()
2326
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2327
-
2328
- if action == "list":
2329
- payload = adapter.get_issue_property_keys(issue_key)
2330
- _emit_json(payload)
2331
-
2332
- elif action == "get":
2333
- if not property_key:
2334
- raise typer.BadParameter("--property-key required for get")
2335
- payload = adapter.get_issue_property(issue_key, property_key)
2336
- _emit_json(payload)
2337
-
2338
- elif action == "set":
2339
- if not yes:
2340
- raise typer.BadParameter("--yes required for set")
2341
- if not property_key:
2342
- raise typer.BadParameter("--property-key required for set")
2343
- payload = _load_value()
2344
- adapter.set_issue_property(issue_key, property_key, payload)
2345
- _emit_json({"status": "updated", "issue": issue_key, "property_key": property_key})
2346
-
2347
- elif action == "delete":
2348
- if not yes:
2349
- raise typer.BadParameter("--yes required for delete")
2350
- if not property_key:
2351
- raise typer.BadParameter("--property-key required for delete")
2352
- adapter.delete_issue_property(issue_key, property_key)
2353
- _emit_json({"status": "deleted", "issue": issue_key, "property_key": property_key})
2354
-
2355
- else:
2356
- raise typer.BadParameter(f"Unknown action: {action}")
2357
-
2358
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2359
- code = 1
2360
- logger.error("issue_property_command_failed %s", exc)
2361
- typer.echo(f"Error: {exc}", err=True)
2362
- finally:
2363
- finished_at = datetime.now(UTC)
2364
- _record_summary(
2365
- command="issue-property",
2366
- args=summary_args,
2367
- exit_code=code,
2368
- started_at=started_at,
2369
- finished_at=finished_at,
2370
- )
2371
- if code != 0:
2372
- raise typer.Exit(code=code) from None
2373
-
2374
-
2375
- @app.command("watcher")
2376
- def cmd_watcher(
2377
- action: str = typer.Argument(..., help="Action: list, add, remove"),
2378
- issue_key: str = typer.Option(..., "--issue-key", "-k", help="Issue key (e.g., NTTC-123)"),
2379
- account: str | None = typer.Option(
2380
- None,
2381
- "--account",
2382
- "-a",
2383
- help="Username or accountId (required for add/remove)",
2384
- ),
2385
- yes: bool = typer.Option(False, "--yes", help="Confirm write operations (add/remove)"),
2386
- ) -> None:
2387
- """Manage issue watchers."""
2388
- started_at = datetime.now(UTC)
2389
- code = 0
2390
- summary_args = [action, f"issue={issue_key}", f"account={account}"]
2391
-
2392
- try:
2393
- s = load_settings(strict=True)
2394
- s.require_basic_or_token()
2395
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2396
-
2397
- if action == "list":
2398
- payload = adapter.issue_get_watchers(issue_key)
2399
- _emit_json(payload)
2400
-
2401
- elif action == "add":
2402
- if not yes:
2403
- raise typer.BadParameter("--yes required for add")
2404
- if not account:
2405
- raise typer.BadParameter("--account required for add")
2406
- adapter.issue_add_watcher(issue_key, account)
2407
- _emit_json({"status": "added", "issue": issue_key, "account": account})
2408
-
2409
- elif action == "remove":
2410
- if not yes:
2411
- raise typer.BadParameter("--yes required for remove")
2412
- if not account:
2413
- raise typer.BadParameter("--account required for remove")
2414
- adapter.issue_delete_watcher(issue_key, account)
2415
- _emit_json({"status": "removed", "issue": issue_key, "account": account})
2416
-
2417
- else:
2418
- raise typer.BadParameter(f"Unknown action: {action}")
2419
-
2420
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2421
- code = 1
2422
- logger.error("watcher_command_failed %s", exc)
2423
- typer.echo(f"Error: {exc}", err=True)
2424
- finally:
2425
- finished_at = datetime.now(UTC)
2426
- _record_summary(
2427
- command="watcher",
2428
- args=summary_args,
2429
- exit_code=code,
2430
- started_at=started_at,
2431
- finished_at=finished_at,
2432
- )
2433
- if code != 0:
2434
- raise typer.Exit(code=code) from None
2435
-
2436
-
2437
- @app.command("security-scheme")
2438
- def cmd_security_scheme(
2439
- action: str = typer.Argument(..., help="Action: list, get"),
2440
- scheme_id: str | None = typer.Option(None, "--scheme-id", help="Scheme ID (for get)"),
2441
- only_levels: bool = typer.Option(False, "--only-levels", help="Return only security levels (for get)"),
2442
- ) -> None:
2443
- """Issue security scheme operations."""
2444
- started_at = datetime.now(UTC)
2445
- code = 0
2446
- try:
2447
- s = load_settings(strict=True)
2448
- s.require_basic_or_token()
2449
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2450
-
2451
- if action == "list":
2452
- payload = adapter.get_issue_security_schemes()
2453
- _emit_json({"count": len(payload), "security_schemes": payload})
2454
- elif action == "get":
2455
- if not scheme_id:
2456
- raise typer.BadParameter("--scheme-id required for get")
2457
- payload = adapter.get_issue_security_scheme(scheme_id, only_levels=only_levels)
2458
- _emit_json(payload)
2459
- else:
2460
- raise typer.BadParameter(f"Unknown action: {action}")
2461
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2462
- code = 1
2463
- logger.error("security_scheme_failed %s", exc)
2464
- typer.echo(f"Error: {exc}", err=True)
2465
- finally:
2466
- finished_at = datetime.now(UTC)
2467
- _record_summary(
2468
- command="security-scheme",
2469
- args=[action, f"scheme_id={scheme_id}", f"only_levels={only_levels}"],
2470
- exit_code=code,
2471
- started_at=started_at,
2472
- finished_at=finished_at,
2473
- )
2474
- if code != 0:
2475
- raise typer.Exit(code=code) from None
2476
-
2477
-
2478
- @app.command("permissions")
2479
- def cmd_permissions(
2480
- action: str = typer.Argument(..., help="Action: all, check"),
2481
- permissions: str | None = typer.Option(None, "--permissions", help="Comma-separated permission names (for check)"),
2482
- project_key: str | None = typer.Option(None, "--project-key", help="Project key (for check)"),
2483
- issue_key: str | None = typer.Option(None, "--issue-key", help="Issue key (for check)"),
2484
- ) -> None:
2485
- """Permission operations."""
2486
- started_at = datetime.now(UTC)
2487
- code = 0
2488
- try:
2489
- s = load_settings(strict=True)
2490
- s.require_basic_or_token()
2491
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2492
-
2493
- if action == "all":
2494
- payload = adapter.get_all_permissions()
2495
- _emit_json({"count": len(payload), "permissions": payload})
2496
- elif action == "check":
2497
- if not permissions:
2498
- raise typer.BadParameter("--permissions required for check")
2499
- perms_list = [p.strip() for p in permissions.split(",")]
2500
- payload = adapter.get_permissions(
2501
- permissions=perms_list,
2502
- project_key=project_key,
2503
- issue_key=issue_key,
2504
- )
2505
- _emit_json(payload)
2506
- else:
2507
- raise typer.BadParameter(f"Unknown action: {action}")
2508
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2509
- code = 1
2510
- logger.error("permissions_failed %s", exc)
2511
- typer.echo(f"Error: {exc}", err=True)
2512
- finally:
2513
- finished_at = datetime.now(UTC)
2514
- _record_summary(
2515
- command="permissions",
2516
- args=[action, f"permissions={permissions}", f"project_key={project_key}", f"issue_key={issue_key}"],
2517
- exit_code=code,
2518
- started_at=started_at,
2519
- finished_at=finished_at,
2520
- )
2521
- if code != 0:
2522
- raise typer.Exit(code=code) from None
2523
-
2524
-
2525
- @app.command("permission-scheme")
2526
- def cmd_permission_scheme(
2527
- project_key: str = typer.Argument(..., help="Project key"),
2528
- expand: str | None = typer.Option(None, "--expand", help="Expand options (comma-separated)"),
2529
- ) -> None:
2530
- """Get project permission scheme."""
2531
- started_at = datetime.now(UTC)
2532
- code = 0
2533
- try:
2534
- s = load_settings(strict=True)
2535
- s.require_basic_or_token()
2536
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2537
- payload = adapter.get_project_permission_scheme(project_key, expand=expand)
2538
- _emit_json(payload)
2539
- except (AuthError, VDSClientError) as exc:
2540
- code = 1
2541
- logger.error("permission_scheme_failed %s", exc)
2542
- typer.echo(f"Error: {exc}", err=True)
2543
- finally:
2544
- finished_at = datetime.now(UTC)
2545
- _record_summary(
2546
- command="permission-scheme",
2547
- args=[project_key, f"expand={expand}"],
2548
- exit_code=code,
2549
- started_at=started_at,
2550
- finished_at=finished_at,
2551
- )
2552
- if code != 0:
2553
- raise typer.Exit(code=code) from None
2554
-
2555
-
2556
- @app.command("issue-security-scheme")
2557
- def cmd_issue_security_scheme(
2558
- project_key: str = typer.Argument(..., help="Project key"),
2559
- only_levels: bool = typer.Option(False, "--only-levels", help="Return only security levels"),
2560
- ) -> None:
2561
- """Get project issue security scheme."""
2562
- started_at = datetime.now(UTC)
2563
- code = 0
2564
- try:
2565
- s = load_settings(strict=True)
2566
- s.require_basic_or_token()
2567
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2568
- payload = adapter.get_project_issue_security_scheme(project_key, only_levels=only_levels)
2569
- _emit_json(payload)
2570
- except (AuthError, VDSClientError) as exc:
2571
- code = 1
2572
- logger.error("issue_security_scheme_failed %s", exc)
2573
- typer.echo(f"Error: {exc}", err=True)
2574
- finally:
2575
- finished_at = datetime.now(UTC)
2576
- _record_summary(
2577
- command="issue-security-scheme",
2578
- args=[project_key, f"only_levels={only_levels}"],
2579
- exit_code=code,
2580
- started_at=started_at,
2581
- finished_at=finished_at,
2582
- )
2583
- if code != 0:
2584
- raise typer.Exit(code=code) from None
2585
-
2586
-
2587
- @app.command("reindex")
2588
- def cmd_reindex(
2589
- action: str = typer.Argument(..., help="Action: start, status, with-type"),
2590
- reindex_type: str | None = typer.Option(None, "--type", help="Reindex type (for with-type)"),
2591
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation"),
2592
- ) -> None:
2593
- """Reindex operations."""
2594
- started_at = datetime.now(UTC)
2595
- code = 0
2596
- try:
2597
- s = load_settings(strict=True)
2598
- s.require_basic_or_token()
2599
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2600
-
2601
- if action == "start":
2602
- if not yes:
2603
- raise typer.BadParameter("Refusing to start reindex without --yes")
2604
- payload = adapter.reindex()
2605
- _emit_json(payload)
2606
- elif action == "status":
2607
- payload = adapter.reindex_status()
2608
- _emit_json(payload)
2609
- elif action == "with-type":
2610
- if not yes:
2611
- raise typer.BadParameter("Refusing to reindex without --yes")
2612
- if not reindex_type:
2613
- raise typer.BadParameter("--type required for with-type")
2614
- payload = adapter.reindex_with_type(reindex_type)
2615
- _emit_json(payload)
2616
- else:
2617
- raise typer.BadParameter(f"Unknown action: {action}")
2618
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2619
- code = 1
2620
- logger.error("reindex_failed %s", exc)
2621
- typer.echo(f"Error: {exc}", err=True)
2622
- finally:
2623
- finished_at = datetime.now(UTC)
2624
- _record_summary(
2625
- command="reindex",
2626
- args=[action, f"type={reindex_type}"],
2627
- exit_code=code,
2628
- started_at=started_at,
2629
- finished_at=finished_at,
2630
- )
2631
- if code != 0:
2632
- raise typer.Exit(code=code) from None
2633
-
2634
-
2635
- @app.command("user")
2636
- def cmd_user(
2637
- action: str = typer.Argument(..., help="Action: search, groups, deactivate"),
2638
- query: str | None = typer.Option(None, "--query", help="Search query (for search)"),
2639
- account_id: str | None = typer.Option(None, "--account-id", help="Account ID (for groups)"),
2640
- username: str | None = typer.Option(None, "--username", help="Username (for deactivate)"),
2641
- start: int = typer.Option(0, "--start", help="Start index for pagination (for search)"),
2642
- limit: int = typer.Option(50, "--limit", help="Limit for pagination (for search)"),
2643
- include_inactive: bool = typer.Option(False, "--include-inactive", help="Include inactive users (for search)"),
2644
- yes: bool = typer.Option(False, "--yes", help="Confirm write operation (for deactivate)"),
2645
- ) -> None:
2646
- """User management operations."""
2647
- started_at = datetime.now(UTC)
2648
- code = 0
2649
- try:
2650
- s = load_settings(strict=True)
2651
- s.require_basic_or_token()
2652
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2653
-
2654
- if action == "search":
2655
- if not query:
2656
- raise typer.BadParameter("--query required for search")
2657
- payload = adapter.find_users(query=query, start=start, limit=limit, include_inactive=include_inactive)
2658
- _emit_json({"count": len(payload), "users": payload})
2659
- elif action == "groups":
2660
- if not account_id:
2661
- raise typer.BadParameter("--account-id required for groups")
2662
- payload = adapter.get_user_groups(account_id)
2663
- _emit_json({"count": len(payload), "groups": payload})
2664
- elif action == "deactivate":
2665
- if not yes:
2666
- raise typer.BadParameter("Refusing to deactivate user without --yes")
2667
- if not username:
2668
- raise typer.BadParameter("--username required for deactivate")
2669
- adapter.deactivate_user(username)
2670
- _emit_json({"status": "deactivated", "username": username})
2671
- else:
2672
- raise typer.BadParameter(f"Unknown action: {action}")
2673
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2674
- code = 1
2675
- logger.error("user_failed %s", exc)
2676
- typer.echo(f"Error: {exc}", err=True)
2677
- finally:
2678
- finished_at = datetime.now(UTC)
2679
- _record_summary(
2680
- command="user",
2681
- args=[
2682
- action,
2683
- f"query={query}",
2684
- f"account_id={account_id}",
2685
- f"username={username}",
2686
- f"start={start}",
2687
- f"limit={limit}",
2688
- f"include_inactive={include_inactive}",
2689
- f"yes={yes}",
2690
- ],
2691
- exit_code=code,
2692
- started_at=started_at,
2693
- finished_at=finished_at,
2694
- )
2695
- if code != 0:
2696
- raise typer.Exit(code=code) from None
2697
-
2698
-
2699
- if __name__ == "__main__":
2700
- app()
2701
-
2702
-
2703
- @app.command("discover-fields")
2704
- def cmd_discover_fields(
2705
- project: str = typer.Option(..., "--project", help="Project key"),
2706
- issuetype: str = typer.Option(..., "--issuetype", help="Issue type name (e.g., Task, Bug)"),
2707
- field: str | None = typer.Option(
2708
- None, "--field", help="Optional: Filter by field name or ID (case-insensitive substring)"
2709
- ),
2710
- include_system: bool = typer.Option(False, "--include-system", help="Include system (non-custom) fields"),
2711
- issue_key: str | None = typer.Option(
2712
- None, "--issue-key", help="Issue key for editmeta fallback when createmeta is unavailable"
2713
- ),
2714
- ) -> None:
2715
- """Discover custom fields (default), requirements, and allowed values for a project/issuetype."""
2716
- started_at = datetime.now(UTC)
2717
- code = 0
2718
- try:
2719
- s = load_settings(strict=True)
2720
- s.require_basic_or_token()
2721
- adapter = JiraAdapter(url=str(s.base_url), username=s.username, password=s.password, token=s.token, proxy_url=s.proxy_url)
2722
-
2723
- raw_fields: dict[str, Any] | None = None
2724
- editmeta_fields: dict[str, Any] | None = None
2725
- createmeta_error: Exception | None = None
2726
-
2727
- try:
2728
- meta = adapter.get_createmeta(project_key=project, issuetype=issuetype)
2729
- raw_fields = _extract_createmeta_fields(meta, project, issuetype)
2730
- except (VDSClientError, typer.BadParameter) as exc:
2731
- createmeta_error = exc
2732
-
2733
- if issue_key:
2734
- try:
2735
- editmeta = adapter.get_editmeta(issue_key)
2736
- editmeta_fields = editmeta.get("fields", {})
2737
- except VDSClientError as exc:
2738
- if createmeta_error:
2739
- raise typer.BadParameter(
2740
- f"Failed to load create metadata for {project}/{issuetype}: {createmeta_error}. "
2741
- f"Editmeta fallback for {issue_key} also failed: {exc}"
2742
- ) from exc
2743
- editmeta_fields = None
2744
- typer.echo(f"Warning: editmeta fallback unavailable: {exc}", err=True)
2745
-
2746
- if raw_fields is None or not raw_fields:
2747
- if editmeta_fields:
2748
- raw_fields = editmeta_fields
2749
- elif createmeta_error:
2750
- raise typer.BadParameter(
2751
- f"Failed to load create metadata for {project}/{issuetype}: {createmeta_error}"
2752
- ) from createmeta_error
2753
- elif editmeta_fields:
2754
- _merge_allowed_values_from_editmeta(raw_fields, editmeta_fields)
2755
-
2756
- if raw_fields is None:
2757
- if createmeta_error:
2758
- raise createmeta_error
2759
- raw_fields = {}
2760
-
2761
- fields = _collect_fields(raw_fields, field_filter=field, include_system=include_system)
2762
-
2763
- duration_ms = int((datetime.now(UTC) - started_at).total_seconds() * 1000)
2764
- output = {
2765
- "project": project,
2766
- "issueType": issuetype,
2767
- "count": len(fields),
2768
- "duration_ms": duration_ms,
2769
- "fields": sorted(fields, key=lambda x: (not x["required"], x["name"])),
2770
- }
2771
-
2772
- if len(fields) <= 50 and duration_ms > 2000:
2773
- logger.warning("discover_fields_slow duration_ms=%s count=%s", duration_ms, len(fields))
2774
- elif len(fields) <= 200 and duration_ms > 5000:
2775
- logger.warning("discover_fields_slow duration_ms=%s count=%s", duration_ms, len(fields))
2776
-
2777
- _emit_json(output)
2778
-
2779
- except (AuthError, VDSClientError, typer.BadParameter) as exc:
2780
- code = 1
2781
- logger.error("discover_fields_failed %s", exc)
2782
- typer.echo(f"Error: {exc}", err=True)
2783
- finally:
2784
- finished_at = datetime.now(UTC)
2785
- _record_summary(
2786
- command="discover-fields",
2787
- args=[
2788
- f"project={project}",
2789
- f"issuetype={issuetype}",
2790
- f"field={field}",
2791
- f"include_system={include_system}",
2792
- f"issue_key={issue_key}",
2793
- ],
2794
- exit_code=code,
2795
- started_at=started_at,
2796
- finished_at=finished_at,
2797
- )
2798
- if code != 0:
2799
- raise typer.Exit(code=code) from None