@ngocsangairvds/vsaf 4.1.9 → 4.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/cli/dist/commands/install.d.ts +1 -1
- package/packages/cli/dist/commands/install.d.ts.map +1 -1
- package/packages/cli/dist/commands/install.js +25 -13
- package/packages/cli/dist/commands/install.js.map +1 -1
- package/packages/cli/dist/commands/skill.d.ts.map +1 -1
- package/packages/cli/dist/commands/skill.js +5 -1
- package/packages/cli/dist/commands/skill.js.map +1 -1
- package/skills/vds-skill/install-deps.mjs +252 -0
- package/skills/vds-skill/pack.yaml +8 -0
- package/skills/vds-skill/runtime/.claude/phase7-CLOSURE.md +100 -0
- package/skills/vds-skill/runtime/.dockerignore +62 -0
- package/skills/vds-skill/runtime/.github/ISSUE_TEMPLATE/cli-change.md +92 -0
- package/skills/vds-skill/runtime/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +48 -0
- package/skills/vds-skill/runtime/.github/workflows/chaos-smoke.yml +266 -0
- package/skills/vds-skill/runtime/.github/workflows/confluence-sync.yml +44 -0
- package/skills/vds-skill/runtime/.github/workflows/docs-confluence-evidence.yml +170 -0
- package/skills/vds-skill/runtime/.github/workflows/docs-quality.yml +59 -0
- package/skills/vds-skill/runtime/.github/workflows/lint-and-test.yml +90 -0
- package/skills/vds-skill/runtime/.github/workflows/scheduler-load-smoke.yml +104 -0
- package/skills/vds-skill/runtime/.github/workflows/telegram-bridge-ci.yml +131 -0
- package/skills/vds-skill/runtime/.graphifyignore +29 -0
- package/skills/vds-skill/runtime/.importlinter +86 -0
- package/skills/vds-skill/runtime/.mcp.json +11 -0
- package/skills/vds-skill/runtime/.pre-commit-config.yaml +62 -0
- package/skills/vds-skill/runtime/.ruffignore +3 -0
- package/skills/vds-skill/runtime/AGENTS.md +250 -0
- package/skills/vds-skill/runtime/AGENTS.vi.md +92 -0
- package/skills/vds-skill/runtime/ECOSYSTEM-CHANGELOG.md +52 -0
- package/skills/vds-skill/runtime/ECOSYSTEM-DOCS.md +602 -0
- package/skills/vds-skill/runtime/ECOSYSTEM_ALIGNMENT.md +133 -0
- package/skills/vds-skill/runtime/Makefile +119 -0
- package/skills/vds-skill/runtime/README.md +103 -0
- package/skills/vds-skill/runtime/bitbucket_manifest_mapping.toml +34 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/ARCHITECTURE_ANALYSIS.md +258 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/BITBUCKET_API_PRACTICES.md +393 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/EVALUATION_REPORT.md +61 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/FEATURES.md +908 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/README.md +817 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/pyproject.toml +49 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/__init__.py +50 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py +641 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/cli.py +2271 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/client.py +2693 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/config.py +185 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/errors.py +34 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/factory.py +185 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/parsers.py +113 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/protocols.py +244 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/repo_ops.py +325 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/__init__.py +8 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/conftest.py +65 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_advanced_search.py +155 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_async_client.py +505 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_branch_permissions.py +172 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_cli.py +113 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_cli_archive.py +122 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_cli_clone.py +131 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client.py +207 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_archive.py +73 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_branch_conditions.py +101 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_code_advanced.py +180 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_code_file.py +33 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_deployment_environments.py +193 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_issues.py +163 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_pipelines_advanced.py +171 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_pr_blockers.py +118 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_repository_variables.py +155 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_code.py +98 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_code_advanced.py +279 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_code_insights.py +334 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_conditions.py +149 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_config.py +297 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_deployment_env.py +352 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_errors.py +67 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_factory.py +352 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_fork_operations.py +203 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_issue_cli.py +262 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_pipeline_advanced.py +265 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_pr_blocker.py +206 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_protocols.py +336 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_ops_archive.py +169 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_ops_clone.py +115 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_ops_parsing.py +149 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_settings.py +336 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_variables.py +266 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_webhooks.py +188 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_workspace.py +234 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/unit/__init__.py +0 -0
- package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/unit/test_parsers.py +254 -0
- package/skills/vds-skill/runtime/brd_orchestrator/README.md +29 -0
- package/skills/vds-skill/runtime/brd_orchestrator/pyproject.toml +63 -0
- package/skills/vds-skill/runtime/brd_orchestrator/src/vds_brd_orchestrator/__init__.py +17 -0
- package/skills/vds-skill/runtime/brd_orchestrator/src/vds_brd_orchestrator/cli.py +187 -0
- package/skills/vds-skill/runtime/brd_orchestrator/src/vds_brd_orchestrator/validator.py +121 -0
- package/skills/vds-skill/runtime/brd_orchestrator/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/brd_orchestrator/tests/test_cli.py +62 -0
- package/skills/vds-skill/runtime/brd_orchestrator/tests/test_validator.py +33 -0
- package/skills/vds-skill/runtime/code/code_evidence_pack.json +435 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/Dockerfile +19 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/README.md +479 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/SYNC_SCRIPTS.md +127 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/SYNC_STANDARDIZATION.md +108 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/pyproject.toml +50 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/__init__.py +56 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/async_client.py +100 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/cli.py +3160 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/config.py +213 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/content.py +368 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/content_v2.py +144 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/crawl_tree.py +1833 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/errors.py +44 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/eventing.py +111 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/http.py +1850 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/orchestration.py +166 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/protocols.py +61 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/reporting.py +78 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/tree.py +122 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/tree_copier.py +431 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/sync_pdfs_from_markdown.py +203 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/sync_pdfs_to_confluence.py +299 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/sync_png_attachments.py +299 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/conftest.py +46 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_advanced_content.py +252 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_advanced_search.py +193 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_async_client.py +104 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_cache_management.py +246 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_cli.py +716 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_config.py +130 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_content.py +192 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_content_flags.py +27 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_content_labels.py +94 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_crawl_tree.py +2252 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_degraded_write_safety.py +176 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_draft_management.py +225 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_errors.py +75 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing.py +73 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing_chaos.py +37 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing_rate_limit.py +44 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing_timeout.py +49 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_export.py +231 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_history.py +217 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_http.py +375 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_orchestration.py +93 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_reporting.py +24 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_search_cql.py +36 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_space_management.py +236 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_space_permissions.py +384 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_tree_copier.py +644 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_tree_copier_remap.py +289 -0
- package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_user_group_management.py +387 -0
- package/skills/vds-skill/runtime/diagram_generator/README.md +663 -0
- package/skills/vds-skill/runtime/diagram_generator/ci_validate.sh +16 -0
- package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.png +0 -0
- package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.puml +23 -0
- package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.png +0 -0
- package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.puml +21 -0
- package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.png +0 -0
- package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.puml +14 -0
- package/skills/vds-skill/runtime/diagram_generator/examples/github-actions-validate.yml +39 -0
- package/skills/vds-skill/runtime/diagram_generator/generate_all_diagrams.py +827 -0
- package/skills/vds-skill/runtime/diagram_generator/generate_insurance_c4_diagrams.py +261 -0
- package/skills/vds-skill/runtime/diagram_generator/generate_insurance_c4_quick.py +486 -0
- package/skills/vds-skill/runtime/diagram_generator/pyproject.toml +28 -0
- package/skills/vds-skill/runtime/diagram_generator/render_png.py +59 -0
- package/skills/vds-skill/runtime/diagram_generator/src/vds_diagram_generator/__init__.py +3 -0
- package/skills/vds-skill/runtime/diagram_generator/src/vds_diagram_generator/cli.py +50 -0
- package/skills/vds-skill/runtime/diagram_generator/test_c4_hierarchical.py +142 -0
- package/skills/vds-skill/runtime/diagram_generator/test_c4_quick.py +131 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_analyzer_completeness.py +260 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_c4_syntax_correctness.py +138 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_component_coverage.py +182 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_mermaid_output.py +80 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_png_generation.py +112 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_scenario_templates.py +15 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_sequence_accuracy.py +93 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_structurizr_export.py +177 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_style_consistency.py +174 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_usecase_generator.py +201 -0
- package/skills/vds-skill/runtime/diagram_generator/tests/test_usecase_integration.py +124 -0
- package/skills/vds-skill/runtime/docker/.dockerignore +38 -0
- package/skills/vds-skill/runtime/docker/ADR.md +392 -0
- package/skills/vds-skill/runtime/docker/Dockerfile +68 -0
- package/skills/vds-skill/runtime/docker/MIGRATION.md +453 -0
- package/skills/vds-skill/runtime/docker/README.md +347 -0
- package/skills/vds-skill/runtime/docker/ROLLBACK.md +596 -0
- package/skills/vds-skill/runtime/docker/compose.phase2-verification.yml +31 -0
- package/skills/vds-skill/runtime/docker/docker-compose.cli.yml +206 -0
- package/skills/vds-skill/runtime/docker/docker-compose.infra.yml +276 -0
- package/skills/vds-skill/runtime/docker/docker-compose.services.yml +425 -0
- package/skills/vds-skill/runtime/docker/infrastructure/init-schemas.sql +177 -0
- package/skills/vds-skill/runtime/docker/infrastructure/pgbouncer/pgbouncer.ini +75 -0
- package/skills/vds-skill/runtime/docker/infrastructure/pgbouncer/userlist.txt +50 -0
- package/skills/vds-skill/runtime/docker/infrastructure/pgbouncer/userlist.txt.template +36 -0
- package/skills/vds-skill/runtime/docs/.confluence-evidence/.gitkeep +0 -0
- package/skills/vds-skill/runtime/docs/.confluence-evidence/PREFLIGHT.md +132 -0
- package/skills/vds-skill/runtime/docs/.confluence-evidence/README.md +84 -0
- package/skills/vds-skill/runtime/docs/.confluence.yaml +156 -0
- package/skills/vds-skill/runtime/docs/.freshness.yaml +54 -0
- package/skills/vds-skill/runtime/docs/README.md +235 -0
- package/skills/vds-skill/runtime/docs/agents/README.md +33 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/data-flow.md +132 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/development-roadmap.md +49 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/features-overview.md +62 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/index.md +36 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/runtime-verification-and-gap-reporting.md +127 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/system-architecture.md +139 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/whats-new.md +75 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/who-ecosystem-introduction.md +65 -0
- package/skills/vds-skill/runtime/docs/agents/explanation/who-ecosystem-model.md +41 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/02-using-vds-ai-memory.md +98 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/03-memory-cross-agent.md +241 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/04-using-progress-reports.md +240 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/08-semantic-search.md +46 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/apply-phase3-migration.md +148 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/choose-the-right-command-or-skill.md +34 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/contribute-new-orchestrator.md +149 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/decision-tree.md +63 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/first-audit-run.md +83 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/index.md +49 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +314 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +165 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +138 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +130 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +142 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +140 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +135 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/phase131-all-project-preparation.md +211 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/phase131-bounded-parallel-analysis.md +123 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/phase131-confluence-upload-recovery.md +204 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/phase132-department-preparation.md +144 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/run-ecosystem-daily-report.md +213 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/tips-and-tricks.md +138 -0
- package/skills/vds-skill/runtime/docs/agents/how-to/troubleshooting-guide.md +221 -0
- package/skills/vds-skill/runtime/docs/agents/reference/agent-operational-contract.md +162 -0
- package/skills/vds-skill/runtime/docs/agents/reference/alignment-phase179-report.md +144 -0
- package/skills/vds-skill/runtime/docs/agents/reference/audit-triage-playbook.md +256 -0
- package/skills/vds-skill/runtime/docs/agents/reference/backup-restore.md +132 -0
- package/skills/vds-skill/runtime/docs/agents/reference/bitbucket-orchestrator.md +56 -0
- package/skills/vds-skill/runtime/docs/agents/reference/brd-orchestrator.md +52 -0
- package/skills/vds-skill/runtime/docs/agents/reference/capability-coverage-review.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/ci-workflows.md +98 -0
- package/skills/vds-skill/runtime/docs/agents/reference/circular-dependency-orchestrator.md +55 -0
- package/skills/vds-skill/runtime/docs/agents/reference/cli-commands.md +583 -0
- package/skills/vds-skill/runtime/docs/agents/reference/cli-development-standards.md +41 -0
- package/skills/vds-skill/runtime/docs/agents/reference/cli-help-matrix.md +84 -0
- package/skills/vds-skill/runtime/docs/agents/reference/common-errors.md +126 -0
- package/skills/vds-skill/runtime/docs/agents/reference/configuration-reference.md +128 -0
- package/skills/vds-skill/runtime/docs/agents/reference/confluence-orchestrator.md +56 -0
- package/skills/vds-skill/runtime/docs/agents/reference/confluence-sync-target.md +111 -0
- package/skills/vds-skill/runtime/docs/agents/reference/confluence-sync.md +46 -0
- package/skills/vds-skill/runtime/docs/agents/reference/db-query-orchestrator.md +93 -0
- package/skills/vds-skill/runtime/docs/agents/reference/diagrams-orchestrator.md +52 -0
- package/skills/vds-skill/runtime/docs/agents/reference/ecosystem-daily-report.md +229 -0
- package/skills/vds-skill/runtime/docs/agents/reference/elastic-orchestrator.md +57 -0
- package/skills/vds-skill/runtime/docs/agents/reference/env-git-helper.md +216 -0
- package/skills/vds-skill/runtime/docs/agents/reference/evolution-orchestrator.md +113 -0
- package/skills/vds-skill/runtime/docs/agents/reference/excel-orchestrator.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/git-orchestrator.md +62 -0
- package/skills/vds-skill/runtime/docs/agents/reference/google-sheets-orchestrator.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/grafana-orchestrator.md +52 -0
- package/skills/vds-skill/runtime/docs/agents/reference/hexagonal-orchestrator.md +64 -0
- package/skills/vds-skill/runtime/docs/agents/reference/index.md +36 -0
- package/skills/vds-skill/runtime/docs/agents/reference/infrastructure-v2.15.md +67 -0
- package/skills/vds-skill/runtime/docs/agents/reference/intellij-orchestrator.md +50 -0
- package/skills/vds-skill/runtime/docs/agents/reference/jira-orchestrator.md +60 -0
- package/skills/vds-skill/runtime/docs/agents/reference/links-orchestrator.md +57 -0
- package/skills/vds-skill/runtime/docs/agents/reference/lint-cli.md +99 -0
- package/skills/vds-skill/runtime/docs/agents/reference/lsp-orchestrator.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/markdown-orchestrator.md +53 -0
- package/skills/vds-skill/runtime/docs/agents/reference/mcp-orchestrator.md +88 -0
- package/skills/vds-skill/runtime/docs/agents/reference/memory-orchestrator.md +53 -0
- package/skills/vds-skill/runtime/docs/agents/reference/metabase-orchestrator.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/migration-playbook.md +71 -0
- package/skills/vds-skill/runtime/docs/agents/reference/multi-agent-orchestrator.md +52 -0
- package/skills/vds-skill/runtime/docs/agents/reference/openapi-orchestrator.md +57 -0
- package/skills/vds-skill/runtime/docs/agents/reference/orchestrator-architecture.md +194 -0
- package/skills/vds-skill/runtime/docs/agents/reference/orchestrator-comparison-matrix.md +79 -0
- package/skills/vds-skill/runtime/docs/agents/reference/orchestrator-index.md +73 -0
- package/skills/vds-skill/runtime/docs/agents/reference/pdf-orchestrator.md +57 -0
- package/skills/vds-skill/runtime/docs/agents/reference/portable-paths-and-config.md +0 -0
- package/skills/vds-skill/runtime/docs/agents/reference/portable-paths-validation-matrix.md +129 -0
- package/skills/vds-skill/runtime/docs/agents/reference/progress-orchestrator.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/progress-report-cli.md +215 -0
- package/skills/vds-skill/runtime/docs/agents/reference/public-interface-orchestrator.md +73 -0
- package/skills/vds-skill/runtime/docs/agents/reference/research-orchestrator.md +53 -0
- package/skills/vds-skill/runtime/docs/agents/reference/schema-orchestrator.md +57 -0
- package/skills/vds-skill/runtime/docs/agents/reference/search-tools.md +34 -0
- package/skills/vds-skill/runtime/docs/agents/reference/skills-commands.md +256 -0
- package/skills/vds-skill/runtime/docs/agents/reference/skills-reference.md +32 -0
- package/skills/vds-skill/runtime/docs/agents/reference/sonarqube-orchestrator.md +62 -0
- package/skills/vds-skill/runtime/docs/agents/reference/spec-orchestrator.md +56 -0
- package/skills/vds-skill/runtime/docs/agents/reference/structure-orchestrator.md +69 -0
- package/skills/vds-skill/runtime/docs/agents/reference/system-requirements.md +76 -0
- package/skills/vds-skill/runtime/docs/agents/reference/tasks-orchestrator.md +53 -0
- package/skills/vds-skill/runtime/docs/agents/reference/validation-and-sync-notes.md +54 -0
- package/skills/vds-skill/runtime/docs/agents/reference/vds-ai-memory-api.md +51 -0
- package/skills/vds-skill/runtime/docs/agents/reference/vds-cli-reference.md +34 -0
- package/skills/vds-skill/runtime/docs/agents/reference/who-capability-inventory.md +96 -0
- package/skills/vds-skill/runtime/docs/agents/reference/who-capability-routing-matrix.md +14 -0
- package/skills/vds-skill/runtime/docs/agents/tutorials/feature-progression-guide.md +112 -0
- package/skills/vds-skill/runtime/docs/agents/tutorials/index.md +36 -0
- package/skills/vds-skill/runtime/docs/agents/tutorials/quick-start.md +50 -0
- package/skills/vds-skill/runtime/docs/agents/tutorials/who-skills-and-scripts-onboarding.md +47 -0
- package/skills/vds-skill/runtime/docs/agents/tutorials/zero-to-productive-developer.md +339 -0
- package/skills/vds-skill/runtime/docs/confluence/IMPLEMENTATION-SUMMARY.md +78 -0
- package/skills/vds-skill/runtime/docs/confluence/SYNC-GUIDE.md +47 -0
- package/skills/vds-skill/runtime/docs/deployment/offline-docker-image-load.md +59 -0
- package/skills/vds-skill/runtime/docs/evolution-auto-run-rollout.md +325 -0
- package/skills/vds-skill/runtime/docs/evolution-loop-deep-integration.md +496 -0
- package/skills/vds-skill/runtime/docs/evolution-loop-integration-guide.md +359 -0
- package/skills/vds-skill/runtime/docs/openspace-schema-snapshot.md +73 -0
- package/skills/vds-skill/runtime/docs/operations/sla-mttr-policy.md +44 -0
- package/skills/vds-skill/runtime/docs/p0-closure-evidence/SUMMARY.md +58 -0
- package/skills/vds-skill/runtime/docs/p4-closure-evidence/.gitkeep +0 -0
- package/skills/vds-skill/runtime/docs/p4-closure-evidence/smoke-20260427T024137Z-b95b586b.json +15 -0
- package/skills/vds-skill/runtime/docs/p8-preflight-evidence/alembic-and-runtime-advisory-locks.md +45 -0
- package/skills/vds-skill/runtime/docs/p8-preflight-evidence/dbos-listen-notify.md +54 -0
- package/skills/vds-skill/runtime/docs/p8-preflight-evidence/pgbouncer-search-path-empirical.md +110 -0
- package/skills/vds-skill/runtime/docs/p8-preflight-evidence/pgvector-set-local-audit.md +51 -0
- package/skills/vds-skill/runtime/docs/p8-preflight-evidence/topology-decision-session-mode.md +57 -0
- package/skills/vds-skill/runtime/docs/phases/CHANGELOG.md +103 -0
- package/skills/vds-skill/runtime/docs/phases/PHASE_125_COMPLETION_AND_MERGE.md +212 -0
- package/skills/vds-skill/runtime/docs/phases/phase125/IMPLEMENTATION_REPORT.md +227 -0
- package/skills/vds-skill/runtime/docs/phases/phase125/TSK-125.10-11-implementation-summary.md +196 -0
- package/skills/vds-skill/runtime/docs/phases/phase125/profile-patch-ollama-local-anthropic.md +122 -0
- package/skills/vds-skill/runtime/docs/phases/phase125_completion_summary.md +369 -0
- package/skills/vds-skill/runtime/docs/phases/phase125_llm_analysis_skill.md +164 -0
- package/skills/vds-skill/runtime/docs/phases/phase125_merge_complete.md +147 -0
- package/skills/vds-skill/runtime/docs/phases/phase125_skill_runtime_closure_20260321.md +91 -0
- package/skills/vds-skill/runtime/docs/phases/phase2-portable-paths/closure-handoff-summary-2026-03-23.md +290 -0
- package/skills/vds-skill/runtime/docs/phases/phase2-portable-paths/remaining-risk-register-2026-03-25.md +143 -0
- package/skills/vds-skill/runtime/docs/phases/phase2-portable-paths/verification-evidence-2026-03-23.md +135 -0
- package/skills/vds-skill/runtime/docs/v0-sunset-known-issues.md +88 -0
- package/skills/vds-skill/runtime/docs/vi/TRANSLATION-BACKLOG.md +72 -0
- package/skills/vds-skill/runtime/docs/vi/agents/README.md +41 -0
- package/skills/vds-skill/runtime/docs/vi/agents/explanation/features-overview.md +29 -0
- package/skills/vds-skill/runtime/docs/vi/agents/explanation/index.md +14 -0
- package/skills/vds-skill/runtime/docs/vi/agents/explanation/runtime-verification-and-gap-reporting.md +129 -0
- package/skills/vds-skill/runtime/docs/vi/agents/explanation/whats-new.md +37 -0
- package/skills/vds-skill/runtime/docs/vi/agents/explanation/who-ecosystem-introduction.md +21 -0
- package/skills/vds-skill/runtime/docs/vi/agents/explanation/who-ecosystem-model.md +36 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/02-using-vds-ai-memory.md +100 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/03-memory-cross-agent.md +243 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/04-using-progress-reports.md +242 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/08-semantic-search.md +16 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/choose-the-right-command-or-skill.md +36 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/decision-tree.md +77 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/first-audit-run.md +85 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/index.md +21 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +156 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +174 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +147 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +139 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +151 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +149 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +144 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase131-all-project-preparation.md +213 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase131-bounded-parallel-analysis.md +125 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase131-confluence-upload-recovery.md +206 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase132-department-preparation.md +146 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/tips-and-tricks.md +34 -0
- package/skills/vds-skill/runtime/docs/vi/agents/how-to/troubleshooting-guide.md +36 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/agent-operational-contract.md +98 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/audit-triage-playbook.md +258 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/bitbucket-orchestrator.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/brd-orchestrator.md +29 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/capability-coverage-review.md +46 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/circular-dependency-orchestrator.md +29 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/cli-commands.md +409 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/cli-development-standards.md +19 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/cli-help-matrix.md +71 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/common-errors.md +133 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/configuration-reference.md +25 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/confluence-orchestrator.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/db-query-orchestrator.md +34 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/diagrams-orchestrator.md +31 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/elastic-orchestrator.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/evolution-orchestrator.md +31 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/excel-orchestrator.md +60 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/git-orchestrator.md +31 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/google-sheets-orchestrator.md +60 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/grafana-orchestrator.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/hexagonal-orchestrator.md +73 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/index.md +25 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/intellij-orchestrator.md +59 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/jira-orchestrator.md +32 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/links-orchestrator.md +66 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/lsp-orchestrator.md +60 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/markdown-orchestrator.md +62 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/mcp-orchestrator.md +34 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/memory-orchestrator.md +45 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/metabase-orchestrator.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/multi-agent-orchestrator.md +61 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/openapi-orchestrator.md +66 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/orchestrator-architecture.md +24 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/orchestrator-index.md +73 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/pdf-orchestrator.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/portable-paths-and-config.md +123 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/portable-paths-validation-matrix.md +131 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/progress-orchestrator.md +43 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/progress-report-cli.md +217 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/public-interface-orchestrator.md +82 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/research-orchestrator.md +45 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/schema-orchestrator.md +66 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/search-tools.md +19 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/skills-reference.md +27 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/sonarqube-orchestrator.md +71 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/spec-orchestrator.md +56 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/structure-orchestrator.md +78 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/system-requirements.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/tasks-orchestrator.md +45 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/validation-and-sync-notes.md +26 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/vds-ai-memory-api.md +53 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/vds-cli-reference.md +34 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/who-capability-inventory.md +98 -0
- package/skills/vds-skill/runtime/docs/vi/agents/reference/who-capability-routing-matrix.md +16 -0
- package/skills/vds-skill/runtime/docs/vi/agents/tutorials/feature-progression-guide.md +124 -0
- package/skills/vds-skill/runtime/docs/vi/agents/tutorials/index.md +13 -0
- package/skills/vds-skill/runtime/docs/vi/agents/tutorials/quick-start.md +30 -0
- package/skills/vds-skill/runtime/docs/vi/agents/tutorials/who-skills-and-scripts-onboarding.md +42 -0
- package/skills/vds-skill/runtime/docs/vi/agents/tutorials/zero-to-productive-developer.md +137 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/README.md +450 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/pyproject.toml +97 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/__init__.py +81 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/cli.py +652 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/client.py +743 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/config.py +208 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/errors.py +34 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/py.typed +0 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/tests/conftest.py +227 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_client.py +990 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_config.py +268 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_e2e_verification.py +272 -0
- package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_errors.py +78 -0
- package/skills/vds-skill/runtime/excel_orchestrator/README.md +288 -0
- package/skills/vds-skill/runtime/excel_orchestrator/RESEARCH_BASED_UPDATES_REPORT.md +261 -0
- package/skills/vds-skill/runtime/excel_orchestrator/add_essential_missing_effort.py +255 -0
- package/skills/vds-skill/runtime/excel_orchestrator/adjust_effort_complexity.py +184 -0
- package/skills/vds-skill/runtime/excel_orchestrator/brd_analysis_and_task_breakdown.py +632 -0
- package/skills/vds-skill/runtime/excel_orchestrator/brd_analysis_comprehensive.py +1029 -0
- package/skills/vds-skill/runtime/excel_orchestrator/check_overlaps_and_brd_coverage.py +570 -0
- package/skills/vds-skill/runtime/excel_orchestrator/clean_remarks_column.py +127 -0
- package/skills/vds-skill/runtime/excel_orchestrator/comprehensive_brd_check.py +322 -0
- package/skills/vds-skill/runtime/excel_orchestrator/create_buffered_summary.py +119 -0
- package/skills/vds-skill/runtime/excel_orchestrator/create_service_totals_sheet.py +118 -0
- package/skills/vds-skill/runtime/excel_orchestrator/examples/basic_operations.py +85 -0
- package/skills/vds-skill/runtime/excel_orchestrator/expand_all_tasks.py +341 -0
- package/skills/vds-skill/runtime/excel_orchestrator/expand_tasks.py +304 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fill_brd_references.py +347 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fill_remarks_and_colors.py +132 -0
- package/skills/vds-skill/runtime/excel_orchestrator/finalize_brd_and_cleanup.py +295 -0
- package/skills/vds-skill/runtime/excel_orchestrator/finalize_brd_coverage.py +327 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fix_all_formulas.py +99 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fix_detail_presentation.py +113 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fix_presentation_and_effort.py +116 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fix_presentation_consistency.py +231 -0
- package/skills/vds-skill/runtime/excel_orchestrator/fix_remarks_matching.py +179 -0
- package/skills/vds-skill/runtime/excel_orchestrator/group_tasks_by_service_id.py +210 -0
- package/skills/vds-skill/runtime/excel_orchestrator/increase_brd_coverage.py +497 -0
- package/skills/vds-skill/runtime/excel_orchestrator/increase_effort_complexity.py +155 -0
- package/skills/vds-skill/runtime/excel_orchestrator/organize_and_deduplicate.py +273 -0
- package/skills/vds-skill/runtime/excel_orchestrator/pyproject.toml +64 -0
- package/skills/vds-skill/runtime/excel_orchestrator/rebuild_all_formulas.py +146 -0
- package/skills/vds-skill/runtime/excel_orchestrator/remove_base_multiplier_and_check_duplicates.py +310 -0
- package/skills/vds-skill/runtime/excel_orchestrator/remove_duplicate_brd_tasks.py +137 -0
- package/skills/vds-skill/runtime/excel_orchestrator/research_based_updates.py +457 -0
- package/skills/vds-skill/runtime/excel_orchestrator/restore_e_values.py +172 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/__init__.py +5 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/cli.py +746 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/config.py +74 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/converters.py +226 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/errors.py +88 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/excel_client.py +443 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/formatters.py +211 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/logging.py +57 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/source_contract.py +29 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/target_state_status.py +837 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/ulnc_alignment.py +1291 -0
- package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/validators.py +164 -0
- package/skills/vds-skill/runtime/excel_orchestrator/sync_detail_and_total_sheets.py +211 -0
- package/skills/vds-skill/runtime/excel_orchestrator/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/excel_orchestrator/tests/conftest.py +36 -0
- package/skills/vds-skill/runtime/excel_orchestrator/tests/test_cli.py +383 -0
- package/skills/vds-skill/runtime/excel_orchestrator/tests/test_excel_client.py +129 -0
- package/skills/vds-skill/runtime/excel_orchestrator/tests/test_ulnc_alignment.py +373 -0
- package/skills/vds-skill/runtime/excel_orchestrator/tests/test_validators.py +64 -0
- package/skills/vds-skill/runtime/excel_orchestrator/update_api_database_effort.py +261 -0
- package/skills/vds-skill/runtime/excel_orchestrator/update_buffers_inline.py +115 -0
- package/skills/vds-skill/runtime/excel_orchestrator/update_complex_services_and_add_new.py +336 -0
- package/skills/vds-skill/runtime/excel_orchestrator/update_responsibility_and_fix_rows.py +208 -0
- package/skills/vds-skill/runtime/excel_orchestrator/update_task_breakdown_vietnamese.py +309 -0
- package/skills/vds-skill/runtime/excel_orchestrator/update_vietnamese_and_responsibility.py +415 -0
- package/skills/vds-skill/runtime/excel_orchestrator/verify_brd_coverage_comprehensive.py +401 -0
- package/skills/vds-skill/runtime/git_orchestrator/ENHANCEMENT_SUMMARY.md +119 -0
- package/skills/vds-skill/runtime/git_orchestrator/README.md +286 -0
- package/skills/vds-skill/runtime/git_orchestrator/VERIFICATION_REPORT.md +152 -0
- package/skills/vds-skill/runtime/git_orchestrator/pyproject.toml +37 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/__init__.py +30 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/__main__.py +4 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/branch_probe.py +271 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/cli.py +892 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/logging_config.py +63 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/manifest.py +249 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/orchestrator.py +1647 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/protocols.py +35 -0
- package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/reporting.py +55 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/test_cli_settings.py +19 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/test_integration.py +79 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/test_manifest.py +79 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/test_orchestrator.py +207 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/test_public_api.py +235 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/test_resilience.py +343 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/unit/__init__.py +0 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/unit/test_branch_probe.py +327 -0
- package/skills/vds-skill/runtime/git_orchestrator/tests/unit/test_protocols.py +132 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/README.md +241 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/pyproject.toml +45 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/__init__.py +69 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/cli.py +568 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/client.py +186 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/config.py +46 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/errors.py +41 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/conftest.py +1 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/__init__.py +1 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/test_cli.py +212 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/test_client.py +24 -0
- package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/test_config.py +16 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/README.md +572 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/pyproject.toml +102 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/__init__.py +78 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/cli.py +455 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/client.py +700 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/config.py +243 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/errors.py +34 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/py.typed +1 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/tests/conftest.py +308 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/tests/test_client.py +458 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/tests/test_config.py +203 -0
- package/skills/vds-skill/runtime/grafana_orchestrator/tests/test_errors.py +78 -0
- package/skills/vds-skill/runtime/jira_orchestrator/README.md +864 -0
- package/skills/vds-skill/runtime/jira_orchestrator/pyproject.toml +43 -0
- package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/__init__.py +65 -0
- package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/adapter.py +1685 -0
- package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/cli.py +2806 -0
- package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/config.py +168 -0
- package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/errors.py +34 -0
- package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/reporting.py +66 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/conftest.py +86 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_agile_list_payloads.py +54 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_bulk_operations.py +91 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_components.py +56 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_createmeta.py +45 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_dashboard.py +119 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_issue_properties.py +53 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_permissions_compat.py +41 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_reindex.py +42 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_remote_links.py +75 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_transitions.py +90 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_user_management.py +116 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_version_management.py +181 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_watchers.py +43 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_advanced_search.py +179 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_agile.py +304 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_application_properties.py +243 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_backlog.py +91 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_bulk_operations.py +403 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_cli.py +108 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_components.py +119 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_config.py +166 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_dashboard.py +122 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_discover_fields.py +207 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_errors.py +72 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_filter_management.py +411 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_issue_archiving.py +179 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_issue_links.py +257 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_issue_properties.py +189 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_link_types.py +407 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_parse_set.py +37 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_permissions.py +343 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_reindex.py +81 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_remote_links.py +269 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_security_schemes.py +202 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_transitions_changelog.py +109 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_user_management.py +246 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_version_management.py +503 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_watchers.py +116 -0
- package/skills/vds-skill/runtime/jira_orchestrator/tests/test_worklog.py +243 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/README.md +864 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/pyproject.toml +43 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/__init__.py +65 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/adapter.py +1689 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/cli.py +2799 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/config.py +135 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/errors.py +34 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/reporting.py +65 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/conftest.py +86 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_agile_list_payloads.py +54 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_bulk_operations.py +101 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_components.py +64 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_createmeta.py +45 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_dashboard.py +135 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_issue_properties.py +63 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_permissions_compat.py +42 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_reindex.py +42 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_remote_links.py +89 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_transitions.py +91 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_user_management.py +130 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_version_management.py +189 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_watchers.py +49 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_advanced_search.py +213 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_agile.py +334 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_application_properties.py +261 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_backlog.py +91 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_bulk_operations.py +443 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_cli.py +106 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_components.py +133 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_config.py +166 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_dashboard.py +130 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_discover_fields.py +207 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_errors.py +61 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_filter_management.py +478 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_issue_archiving.py +181 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_issue_links.py +257 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_issue_properties.py +203 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_link_types.py +426 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_parse_set.py +37 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_permissions.py +358 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_reindex.py +81 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_remote_links.py +292 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_security_schemes.py +218 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_transitions_changelog.py +121 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_user_management.py +283 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_version_management.py +561 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_watchers.py +128 -0
- package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_worklog.py +265 -0
- package/skills/vds-skill/runtime/llms.txt +159 -0
- package/skills/vds-skill/runtime/markdown_orchestrator/README.md +72 -0
- package/skills/vds-skill/runtime/markdown_orchestrator/pyproject.toml +39 -0
- package/skills/vds-skill/runtime/markdown_orchestrator/src/vds_markdown_orchestrator/__init__.py +5 -0
- package/skills/vds-skill/runtime/markdown_orchestrator/src/vds_markdown_orchestrator/cli.py +102 -0
- package/skills/vds-skill/runtime/mcp_server/Dockerfile +63 -0
- package/skills/vds-skill/runtime/mcp_server/README.md +140 -0
- package/skills/vds-skill/runtime/mcp_server/pyproject.toml +41 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/__init__.py +3 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/config.py +36 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/server.py +111 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/__init__.py +15 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/bitbucket_tools.py +47 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/confluence_tools.py +53 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/git_tools.py +71 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/jira_tools.py +63 -0
- package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/vidp_tools.py +64 -0
- package/skills/vds-skill/runtime/mcp_server/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/mcp_server/tests/conftest.py +31 -0
- package/skills/vds-skill/runtime/mcp_server/tests/unit/__init__.py +1 -0
- package/skills/vds-skill/runtime/mcp_server/tests/unit/test_bitbucket_tools.py +28 -0
- package/skills/vds-skill/runtime/mcp_server/tests/unit/test_confluence_tools.py +28 -0
- package/skills/vds-skill/runtime/mcp_server/tests/unit/test_git_tools.py +35 -0
- package/skills/vds-skill/runtime/mcp_server/tests/unit/test_jira_tools.py +35 -0
- package/skills/vds-skill/runtime/mcp_server/tests/verification/__init__.py +6 -0
- package/skills/vds-skill/runtime/mcp_server/tests/verification/conftest.py +51 -0
- package/skills/vds-skill/runtime/mcp_server/tests/verification/test_mcp_confluence_tools.py +40 -0
- package/skills/vds-skill/runtime/mcp_server/tests/verification/test_mcp_jira_tools.py +39 -0
- package/skills/vds-skill/runtime/mcp_server/tests/verification/test_mcp_tool_registration.py +50 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/.dockerignore +93 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/.env.example +40 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/.ruff_rules.py +350 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/.yamllint.yml +43 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/DEVELOPMENT_PLAN.md +80 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/Dockerfile +87 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/README.md +608 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/cli_verification_test/test.md +6 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/cli_verification_test/test.pdf +0 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/config/alertmanager.yml +83 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/config/prometheus.prod.yml +98 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/config/prometheus.yml +40 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/config/redis.conf +78 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/docs/COMPETITIVE_ANALYSIS_REPORT.md +309 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/docs/FEATURES_GUIDE.md +518 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/docs/MULTI_USER_DEPLOYMENT_GUIDE.md +615 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/docs/USER_GUIDE.md +829 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/pyproject.toml +87 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/pytest.ini +71 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/ruff.toml +6 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/debug_security_report.py +59 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/demo_library_selector.py +109 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/generate_project_stats.py +52 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/generate_styled_pdf.py +95 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/migrate_render_pdfs.py +285 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/setup_team.bat +283 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/scripts/setup_team.sh +324 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/src/vds_pdf_orchestrator/__init__.py +5 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/src/vds_pdf_orchestrator/cli.py +542 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/src/vds_pdf_orchestrator/config.py +33 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/tests/README.md +650 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/tests/conftest.py +520 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/tests/requirements.txt +51 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/tests/run_tests.py +659 -0
- package/skills/vds-skill/runtime/pdf_orchestrator/tests/test_config.py +36 -0
- package/skills/vds-skill/runtime/platform_core/pyproject.toml +49 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/__init__.py +16 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/alembic/__init__.py +18 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/alembic/runtime.py +139 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/config.py +88 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/credentials.py +40 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/env.py +24 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/errors.py +127 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/__init__.py +18 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/auth.py +32 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/errors.py +47 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/pagination.py +65 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/retry.py +62 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/stack.py +61 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/logging.py +132 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/protocols.py +77 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/serialization.py +80 -0
- package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/severity.py +175 -0
- package/skills/vds-skill/runtime/platform_core/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/platform_core/tests/conftest.py +1 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_alembic_runtime.py +300 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_auth.py +84 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_config.py +83 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_credentials.py +73 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_env.py +56 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_errors.py +201 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_errors_http.py +74 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_http_settings.py +116 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_logging.py +148 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_pagination.py +153 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_protocols.py +132 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_retry.py +151 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_serialization.py +92 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_severity.py +178 -0
- package/skills/vds-skill/runtime/platform_core/tests/test_stack.py +130 -0
- package/skills/vds-skill/runtime/platform_core/uv.lock +341 -0
- package/skills/vds-skill/runtime/pyproject.toml +145 -0
- package/skills/vds-skill/runtime/pyrightconfig.json +82 -0
- package/skills/vds-skill/runtime/repo-manifest.yaml +380 -0
- package/skills/vds-skill/runtime/repo-manifest.yaml.example +25 -0
- package/skills/vds-skill/runtime/ruff.toml +100 -0
- package/skills/vds-skill/runtime/scripts/BRD-Validation-API.postman_collection.json +706 -0
- package/skills/vds-skill/runtime/scripts/BRD-Validation-README.md +308 -0
- package/skills/vds-skill/runtime/scripts/README.md +271 -0
- package/skills/vds-skill/runtime/scripts/_validate_alias_phase2.py +137 -0
- package/skills/vds-skill/runtime/scripts/audit-cli-patterns.sh +135 -0
- package/skills/vds-skill/runtime/scripts/audit-dashboard.sh +525 -0
- package/skills/vds-skill/runtime/scripts/backup.sh +123 -0
- package/skills/vds-skill/runtime/scripts/bootstrap_uv.sh +69 -0
- package/skills/vds-skill/runtime/scripts/brd-validation-environment.json +51 -0
- package/skills/vds-skill/runtime/scripts/brd-validation-test-results.json +13023 -0
- package/skills/vds-skill/runtime/scripts/brd_coverage_report.json +276 -0
- package/skills/vds-skill/runtime/scripts/check-future-annotations.py +22 -0
- package/skills/vds-skill/runtime/scripts/check-invalid-symlinks.py +183 -0
- package/skills/vds-skill/runtime/scripts/check-no-debug-markers.py +21 -0
- package/skills/vds-skill/runtime/scripts/check-no-unittest.py +21 -0
- package/skills/vds-skill/runtime/scripts/ci/assert_no_openspace_commits.sh +37 -0
- package/skills/vds-skill/runtime/scripts/ci/verify_branch_protection.sh +64 -0
- package/skills/vds-skill/runtime/scripts/closure/phase1_check.sh +483 -0
- package/skills/vds-skill/runtime/scripts/closure/phase2_check.sh +500 -0
- package/skills/vds-skill/runtime/scripts/create_memory_session.py +36 -0
- package/skills/vds-skill/runtime/scripts/deploy-bootstrap.sh +201 -0
- package/skills/vds-skill/runtime/scripts/deployment/load_docker_images_offline.sh +90 -0
- package/skills/vds-skill/runtime/scripts/dev/cli_smoke.sh +259 -0
- package/skills/vds-skill/runtime/scripts/final_completion_report.md +139 -0
- package/skills/vds-skill/runtime/scripts/folder_structure_report.json +321 -0
- package/skills/vds-skill/runtime/scripts/generate_completion_report.py +132 -0
- package/skills/vds-skill/runtime/scripts/generate_intellij_modules.py +154 -0
- package/skills/vds-skill/runtime/scripts/init-pgbouncer-userlist.sh +154 -0
- package/skills/vds-skill/runtime/scripts/link_integrity_report.json +807 -0
- package/skills/vds-skill/runtime/scripts/move_audit_artifact_pages.py +252 -0
- package/skills/vds-skill/runtime/scripts/move_audit_artifact_pages_rest.py +165 -0
- package/skills/vds-skill/runtime/scripts/move_wrong_dept_pages.py +235 -0
- package/skills/vds-skill/runtime/scripts/openspace_bootstrap.sh +56 -0
- package/skills/vds-skill/runtime/scripts/openspace_common.sh +75 -0
- package/skills/vds-skill/runtime/scripts/openspace_doctor.sh +61 -0
- package/skills/vds-skill/runtime/scripts/openspace_sync_shadow.sh +65 -0
- package/skills/vds-skill/runtime/scripts/phase7-baseline.sh +77 -0
- package/skills/vds-skill/runtime/scripts/preflight/env_check.sh +102 -0
- package/skills/vds-skill/runtime/scripts/repair_autopay_reports.sh +173 -0
- package/skills/vds-skill/runtime/scripts/rollback_drill.sh +659 -0
- package/skills/vds-skill/runtime/scripts/run-audit-in-tmux.sh +286 -0
- package/skills/vds-skill/runtime/scripts/run-department-audit.sh +495 -0
- package/skills/vds-skill/runtime/scripts/run-project-audit.sh +267 -0
- package/skills/vds-skill/runtime/scripts/save_intellij_memories.py +112 -0
- package/skills/vds-skill/runtime/scripts/save_memories_to_vds_ai.py +81 -0
- package/skills/vds-skill/runtime/scripts/save_memories_vds_style.py +133 -0
- package/skills/vds-skill/runtime/scripts/search_intellij_memories.py +48 -0
- package/skills/vds-skill/runtime/scripts/setup_intellij_workspace.py +71 -0
- package/skills/vds-skill/runtime/scripts/smoke-test-deploy.sh +137 -0
- package/skills/vds-skill/runtime/scripts/smoke_deploy_lib.py +205 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/README.md +89 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/confluence_sync_coordinator.sh +27 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/coordination.sh +114 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/diagram_coordinator.sh +25 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/docs_root.sh +22 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/generate_diagrams.sh +22 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/markdown_coordinator.sh +25 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/progress_dashboard.sh +17 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/schema_coordinator.sh +25 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/sync_confluence.sh +30 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/update_dependencies.sh +19 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/validate_links.sh +86 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/validate_markdown.sh +52 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/validate_schemas.sh +26 -0
- package/skills/vds-skill/runtime/scripts/target-state-automation/validate_structure.sh +98 -0
- package/skills/vds-skill/runtime/scripts/tests/__init__.py +1 -0
- package/skills/vds-skill/runtime/scripts/tests/test_dockerfile_correctness.py +815 -0
- package/skills/vds-skill/runtime/scripts/tests/test_makefile_loadouts.py +560 -0
- package/skills/vds-skill/runtime/scripts/tests/test_smoke_deploy.py +313 -0
- package/skills/vds-skill/runtime/scripts/tests/test_verify_alembic.py +581 -0
- package/skills/vds-skill/runtime/scripts/tests/test_verify_infra_topology.py +254 -0
- package/skills/vds-skill/runtime/scripts/update_modules_xml.py +194 -0
- package/skills/vds-skill/runtime/scripts/uv-workspace-alignment-verification-2026-03-25.md +128 -0
- package/skills/vds-skill/runtime/scripts/uv-workspace-alignment-verification-2026-04-18.md +100 -0
- package/skills/vds-skill/runtime/scripts/validate-cli-standardization.sh +188 -0
- package/skills/vds-skill/runtime/scripts/validate_brd_coverage.py +197 -0
- package/skills/vds-skill/runtime/scripts/validate_folder_structure.py +234 -0
- package/skills/vds-skill/runtime/scripts/validate_link_integrity.py +274 -0
- package/skills/vds-skill/runtime/scripts/vami017-caller-compat-report.md +62 -0
- package/skills/vds-skill/runtime/scripts/vami017-phase-b-scaffold-notes.md +79 -0
- package/skills/vds-skill/runtime/scripts/vds_sh_helpers.sh +180 -0
- package/skills/vds-skill/runtime/scripts/verification/phase2_portable_paths_ubuntu_docker.sh +26 -0
- package/skills/vds-skill/runtime/scripts/verify-infra-topology.py +868 -0
- package/skills/vds-skill/runtime/scripts/verify-memory-cli-e2e.sh +598 -0
- package/skills/vds-skill/runtime/scripts/verify-worktree-features.sh +306 -0
- package/skills/vds-skill/runtime/scripts/worktree-add.sh +128 -0
- package/skills/vds-skill/runtime/scripts/worktree-remove.sh +112 -0
- package/skills/vds-skill/runtime/scripts/worktree_compose.sh +269 -0
- package/skills/vds-skill/runtime/scripts/worktree_uv.sh +77 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/IMPLEMENTATION_AUDIT.md +376 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/README.md +507 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/pyproject.toml +106 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/scripts/ensure_symlink.sh +38 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/__init__.py +164 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/batch.py +212 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/cli.py +1407 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/client.py +608 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/config.py +260 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/diff.py +220 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/errors.py +34 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/external_sca.py +932 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/portfolio.py +225 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/pr.py +505 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/reports.py +342 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/scanner.py +351 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/webhooks.py +269 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/conftest.py +134 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_batch.py +419 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_config.py +145 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_errors.py +78 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_external_sca.py +466 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_pr.py +471 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_reports.py +511 -0
- package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_webhooks.py +660 -0
- package/skills/vds-skill/runtime/uv.lock +5046 -0
- package/skills/vds-skill/runtime/vds_agent_core/CHANGELOG.md +36 -0
- package/skills/vds-skill/runtime/vds_agent_core/README.md +453 -0
- package/skills/vds-skill/runtime/vds_agent_core/docs/PHASE9A_ASSESSMENT.md +50 -0
- package/skills/vds-skill/runtime/vds_agent_core/docs/embedding.md +468 -0
- package/skills/vds-skill/runtime/vds_agent_core/pyproject.toml +51 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/__init__.py +29 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/__init__.py +26 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/hooks.py +119 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/loop.py +864 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/tools.py +41 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/config.py +252 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/__init__.py +55 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/_cascade.py +143 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/budget.py +353 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/cache.py +373 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/embedding.py +815 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/provider.py +173 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/schemas.py +45 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/__init__.py +77 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/decorators.py +258 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/jsonl_exporter.py +236 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/tracer.py +497 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/profiles.py +2015 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/runtime/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/runtime/agent_id.py +60 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/security/__init__.py +13 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/security/credentials.py +106 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/__init__.py +1 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/executor.py +238 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/manager.py +381 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/policy.py +568 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/workflows/__init__.py +19 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/workflows/langgraph_runner.py +102 -0
- package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/workflows/protocols.py +81 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/conftest.py +62 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/integration/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/integration/test_audit_loop_hooks_integration.py +135 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/integration/test_audit_observability_integration.py +246 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/integration/test_public_api_stability.py +91 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_call_site_parallelism.py +30 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_dimension_guardrail.py +25 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_drop_in_provider_extensibility.py +76 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding.py +393 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding_cache.py +302 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding_extra.py +696 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding_subclass.py +49 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_no_provider_leakage_in_env.py +34 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_provider_auto_route.py +48 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_runtime_log_clean.py +111 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_w7_logic_fixes.py +219 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_embedding_block_parser.py +194 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_env_resolver_allowlist.py +141 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_profile_authorization.py +158 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_profiles_w3_extra.py +547 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_real_audit_profile_compat.py +129 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/runtime/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/runtime/test_for_agent.py +322 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/runtime/test_w9_cascade_edges.py +369 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/security/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/security/test_credentials.py +132 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_agent_loop.py +663 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_agent_loop_coverage.py +429 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_agents_hooks_defaults.py +22 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_budget.py +155 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_budget_coverage.py +264 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_budget_tracking_only.py +71 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_cache.py +251 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_cache_context.py +62 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_config.py +155 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_langgraph_runner.py +45 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_langgraph_runner_coverage.py +98 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_llm_cache_deep.py +113 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_decorators.py +697 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_hooks.py +217 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_jsonl_exporter.py +542 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_jsonl_wiring.py +313 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_tracer.py +896 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_profiles.py +1571 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_profiles_coverage.py +444 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_provider.py +316 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_schemas.py +63 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_executor.py +297 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_manager.py +370 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_manager_coverage.py +364 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_policy.py +402 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_rubric.py +47 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_tools.py +51 -0
- package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_workflow_protocols.py +136 -0
- package/skills/vds-skill/runtime/vds_cli/README.md +201 -0
- package/skills/vds-skill/runtime/vds_cli/VERIFICATION_REPORT.md +41 -0
- package/skills/vds-skill/runtime/vds_cli/pyproject.toml +50 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/__init__.py +3 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/assets/git-credential-helper.py +235 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/cli.py +1126 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/commands/__init__.py +1 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/commands/lint_cli.py +389 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/confluence_sync.py +855 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/consumption/__init__.py +7 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/consumption/funnel.py +105 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/consumption/scanner.py +211 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/freshness/report.py +90 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/types.py +27 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs_cmd.py +672 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs_metrics.py +75 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs_sync.py +1171 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/ecosystem/__init__.py +39 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/ecosystem/report.py +439 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/ecosystem_docs.py +164 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/env.py +111 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/env_git_helper.py +281 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/google_sheets_orchestrator/__init__.py +3 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/google_sheets_orchestrator/google_sheets_orchestrator.py +173 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/router.py +232 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/skills_cmd.py +274 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/sync_api.py +613 -0
- package/skills/vds-skill/runtime/vds_cli/src/vds_cli/sync_service.py +283 -0
- package/skills/vds-skill/runtime/vds_cli/tests/conftest.py +62 -0
- package/skills/vds-skill/runtime/vds_cli/tests/test_env_git_helper_lifecycle.py +261 -0
- package/skills/vds-skill/runtime/vds_cli/tests/test_git_credential_helper.py +240 -0
- package/skills/vds-skill/runtime/vds_cli/tests/test_router_help_proxy.py +43 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_cli.py +241 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_cli_DOC004.py +110 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_confluence_sync.py +315 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_confluence_sync_wave7.py +375 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_consumption_funnel.py +106 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_consumption_scanner.py +144 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_cmd.py +89 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_cmd_wave8.py +161 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_metrics.py +16 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_quality_score.py +61 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_sync.py +417 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_ecosystem_cli_dashboard.py +667 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_ecosystem_cli_dashboard_rendering.py +143 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_ecosystem_docs.py +63 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_env.py +85 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_freshness_report.py +125 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_lint_cli.py +224 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_router.py +101 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_skills_cmd.py +419 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_sync_api.py +357 -0
- package/skills/vds-skill/runtime/vds_cli/tests/unit/test_sync_service.py +170 -0
- package/skills/vds-skill/runtime/vds_cli/tests/verification/conftest.py +51 -0
- package/skills/vds-skill/runtime/vds_cli/tests/verification/test_bitbucket_real.py +32 -0
- package/skills/vds-skill/runtime/vds_cli/tests/verification/test_confluence_real.py +32 -0
- package/skills/vds-skill/runtime/vds_cli/tests/verification/test_jira_real.py +40 -0
- package/skills/vds-skill/runtime/vds_cli_common/README.md +190 -0
- package/skills/vds-skill/runtime/vds_cli_common/pyproject.toml +96 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/__init__.py +36 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/app.py +55 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/completers.py +139 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/context.py +201 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/env.py +163 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/errors.py +440 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/output.py +284 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/paths.py +78 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/testing.py +211 -0
- package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/version.py +85 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/__init__.py +0 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_app.py +126 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_completers.py +148 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_context.py +192 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_env.py +235 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_errors.py +275 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_output.py +229 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_paths.py +61 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_testing.py +138 -0
- package/skills/vds-skill/runtime/vds_cli_common/tests/test_version.py +64 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/README.md +31 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/pyproject.toml +50 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/__init__.py +26 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/cli.py +246 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/client.py +104 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/config.py +82 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.json +3 -0
- package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.py +130 -0
- package/skills/vds-skill/vds-scripts-skill/SKILL.md +129 -0
- package/skills/vds-skill/vds-scripts-skill/references/audit-commands.md +171 -0
- package/skills/vds-skill/vds-scripts-skill/references/capability-index.md +34 -0
- package/skills/vds-skill/vds-scripts-skill/references/development-commands.md +12 -0
- package/skills/vds-skill/vds-scripts-skill/references/google-sheets.md +71 -0
- package/skills/vds-skill/vds-scripts-skill/references/integration-commands.md +17 -0
- package/skills/vds-skill/vds-scripts-skill/references/platform-bootstrap.md +25 -0
- package/skills/vds-skill/vds-scripts-skill/references/specialist-routing.md +14 -0
- package/skills/vds-skill/vds-scripts-skill/references/validation-commands.md +15 -0
|
@@ -0,0 +1,1689 @@
|
|
|
1
|
+
"""Jira adapter using atlassian-python-api (SDK-only)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable, Sequence
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from atlassian import Jira
|
|
9
|
+
from requests import Session
|
|
10
|
+
|
|
11
|
+
from .errors import (
|
|
12
|
+
VDSClientError,
|
|
13
|
+
AuthError,
|
|
14
|
+
ConflictError,
|
|
15
|
+
NotFoundError,
|
|
16
|
+
RateLimitError,
|
|
17
|
+
ResponseError,
|
|
18
|
+
TransportError,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class JiraAdapter:
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
*,
|
|
26
|
+
url: str,
|
|
27
|
+
username: str | None = None,
|
|
28
|
+
password: str | None = None,
|
|
29
|
+
token: str | None = None,
|
|
30
|
+
session: Session | None = None,
|
|
31
|
+
proxy_url: str | None = None,
|
|
32
|
+
cloud: bool = False,
|
|
33
|
+
timeout: int = 30,
|
|
34
|
+
) -> None:
|
|
35
|
+
auth = {}
|
|
36
|
+
if token:
|
|
37
|
+
auth = {"token": token}
|
|
38
|
+
elif username and password:
|
|
39
|
+
auth = {"username": username, "password": password}
|
|
40
|
+
else:
|
|
41
|
+
raise AuthError("Provide either token or username/password")
|
|
42
|
+
|
|
43
|
+
# Proxy injected per-request via Session (not system-wide env vars)
|
|
44
|
+
if proxy_url and session is None:
|
|
45
|
+
session = Session()
|
|
46
|
+
session.proxies = {"http": proxy_url, "https": proxy_url}
|
|
47
|
+
|
|
48
|
+
self._client = Jira(url=url, session=session, cloud=cloud, timeout=timeout, **auth)
|
|
49
|
+
self._is_cloud = cloud or ".atlassian.net" in url.lower()
|
|
50
|
+
|
|
51
|
+
# --- read operations ---
|
|
52
|
+
def jql(self, query: str, *, limit: int = 50, fields: Iterable[str] | None = None) -> dict[str, Any]:
|
|
53
|
+
try:
|
|
54
|
+
return self._client.jql(query, limit=limit, fields=",".join(fields) if fields else None)
|
|
55
|
+
except Exception as exc: # map coarse errors; refine as needed
|
|
56
|
+
_raise_mapped(exc)
|
|
57
|
+
|
|
58
|
+
def get_issue(self, key: str) -> dict[str, Any]:
|
|
59
|
+
try:
|
|
60
|
+
issue = self._client.issue(key)
|
|
61
|
+
if not issue:
|
|
62
|
+
raise NotFoundError(f"Issue not found: {key}")
|
|
63
|
+
return issue
|
|
64
|
+
except Exception as exc:
|
|
65
|
+
_raise_mapped(exc)
|
|
66
|
+
|
|
67
|
+
def list_projects(self) -> list[dict[str, Any]]:
|
|
68
|
+
try:
|
|
69
|
+
projects = self._client.projects()
|
|
70
|
+
return projects if isinstance(projects, list) else list(projects)
|
|
71
|
+
except Exception as exc:
|
|
72
|
+
_raise_mapped(exc)
|
|
73
|
+
|
|
74
|
+
# --- write operations (guarded by CLI) ---
|
|
75
|
+
def create_issue(
|
|
76
|
+
self,
|
|
77
|
+
*,
|
|
78
|
+
project_key: str,
|
|
79
|
+
summary: str,
|
|
80
|
+
issuetype: str,
|
|
81
|
+
description: str | None = None,
|
|
82
|
+
assignee: str | None = None,
|
|
83
|
+
labels: Sequence[str] | None = None,
|
|
84
|
+
extra_fields: dict[str, Any] | None = None,
|
|
85
|
+
) -> dict[str, Any]:
|
|
86
|
+
fields: dict[str, Any] = {
|
|
87
|
+
"project": {"key": project_key},
|
|
88
|
+
"summary": summary,
|
|
89
|
+
"issuetype": {"name": issuetype},
|
|
90
|
+
}
|
|
91
|
+
if description:
|
|
92
|
+
fields["description"] = description
|
|
93
|
+
if assignee:
|
|
94
|
+
# Server/DC uses username key (current behavior, not legacy)
|
|
95
|
+
fields["assignee"] = {"name": assignee}
|
|
96
|
+
if labels:
|
|
97
|
+
fields["labels"] = list(labels)
|
|
98
|
+
if extra_fields:
|
|
99
|
+
fields.update(extra_fields)
|
|
100
|
+
try:
|
|
101
|
+
return self._client.create_issue(fields=fields) # type: ignore[call-arg]
|
|
102
|
+
except Exception as exc:
|
|
103
|
+
_raise_mapped(exc)
|
|
104
|
+
|
|
105
|
+
def update_issue_fields(self, key: str, fields: dict[str, Any]) -> dict[str, Any]:
|
|
106
|
+
try:
|
|
107
|
+
# atlassian-python-api: Jira.update_issue_field(issue_key, fields)
|
|
108
|
+
return self._client.update_issue_field(key, fields) # type: ignore[call-arg]
|
|
109
|
+
except Exception as exc:
|
|
110
|
+
_raise_mapped(exc)
|
|
111
|
+
|
|
112
|
+
def add_comment(self, key: str, message: str) -> dict[str, Any]:
|
|
113
|
+
"""Add comment to issue."""
|
|
114
|
+
try:
|
|
115
|
+
return self._client.issue_add_comment(key, message) # type: ignore[attr-defined]
|
|
116
|
+
except Exception as exc:
|
|
117
|
+
_raise_mapped(exc)
|
|
118
|
+
|
|
119
|
+
def get_comments(self, key: str) -> list[dict[str, Any]]:
|
|
120
|
+
"""Get comments from issue."""
|
|
121
|
+
try:
|
|
122
|
+
result = self._client.issue_get_comments(key) # type: ignore[attr-defined]
|
|
123
|
+
if isinstance(result, dict) and "comments" in result:
|
|
124
|
+
return result["comments"]
|
|
125
|
+
return result if isinstance(result, list) else []
|
|
126
|
+
except Exception as exc:
|
|
127
|
+
_raise_mapped(exc)
|
|
128
|
+
|
|
129
|
+
def transition_issue(self, key: str, to_status: str) -> None:
|
|
130
|
+
try:
|
|
131
|
+
transitions = self.get_issue_transitions(key)
|
|
132
|
+
if not transitions:
|
|
133
|
+
raise VDSClientError(f"No transitions available for {key}")
|
|
134
|
+
match = None
|
|
135
|
+
for t in transitions:
|
|
136
|
+
name = str(t.get("name", ""))
|
|
137
|
+
if name.lower() == to_status.lower():
|
|
138
|
+
match = t.get("id")
|
|
139
|
+
break
|
|
140
|
+
if not match:
|
|
141
|
+
raise VDSClientError(f"Transition '{to_status}' not found for {key}")
|
|
142
|
+
|
|
143
|
+
transition_id = int(match)
|
|
144
|
+
# Prefer official atlassian-python-api transition APIs.
|
|
145
|
+
if hasattr(self._client, "set_issue_status_by_transition_id"):
|
|
146
|
+
self._client.set_issue_status_by_transition_id(key, transition_id) # type: ignore[attr-defined]
|
|
147
|
+
return
|
|
148
|
+
if hasattr(self._client, "set_issue_status_by_transition_name"):
|
|
149
|
+
self._client.set_issue_status_by_transition_name(key, to_status) # type: ignore[attr-defined]
|
|
150
|
+
return
|
|
151
|
+
if hasattr(self._client, "issue_transition"):
|
|
152
|
+
self._client.issue_transition(key, to_status) # type: ignore[attr-defined]
|
|
153
|
+
return
|
|
154
|
+
raise VDSClientError("Jira client does not support issue transition APIs")
|
|
155
|
+
except Exception as exc:
|
|
156
|
+
_raise_mapped(exc)
|
|
157
|
+
|
|
158
|
+
def delete_issue(self, key: str) -> None:
|
|
159
|
+
try:
|
|
160
|
+
self._client.delete_issue(key)
|
|
161
|
+
except Exception as exc:
|
|
162
|
+
_raise_mapped(exc)
|
|
163
|
+
|
|
164
|
+
# --- metadata operations ---
|
|
165
|
+
def get_createmeta(
|
|
166
|
+
self, project_key: str, issuetype: str | None = None, expand: str | None = None
|
|
167
|
+
) -> dict[str, Any]:
|
|
168
|
+
"""Get create metadata for issue creation (field definitions, allowed values).
|
|
169
|
+
|
|
170
|
+
Prefer the newer createmeta endpoints and fall back to legacy createmeta when needed.
|
|
171
|
+
"""
|
|
172
|
+
legacy_expand = expand or "projects.issuetypes.fields"
|
|
173
|
+
|
|
174
|
+
if issuetype:
|
|
175
|
+
try:
|
|
176
|
+
return self._get_createmeta_v2(project_key, issuetype)
|
|
177
|
+
except Exception as exc:
|
|
178
|
+
if not self._createmeta_should_fallback(exc):
|
|
179
|
+
_raise_mapped(exc)
|
|
180
|
+
|
|
181
|
+
try:
|
|
182
|
+
return self._get_createmeta_legacy(project_key, issuetype=issuetype, expand=legacy_expand)
|
|
183
|
+
except Exception:
|
|
184
|
+
try:
|
|
185
|
+
return self._get_createmeta_legacy_rest(project_key, issuetype=issuetype, expand=legacy_expand)
|
|
186
|
+
except Exception as fallback_exc:
|
|
187
|
+
_raise_mapped(fallback_exc)
|
|
188
|
+
|
|
189
|
+
raise VDSClientError("Unexpected createmeta fallback path") # pragma: no cover
|
|
190
|
+
|
|
191
|
+
def _get_createmeta_v2(self, project_key: str, issuetype: str) -> dict[str, Any]:
|
|
192
|
+
if not hasattr(self._client, "issue_createmeta_issuetypes") or not hasattr(
|
|
193
|
+
self._client, "issue_createmeta_fieldtypes"
|
|
194
|
+
):
|
|
195
|
+
raise VDSClientError("Jira client does not support createmeta v2 endpoints")
|
|
196
|
+
|
|
197
|
+
issue_types, issuetypes_payload = self._collect_createmeta_issuetypes(project_key)
|
|
198
|
+
matched = self._match_createmeta_issuetype(issue_types, issuetype)
|
|
199
|
+
if not matched:
|
|
200
|
+
raise VDSClientError(f"Issue type '{issuetype}' not found for project '{project_key}'")
|
|
201
|
+
|
|
202
|
+
issue_type_id = self._extract_createmeta_issuetype_id(matched)
|
|
203
|
+
if not issue_type_id:
|
|
204
|
+
raise VDSClientError(f"Issue type id not available for '{issuetype}' in project '{project_key}'")
|
|
205
|
+
|
|
206
|
+
fields_payload = self._collect_createmeta_fields(project_key, issue_type_id)
|
|
207
|
+
fields = self._normalize_createmeta_fields(fields_payload)
|
|
208
|
+
|
|
209
|
+
issue_type_entry = dict(matched)
|
|
210
|
+
issue_type_entry["fields"] = fields
|
|
211
|
+
|
|
212
|
+
project_entry: dict[str, Any] = {"key": project_key}
|
|
213
|
+
project_id = None
|
|
214
|
+
if isinstance(issuetypes_payload, dict):
|
|
215
|
+
project_id = issuetypes_payload.get("projectId") or issuetypes_payload.get("project_id")
|
|
216
|
+
if not project_id and isinstance(issuetypes_payload.get("project"), dict):
|
|
217
|
+
project_id = issuetypes_payload["project"].get("id") or issuetypes_payload["project"].get("key")
|
|
218
|
+
if project_id:
|
|
219
|
+
project_entry["id"] = str(project_id)
|
|
220
|
+
|
|
221
|
+
return {"projects": [{**project_entry, "issuetypes": [issue_type_entry]}]}
|
|
222
|
+
|
|
223
|
+
def _collect_createmeta_issuetypes(self, project_key: str) -> tuple[list[dict[str, Any]], dict[str, Any] | None]:
|
|
224
|
+
start = 0
|
|
225
|
+
limit = 100
|
|
226
|
+
items: list[dict[str, Any]] = []
|
|
227
|
+
last_payload: dict[str, Any] | None = None
|
|
228
|
+
|
|
229
|
+
while True:
|
|
230
|
+
payload = self._client.issue_createmeta_issuetypes(project_key, start=start, limit=limit) # type: ignore[attr-defined]
|
|
231
|
+
if isinstance(payload, dict):
|
|
232
|
+
last_payload = payload
|
|
233
|
+
|
|
234
|
+
page_items = self._createmeta_list_from_payload(payload, ("values", "issueTypes", "issuetypes"))
|
|
235
|
+
if page_items:
|
|
236
|
+
items.extend(page_items)
|
|
237
|
+
if isinstance(payload, list):
|
|
238
|
+
break
|
|
239
|
+
|
|
240
|
+
if self._createmeta_page_is_last(payload, start=start, fetched=len(page_items), limit=limit):
|
|
241
|
+
break
|
|
242
|
+
|
|
243
|
+
if not page_items:
|
|
244
|
+
break
|
|
245
|
+
|
|
246
|
+
start = self._createmeta_next_start(payload, start=start, fetched=len(page_items), limit=limit)
|
|
247
|
+
|
|
248
|
+
return items, last_payload
|
|
249
|
+
|
|
250
|
+
def _collect_createmeta_fields(self, project_key: str, issue_type_id: str) -> dict[str, Any] | list[dict[str, Any]]:
|
|
251
|
+
start = 0
|
|
252
|
+
limit = 200
|
|
253
|
+
items: list[dict[str, Any]] = []
|
|
254
|
+
|
|
255
|
+
while True:
|
|
256
|
+
payload = self._client.issue_createmeta_fieldtypes(project_key, issue_type_id, start=start, limit=limit) # type: ignore[attr-defined]
|
|
257
|
+
if isinstance(payload, dict) and isinstance(payload.get("fields"), dict):
|
|
258
|
+
return payload["fields"]
|
|
259
|
+
|
|
260
|
+
page_items = self._createmeta_list_from_payload(payload, ("fields", "values"))
|
|
261
|
+
if page_items:
|
|
262
|
+
items.extend(page_items)
|
|
263
|
+
if isinstance(payload, list):
|
|
264
|
+
break
|
|
265
|
+
|
|
266
|
+
if self._createmeta_page_is_last(payload, start=start, fetched=len(page_items), limit=limit):
|
|
267
|
+
break
|
|
268
|
+
|
|
269
|
+
if not page_items:
|
|
270
|
+
break
|
|
271
|
+
|
|
272
|
+
start = self._createmeta_next_start(payload, start=start, fetched=len(page_items), limit=limit)
|
|
273
|
+
|
|
274
|
+
return items
|
|
275
|
+
|
|
276
|
+
@staticmethod
|
|
277
|
+
def _normalize_createmeta_fields(fields_payload: dict[str, Any] | list[dict[str, Any]]) -> dict[str, Any]:
|
|
278
|
+
if isinstance(fields_payload, dict):
|
|
279
|
+
if isinstance(fields_payload.get("fields"), list):
|
|
280
|
+
fields_payload = fields_payload["fields"]
|
|
281
|
+
elif isinstance(fields_payload.get("values"), list):
|
|
282
|
+
fields_payload = fields_payload["values"]
|
|
283
|
+
else:
|
|
284
|
+
return fields_payload
|
|
285
|
+
|
|
286
|
+
fields: dict[str, Any] = {}
|
|
287
|
+
for item in fields_payload:
|
|
288
|
+
if not isinstance(item, dict):
|
|
289
|
+
continue
|
|
290
|
+
field_id = str(item.get("fieldId") or item.get("id") or item.get("key") or item.get("name") or "")
|
|
291
|
+
if not field_id:
|
|
292
|
+
continue
|
|
293
|
+
field_info = dict(item)
|
|
294
|
+
if "name" not in field_info and item.get("key"):
|
|
295
|
+
field_info["name"] = str(item["key"])
|
|
296
|
+
fields[field_id] = field_info
|
|
297
|
+
|
|
298
|
+
return fields
|
|
299
|
+
|
|
300
|
+
@staticmethod
|
|
301
|
+
def _match_createmeta_issuetype(issue_types: list[dict[str, Any]], issuetype: str) -> dict[str, Any] | None:
|
|
302
|
+
target = issuetype.strip().lower()
|
|
303
|
+
for issue_type in issue_types:
|
|
304
|
+
if not isinstance(issue_type, dict):
|
|
305
|
+
continue
|
|
306
|
+
type_id = str(issue_type.get("id") or issue_type.get("issueTypeId") or issue_type.get("issuetypeId") or "")
|
|
307
|
+
type_name = str(issue_type.get("name") or issue_type.get("issueType") or issue_type.get("value") or "")
|
|
308
|
+
if type_id and type_id == issuetype:
|
|
309
|
+
return issue_type
|
|
310
|
+
if type_name and type_name.lower() == target:
|
|
311
|
+
return issue_type
|
|
312
|
+
return None
|
|
313
|
+
|
|
314
|
+
@staticmethod
|
|
315
|
+
def _extract_createmeta_issuetype_id(issue_type: dict[str, Any]) -> str | None:
|
|
316
|
+
for key in ("id", "issueTypeId", "issuetypeId"):
|
|
317
|
+
value = issue_type.get(key)
|
|
318
|
+
if value:
|
|
319
|
+
return str(value)
|
|
320
|
+
return None
|
|
321
|
+
|
|
322
|
+
@staticmethod
|
|
323
|
+
def _createmeta_list_from_payload(payload: Any, keys: Sequence[str]) -> list[dict[str, Any]]:
|
|
324
|
+
if isinstance(payload, list):
|
|
325
|
+
return [item for item in payload if isinstance(item, dict)]
|
|
326
|
+
if not isinstance(payload, dict):
|
|
327
|
+
return []
|
|
328
|
+
for key in keys:
|
|
329
|
+
value = payload.get(key)
|
|
330
|
+
if isinstance(value, list):
|
|
331
|
+
return [item for item in value if isinstance(item, dict)]
|
|
332
|
+
return []
|
|
333
|
+
|
|
334
|
+
@staticmethod
|
|
335
|
+
def _createmeta_page_is_last(payload: Any, start: int, fetched: int, limit: int) -> bool:
|
|
336
|
+
if isinstance(payload, dict):
|
|
337
|
+
if payload.get("isLast") is True or payload.get("last") is True:
|
|
338
|
+
return True
|
|
339
|
+
total = payload.get("total")
|
|
340
|
+
if total is not None:
|
|
341
|
+
start_at = JiraAdapter._coerce_int(payload.get("startAt", payload.get("start", start)), start)
|
|
342
|
+
size = JiraAdapter._coerce_int(payload.get("maxResults", payload.get("size", limit)), limit)
|
|
343
|
+
if fetched:
|
|
344
|
+
size = fetched
|
|
345
|
+
return start_at + size >= JiraAdapter._coerce_int(total, 0)
|
|
346
|
+
return fetched < limit
|
|
347
|
+
|
|
348
|
+
@staticmethod
|
|
349
|
+
def _createmeta_next_start(payload: Any, start: int, fetched: int, limit: int) -> int:
|
|
350
|
+
if isinstance(payload, dict):
|
|
351
|
+
start_at = JiraAdapter._coerce_int(payload.get("startAt", payload.get("start", start)), start)
|
|
352
|
+
size = JiraAdapter._coerce_int(payload.get("maxResults", payload.get("size", limit)), limit)
|
|
353
|
+
if fetched:
|
|
354
|
+
size = fetched
|
|
355
|
+
return start_at + size
|
|
356
|
+
return start + (fetched or limit)
|
|
357
|
+
|
|
358
|
+
@staticmethod
|
|
359
|
+
def _coerce_int(value: Any, default: int = 0) -> int:
|
|
360
|
+
try:
|
|
361
|
+
return int(value)
|
|
362
|
+
except (TypeError, ValueError):
|
|
363
|
+
return default
|
|
364
|
+
|
|
365
|
+
@staticmethod
|
|
366
|
+
def _coerce_list_items(payload: Any, preferred_keys: tuple[str, ...] = ("values",)) -> list[dict[str, Any]]:
|
|
367
|
+
"""Normalize Jira SDK responses that may be list or paginated dict payloads."""
|
|
368
|
+
if isinstance(payload, list):
|
|
369
|
+
return [item for item in payload if isinstance(item, dict)]
|
|
370
|
+
if isinstance(payload, dict):
|
|
371
|
+
for key in preferred_keys:
|
|
372
|
+
value = payload.get(key)
|
|
373
|
+
if isinstance(value, list):
|
|
374
|
+
return [item for item in value if isinstance(item, dict)]
|
|
375
|
+
for fallback_key in ("values", "issues", "epics", "sprints", "versions", "dashboards", "properties"):
|
|
376
|
+
value = payload.get(fallback_key)
|
|
377
|
+
if isinstance(value, list):
|
|
378
|
+
return [item for item in value if isinstance(item, dict)]
|
|
379
|
+
return []
|
|
380
|
+
|
|
381
|
+
@staticmethod
|
|
382
|
+
def _createmeta_should_fallback(exc: Exception) -> bool:
|
|
383
|
+
response = getattr(exc, "response", None)
|
|
384
|
+
if response is not None:
|
|
385
|
+
try:
|
|
386
|
+
if int(getattr(response, "status_code", 0)) in (404, 405, 410):
|
|
387
|
+
return True
|
|
388
|
+
except (TypeError, ValueError):
|
|
389
|
+
pass
|
|
390
|
+
text = str(exc).lower()
|
|
391
|
+
return any(
|
|
392
|
+
token in text
|
|
393
|
+
for token in (
|
|
394
|
+
"404",
|
|
395
|
+
"405",
|
|
396
|
+
"not found",
|
|
397
|
+
"unknown resource",
|
|
398
|
+
"not supported",
|
|
399
|
+
"does not support",
|
|
400
|
+
"not support",
|
|
401
|
+
)
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
def _get_createmeta_legacy(
|
|
405
|
+
self, project_key: str, *, issuetype: str | None = None, expand: str | None = None
|
|
406
|
+
) -> dict[str, Any]:
|
|
407
|
+
kwargs = {}
|
|
408
|
+
if expand:
|
|
409
|
+
kwargs["expand"] = expand
|
|
410
|
+
payload = self._client.issue_createmeta(project_key, **kwargs)
|
|
411
|
+
if issuetype:
|
|
412
|
+
payload = self._filter_createmeta_payload(payload, project_key=project_key, issuetype=issuetype)
|
|
413
|
+
return payload
|
|
414
|
+
|
|
415
|
+
def _get_createmeta_legacy_rest(
|
|
416
|
+
self, project_key: str, *, issuetype: str | None = None, expand: str | None = None
|
|
417
|
+
) -> dict[str, Any]:
|
|
418
|
+
params: dict[str, Any] = {"projectKeys": project_key}
|
|
419
|
+
if issuetype:
|
|
420
|
+
param_name = "issuetypeIds" if issuetype.isdigit() else "issuetypeNames"
|
|
421
|
+
params[param_name] = issuetype
|
|
422
|
+
if expand:
|
|
423
|
+
params["expand"] = expand
|
|
424
|
+
|
|
425
|
+
base_url = self._client.resource_url("issue") # type: ignore[attr-defined]
|
|
426
|
+
url = f"{base_url}/createmeta"
|
|
427
|
+
return self._client.get(url, params=params) # type: ignore[attr-defined]
|
|
428
|
+
|
|
429
|
+
@staticmethod
|
|
430
|
+
def _filter_createmeta_payload(payload: dict[str, Any], *, project_key: str, issuetype: str) -> dict[str, Any]:
|
|
431
|
+
if not isinstance(payload, dict):
|
|
432
|
+
return payload
|
|
433
|
+
projects = payload.get("projects")
|
|
434
|
+
if not isinstance(projects, list):
|
|
435
|
+
return payload
|
|
436
|
+
|
|
437
|
+
filtered_projects: list[dict[str, Any]] = []
|
|
438
|
+
for project in projects:
|
|
439
|
+
if not isinstance(project, dict):
|
|
440
|
+
continue
|
|
441
|
+
project_key_match = str(project.get("key", "")).lower() == project_key.lower()
|
|
442
|
+
project_id_match = str(project.get("id", "")) == project_key
|
|
443
|
+
if not (project_key_match or project_id_match):
|
|
444
|
+
continue
|
|
445
|
+
|
|
446
|
+
issuetypes = project.get("issuetypes", [])
|
|
447
|
+
if isinstance(issuetypes, list):
|
|
448
|
+
filtered_types = []
|
|
449
|
+
for issue_type in issuetypes:
|
|
450
|
+
if not isinstance(issue_type, dict):
|
|
451
|
+
continue
|
|
452
|
+
name = str(issue_type.get("name", "")).lower()
|
|
453
|
+
type_id = str(issue_type.get("id", ""))
|
|
454
|
+
if name == issuetype.lower() or type_id == issuetype:
|
|
455
|
+
filtered_types.append(issue_type)
|
|
456
|
+
if filtered_types:
|
|
457
|
+
project_copy = dict(project)
|
|
458
|
+
project_copy["issuetypes"] = filtered_types
|
|
459
|
+
filtered_projects.append(project_copy)
|
|
460
|
+
|
|
461
|
+
if filtered_projects:
|
|
462
|
+
payload_copy = dict(payload)
|
|
463
|
+
payload_copy["projects"] = filtered_projects
|
|
464
|
+
return payload_copy
|
|
465
|
+
|
|
466
|
+
return payload
|
|
467
|
+
|
|
468
|
+
def get_editmeta(self, issue_key: str) -> dict[str, Any]:
|
|
469
|
+
"""Get edit metadata for issue updates (field definitions, allowed values)."""
|
|
470
|
+
try:
|
|
471
|
+
if hasattr(self._client, "issue_editmeta"):
|
|
472
|
+
return self._client.issue_editmeta(issue_key) # type: ignore[attr-defined]
|
|
473
|
+
|
|
474
|
+
get_fn = getattr(self._client, "get", None)
|
|
475
|
+
if not get_fn:
|
|
476
|
+
raise VDSClientError("Jira client does not support editmeta lookup")
|
|
477
|
+
|
|
478
|
+
resource_url = getattr(self._client, "resource_url", None)
|
|
479
|
+
if callable(resource_url):
|
|
480
|
+
base_url = resource_url("issue")
|
|
481
|
+
url = f"{base_url}/{issue_key}/editmeta"
|
|
482
|
+
return get_fn(url)
|
|
483
|
+
|
|
484
|
+
return get_fn(f"issue/{issue_key}/editmeta")
|
|
485
|
+
except Exception as exc:
|
|
486
|
+
_raise_mapped(exc)
|
|
487
|
+
|
|
488
|
+
# --- issue utilities ---
|
|
489
|
+
def issue_exists(self, key: str) -> bool:
|
|
490
|
+
"""Check if issue exists."""
|
|
491
|
+
try:
|
|
492
|
+
return self._client.issue_exists(key) # type: ignore[attr-defined]
|
|
493
|
+
except Exception as exc:
|
|
494
|
+
_raise_mapped(exc)
|
|
495
|
+
|
|
496
|
+
def issue_deleted(self, key: str) -> bool:
|
|
497
|
+
"""Check if issue is deleted."""
|
|
498
|
+
try:
|
|
499
|
+
return self._client.issue_deleted(key) # type: ignore[attr-defined]
|
|
500
|
+
except Exception as exc:
|
|
501
|
+
_raise_mapped(exc)
|
|
502
|
+
|
|
503
|
+
def match_jql(self, issue_ids: list[str], jqls: list[str]) -> dict[str, Any]:
|
|
504
|
+
"""Check issues against JQL queries."""
|
|
505
|
+
try:
|
|
506
|
+
return self._client.match_jql(issue_ids, jqls) # type: ignore[attr-defined]
|
|
507
|
+
except Exception as exc:
|
|
508
|
+
_raise_mapped(exc)
|
|
509
|
+
|
|
510
|
+
def get_issue_field_value(self, key: str, field: str) -> Any:
|
|
511
|
+
"""Get issue field value."""
|
|
512
|
+
try:
|
|
513
|
+
return self._client.issue_field_value(key, field) # type: ignore[attr-defined]
|
|
514
|
+
except Exception as exc:
|
|
515
|
+
_raise_mapped(exc)
|
|
516
|
+
|
|
517
|
+
def append_issue_field_value(self, key: str, field: str, value: Any, notify_users: bool = True) -> dict[str, Any]:
|
|
518
|
+
"""Append value to issue field (e.g., for multi-select fields)."""
|
|
519
|
+
try:
|
|
520
|
+
return self._client.issue_field_value_append(key, field, value, notify_users=notify_users) # type: ignore[attr-defined]
|
|
521
|
+
except Exception as exc:
|
|
522
|
+
_raise_mapped(exc)
|
|
523
|
+
|
|
524
|
+
# --- attachment operations ---
|
|
525
|
+
def add_attachment(self, key: str, filename: str) -> dict[str, Any]:
|
|
526
|
+
"""Add attachment to issue."""
|
|
527
|
+
try:
|
|
528
|
+
return self._client.add_attachment(key, filename) # type: ignore[attr-defined]
|
|
529
|
+
except Exception as exc:
|
|
530
|
+
_raise_mapped(exc)
|
|
531
|
+
|
|
532
|
+
def get_attachments(self, key: str) -> list[dict[str, Any]]:
|
|
533
|
+
"""Get list of attachments for issue."""
|
|
534
|
+
try:
|
|
535
|
+
issue = self.get_issue(key)
|
|
536
|
+
return issue.get("fields", {}).get("attachment", [])
|
|
537
|
+
except Exception as exc:
|
|
538
|
+
_raise_mapped(exc)
|
|
539
|
+
|
|
540
|
+
def download_attachments(self, key: str, path: str | None = None, cloud: bool = False) -> list[str]:
|
|
541
|
+
"""Download attachments from issue."""
|
|
542
|
+
try:
|
|
543
|
+
issue = self.get_issue(key)
|
|
544
|
+
return self._client.download_attachments_from_issue(issue, path=path, cloud=cloud) # type: ignore[attr-defined]
|
|
545
|
+
except Exception as exc:
|
|
546
|
+
_raise_mapped(exc)
|
|
547
|
+
|
|
548
|
+
# --- project operations ---
|
|
549
|
+
def get_project(self, key: str, expand: str | None = None) -> dict[str, Any]:
|
|
550
|
+
"""Get project details."""
|
|
551
|
+
try:
|
|
552
|
+
return self._client.project(key, expand=expand) # type: ignore[attr-defined]
|
|
553
|
+
except Exception as exc:
|
|
554
|
+
_raise_mapped(exc)
|
|
555
|
+
|
|
556
|
+
def get_project_components(self, key: str) -> list[dict[str, Any]]:
|
|
557
|
+
"""Get project components."""
|
|
558
|
+
try:
|
|
559
|
+
return self._client.get_project_components(key) # type: ignore[attr-defined]
|
|
560
|
+
except Exception as exc:
|
|
561
|
+
_raise_mapped(exc)
|
|
562
|
+
|
|
563
|
+
def get_project_versions(self, key: str, expand: str | None = None) -> list[dict[str, Any]]:
|
|
564
|
+
"""Get project versions."""
|
|
565
|
+
try:
|
|
566
|
+
return self._client.get_project_versions(key, expand=expand) # type: ignore[attr-defined]
|
|
567
|
+
except Exception as exc:
|
|
568
|
+
_raise_mapped(exc)
|
|
569
|
+
|
|
570
|
+
def add_version(
|
|
571
|
+
self,
|
|
572
|
+
key: str,
|
|
573
|
+
project_id: str,
|
|
574
|
+
version: str,
|
|
575
|
+
is_archived: bool = False,
|
|
576
|
+
is_released: bool = False,
|
|
577
|
+
) -> dict[str, Any]:
|
|
578
|
+
"""Add version to project."""
|
|
579
|
+
try:
|
|
580
|
+
return self._client.add_version(key, project_id, version, is_archived=is_archived, is_released=is_released) # type: ignore[attr-defined]
|
|
581
|
+
except Exception as exc:
|
|
582
|
+
_raise_mapped(exc)
|
|
583
|
+
|
|
584
|
+
def update_version(
|
|
585
|
+
self,
|
|
586
|
+
version: str,
|
|
587
|
+
name: str | None = None,
|
|
588
|
+
description: str | None = None,
|
|
589
|
+
is_archived: bool | None = None,
|
|
590
|
+
is_released: bool | None = None,
|
|
591
|
+
start_date: str | None = None,
|
|
592
|
+
release_date: str | None = None,
|
|
593
|
+
) -> dict[str, Any]:
|
|
594
|
+
"""Update version."""
|
|
595
|
+
try:
|
|
596
|
+
return self._client.update_version( # type: ignore[attr-defined]
|
|
597
|
+
version,
|
|
598
|
+
name=name,
|
|
599
|
+
description=description,
|
|
600
|
+
is_archived=is_archived,
|
|
601
|
+
is_released=is_released,
|
|
602
|
+
start_date=start_date,
|
|
603
|
+
release_date=release_date,
|
|
604
|
+
)
|
|
605
|
+
except Exception as exc:
|
|
606
|
+
_raise_mapped(exc)
|
|
607
|
+
|
|
608
|
+
# --- component operations ---
|
|
609
|
+
def get_component(self, component_id: str) -> dict[str, Any]:
|
|
610
|
+
"""Get component details."""
|
|
611
|
+
try:
|
|
612
|
+
return self._client.component(component_id) # type: ignore[attr-defined]
|
|
613
|
+
except Exception as exc:
|
|
614
|
+
_raise_mapped(exc)
|
|
615
|
+
|
|
616
|
+
def create_component(self, component: dict[str, Any]) -> dict[str, Any]:
|
|
617
|
+
"""Create component."""
|
|
618
|
+
try:
|
|
619
|
+
return self._client.create_component(component) # type: ignore[attr-defined]
|
|
620
|
+
except Exception as exc:
|
|
621
|
+
_raise_mapped(exc)
|
|
622
|
+
|
|
623
|
+
def update_component(self, component: dict[str, Any], component_id: str) -> dict[str, Any]:
|
|
624
|
+
"""Update component."""
|
|
625
|
+
try:
|
|
626
|
+
return self._client.update_component(component, component_id) # type: ignore[attr-defined]
|
|
627
|
+
except Exception as exc:
|
|
628
|
+
_raise_mapped(exc)
|
|
629
|
+
|
|
630
|
+
def delete_component(self, component_id: str) -> None:
|
|
631
|
+
"""Delete component."""
|
|
632
|
+
try:
|
|
633
|
+
self._client.delete_component(component_id) # type: ignore[attr-defined]
|
|
634
|
+
except Exception as exc:
|
|
635
|
+
_raise_mapped(exc)
|
|
636
|
+
|
|
637
|
+
# --- user operations ---
|
|
638
|
+
def get_myself(self) -> dict[str, Any]:
|
|
639
|
+
"""Get current user info."""
|
|
640
|
+
try:
|
|
641
|
+
return self._client.myself() # type: ignore[attr-defined]
|
|
642
|
+
except Exception as exc:
|
|
643
|
+
_raise_mapped(exc)
|
|
644
|
+
|
|
645
|
+
def get_user(self, account_id: str) -> dict[str, Any]:
|
|
646
|
+
"""Get user by account ID."""
|
|
647
|
+
try:
|
|
648
|
+
return self._client.user(account_id) # type: ignore[attr-defined]
|
|
649
|
+
except Exception as exc:
|
|
650
|
+
_raise_mapped(exc)
|
|
651
|
+
|
|
652
|
+
def find_users(
|
|
653
|
+
self, query: str, start: int = 0, limit: int = 50, include_inactive: bool = False
|
|
654
|
+
) -> list[dict[str, Any]]:
|
|
655
|
+
"""Find users by email/display name (Cloud) or username (Server/DC)."""
|
|
656
|
+
try:
|
|
657
|
+
return self._client.user_find_by_user_string( # type: ignore[attr-defined]
|
|
658
|
+
query=query, start=start, limit=limit, include_inactive_users=include_inactive
|
|
659
|
+
)
|
|
660
|
+
except Exception as exc:
|
|
661
|
+
_raise_mapped(exc)
|
|
662
|
+
|
|
663
|
+
# --- bulk operations ---
|
|
664
|
+
def bulk_update_issue_field(self, key_list: list[str], fields: str = "*all") -> dict[str, Any]:
|
|
665
|
+
"""Bulk update issue fields."""
|
|
666
|
+
try:
|
|
667
|
+
return self._client.bulk_update_issue_field(key_list, fields=fields) # type: ignore[attr-defined]
|
|
668
|
+
except Exception as exc:
|
|
669
|
+
_raise_mapped(exc)
|
|
670
|
+
|
|
671
|
+
def issue_field_value_append(
|
|
672
|
+
self, issue_id_or_key: str, field: str, value: dict[str, Any], notify_users: bool = True
|
|
673
|
+
) -> dict[str, Any]:
|
|
674
|
+
"""Append value to issue field (for multi-select fields)."""
|
|
675
|
+
try:
|
|
676
|
+
return self._client.issue_field_value_append(issue_id_or_key, field, value, notify_users=notify_users) # type: ignore[attr-defined]
|
|
677
|
+
except Exception as exc:
|
|
678
|
+
_raise_mapped(exc)
|
|
679
|
+
|
|
680
|
+
def issue_archive(self, issue_id_or_key: str) -> None:
|
|
681
|
+
"""Archive an issue."""
|
|
682
|
+
try:
|
|
683
|
+
self._client.issue_archive(issue_id_or_key) # type: ignore[attr-defined]
|
|
684
|
+
except Exception as exc:
|
|
685
|
+
_raise_mapped(exc)
|
|
686
|
+
|
|
687
|
+
def issue_restore(self, issue_id_or_key: str) -> None:
|
|
688
|
+
"""Restore an archived issue."""
|
|
689
|
+
try:
|
|
690
|
+
self._client.issue_restore(issue_id_or_key) # type: ignore[attr-defined]
|
|
691
|
+
except Exception as exc:
|
|
692
|
+
_raise_mapped(exc)
|
|
693
|
+
|
|
694
|
+
def get_attachments_ids_from_issue(self, key: str) -> list[str]:
|
|
695
|
+
"""Get list of attachment IDs from issue."""
|
|
696
|
+
try:
|
|
697
|
+
return self._client.get_attachments_ids_from_issue(key) # type: ignore[attr-defined]
|
|
698
|
+
except Exception as exc:
|
|
699
|
+
_raise_mapped(exc)
|
|
700
|
+
|
|
701
|
+
# --- enhanced project operations ---
|
|
702
|
+
def get_all_projects(
|
|
703
|
+
self, included_archived: bool | None = None, expand: str | None = None
|
|
704
|
+
) -> list[dict[str, Any]]:
|
|
705
|
+
"""Get all projects (alternative call)."""
|
|
706
|
+
try:
|
|
707
|
+
projects = self._client.get_all_projects(included_archived=included_archived, expand=expand) # type: ignore[attr-defined]
|
|
708
|
+
return projects if isinstance(projects, list) else list(projects)
|
|
709
|
+
except Exception as exc:
|
|
710
|
+
_raise_mapped(exc)
|
|
711
|
+
|
|
712
|
+
def get_project_issues_count(self, project_key: str) -> int:
|
|
713
|
+
"""Get project issues count."""
|
|
714
|
+
try:
|
|
715
|
+
return self._client.get_project_issues_count(project_key) # type: ignore[attr-defined]
|
|
716
|
+
except Exception as exc:
|
|
717
|
+
_raise_mapped(exc)
|
|
718
|
+
|
|
719
|
+
def get_all_project_issues(
|
|
720
|
+
self, project_key: str, fields: str = "*all", start: int = 0, limit: int = 500
|
|
721
|
+
) -> list[dict[str, Any]]:
|
|
722
|
+
"""Get all project issues."""
|
|
723
|
+
try:
|
|
724
|
+
return self._client.get_all_project_issues(project_key, fields=fields, start=start, limit=limit) # type: ignore[attr-defined]
|
|
725
|
+
except Exception as exc:
|
|
726
|
+
_raise_mapped(exc)
|
|
727
|
+
|
|
728
|
+
def get_all_assignable_users_for_project(
|
|
729
|
+
self, project_key: str, start: int = 0, limit: int = 50
|
|
730
|
+
) -> list[dict[str, Any]]:
|
|
731
|
+
"""Get all assignable users for project."""
|
|
732
|
+
try:
|
|
733
|
+
return self._client.get_all_assignable_users_for_project(project_key, start=start, limit=limit) # type: ignore[attr-defined]
|
|
734
|
+
except Exception as exc:
|
|
735
|
+
_raise_mapped(exc)
|
|
736
|
+
|
|
737
|
+
def get_project_issuekey_last(self, project_key: str) -> str | None:
|
|
738
|
+
"""Get last project issue key."""
|
|
739
|
+
try:
|
|
740
|
+
return self._client.get_project_issuekey_last(project_key) # type: ignore[attr-defined]
|
|
741
|
+
except Exception as exc:
|
|
742
|
+
_raise_mapped(exc)
|
|
743
|
+
|
|
744
|
+
def get_project_issuekey_all(self, project_key: str) -> list[str]:
|
|
745
|
+
"""Get all project issue keys."""
|
|
746
|
+
try:
|
|
747
|
+
return self._client.get_project_issuekey_all(project_key) # type: ignore[attr-defined]
|
|
748
|
+
except Exception as exc:
|
|
749
|
+
_raise_mapped(exc)
|
|
750
|
+
|
|
751
|
+
def update_project(
|
|
752
|
+
self, project_key: str, data: dict[str, Any], expand: str = "lead,description"
|
|
753
|
+
) -> dict[str, Any]:
|
|
754
|
+
"""Update a project."""
|
|
755
|
+
try:
|
|
756
|
+
return self._client.update_project(project_key, data, expand=expand) # type: ignore[attr-defined]
|
|
757
|
+
except Exception as exc:
|
|
758
|
+
_raise_mapped(exc)
|
|
759
|
+
|
|
760
|
+
def delete_project(self, project_key: str) -> None:
|
|
761
|
+
"""Delete project."""
|
|
762
|
+
try:
|
|
763
|
+
self._client.delete_project(project_key) # type: ignore[attr-defined]
|
|
764
|
+
except Exception as exc:
|
|
765
|
+
_raise_mapped(exc)
|
|
766
|
+
|
|
767
|
+
def archive_project(self, project_key: str) -> None:
|
|
768
|
+
"""Archive project."""
|
|
769
|
+
try:
|
|
770
|
+
self._client.archive_project(project_key) # type: ignore[attr-defined]
|
|
771
|
+
except Exception as exc:
|
|
772
|
+
_raise_mapped(exc)
|
|
773
|
+
|
|
774
|
+
def get_project_versions_paginated(
|
|
775
|
+
self,
|
|
776
|
+
project_key: str,
|
|
777
|
+
start: int | None = None,
|
|
778
|
+
limit: int | None = None,
|
|
779
|
+
order_by: str | None = None,
|
|
780
|
+
expand: str | None = None,
|
|
781
|
+
query: str | None = None,
|
|
782
|
+
status: str | None = None,
|
|
783
|
+
) -> dict[str, Any]:
|
|
784
|
+
"""Get project versions (paginated)."""
|
|
785
|
+
try:
|
|
786
|
+
return self._client.get_project_versions_paginated( # type: ignore[attr-defined]
|
|
787
|
+
project_key, start=start, limit=limit, order_by=order_by, expand=expand, query=query, status=status
|
|
788
|
+
)
|
|
789
|
+
except Exception as exc:
|
|
790
|
+
_raise_mapped(exc)
|
|
791
|
+
|
|
792
|
+
def get_project_permission_scheme(self, project_id_or_key: str, expand: str | None = None) -> dict[str, Any]:
|
|
793
|
+
"""Get project permission scheme."""
|
|
794
|
+
try:
|
|
795
|
+
return self._client.get_project_permission_scheme(project_id_or_key, expand=expand) # type: ignore[attr-defined]
|
|
796
|
+
except Exception as exc:
|
|
797
|
+
_raise_mapped(exc)
|
|
798
|
+
|
|
799
|
+
def get_project_issue_security_scheme(self, project_id_or_key: str, only_levels: bool = False) -> dict[str, Any]:
|
|
800
|
+
"""Get project issue security scheme."""
|
|
801
|
+
try:
|
|
802
|
+
return self._client.get_project_issue_security_scheme(project_id_or_key, only_levels=only_levels) # type: ignore[attr-defined]
|
|
803
|
+
except Exception as exc:
|
|
804
|
+
_raise_mapped(exc)
|
|
805
|
+
|
|
806
|
+
def get_priority_scheme_of_project(self, project_key_or_id: str, expand: str | None = None) -> dict[str, Any]:
|
|
807
|
+
"""Get priority scheme of project."""
|
|
808
|
+
try:
|
|
809
|
+
return self._client.get_priority_scheme_of_project(project_key_or_id, expand=expand) # type: ignore[attr-defined]
|
|
810
|
+
except Exception as exc:
|
|
811
|
+
_raise_mapped(exc)
|
|
812
|
+
|
|
813
|
+
def get_users_with_browse_permission_to_a_project(
|
|
814
|
+
self,
|
|
815
|
+
username: str,
|
|
816
|
+
issue_key: str | None = None,
|
|
817
|
+
project_key: str | None = None,
|
|
818
|
+
start: int = 0,
|
|
819
|
+
limit: int = 100,
|
|
820
|
+
) -> list[dict[str, Any]]:
|
|
821
|
+
"""Get users with browse permission to a project."""
|
|
822
|
+
try:
|
|
823
|
+
return self._client.get_users_with_browse_permission_to_a_project( # type: ignore[attr-defined]
|
|
824
|
+
username, issue_key=issue_key, project_key=project_key, start=start, limit=limit
|
|
825
|
+
)
|
|
826
|
+
except Exception as exc:
|
|
827
|
+
_raise_mapped(exc)
|
|
828
|
+
|
|
829
|
+
# --- custom fields ---
|
|
830
|
+
def get_custom_fields(self, search: str | None = None, start: int = 1, limit: int = 50) -> list[dict[str, Any]]:
|
|
831
|
+
"""Get existing custom fields or find by filter."""
|
|
832
|
+
try:
|
|
833
|
+
return self._client.get_custom_fields(search=search, start=start, limit=limit) # type: ignore[attr-defined]
|
|
834
|
+
except Exception as exc:
|
|
835
|
+
_raise_mapped(exc)
|
|
836
|
+
|
|
837
|
+
# --- user management ---
|
|
838
|
+
def remove_user(self, username: str) -> None:
|
|
839
|
+
"""Remove user."""
|
|
840
|
+
try:
|
|
841
|
+
self._client.user_remove(username) # type: ignore[attr-defined]
|
|
842
|
+
except Exception as exc:
|
|
843
|
+
_raise_mapped(exc)
|
|
844
|
+
|
|
845
|
+
def deactivate_user(self, username: str) -> None:
|
|
846
|
+
"""Deactivate user (works from Jira 8.3.0+)."""
|
|
847
|
+
try:
|
|
848
|
+
self._client.user_deactivate(username) # type: ignore[attr-defined]
|
|
849
|
+
except Exception as exc:
|
|
850
|
+
_raise_mapped(exc)
|
|
851
|
+
|
|
852
|
+
def get_user_groups(self, account_id: str) -> list[dict[str, Any]]:
|
|
853
|
+
"""Get groups of a user (Cloud only)."""
|
|
854
|
+
if not self._is_cloud:
|
|
855
|
+
raise VDSClientError(
|
|
856
|
+
"get_user_groups is only available in Jira Cloud mode",
|
|
857
|
+
context={"url": "unknown"},
|
|
858
|
+
)
|
|
859
|
+
try:
|
|
860
|
+
return self._client.get_user_groups(account_id) # type: ignore[attr-defined]
|
|
861
|
+
except Exception as exc:
|
|
862
|
+
_raise_mapped(exc)
|
|
863
|
+
|
|
864
|
+
# --- group management ---
|
|
865
|
+
def create_group(self, name: str) -> dict[str, Any]:
|
|
866
|
+
"""Create a group."""
|
|
867
|
+
try:
|
|
868
|
+
return self._client.create_group(name) # type: ignore[attr-defined]
|
|
869
|
+
except Exception as exc:
|
|
870
|
+
_raise_mapped(exc)
|
|
871
|
+
|
|
872
|
+
def remove_group(self, name: str, swap_group: str | None = None) -> None:
|
|
873
|
+
"""Delete a group."""
|
|
874
|
+
try:
|
|
875
|
+
self._client.remove_group(name, swap_group=swap_group) # type: ignore[attr-defined]
|
|
876
|
+
except Exception as exc:
|
|
877
|
+
_raise_mapped(exc)
|
|
878
|
+
|
|
879
|
+
def get_all_users_from_group(
|
|
880
|
+
self, group: str, include_inactive_users: bool = False, start: int = 0, limit: int = 50
|
|
881
|
+
) -> list[dict[str, Any]]:
|
|
882
|
+
"""Get all users from group."""
|
|
883
|
+
try:
|
|
884
|
+
return self._client.get_all_users_from_group( # type: ignore[attr-defined]
|
|
885
|
+
group, include_inactive_users=include_inactive_users, start=start, limit=limit
|
|
886
|
+
)
|
|
887
|
+
except Exception as exc:
|
|
888
|
+
_raise_mapped(exc)
|
|
889
|
+
|
|
890
|
+
def add_user_to_group(
|
|
891
|
+
self, username: str | None = None, group_name: str | None = None, account_id: str | None = None
|
|
892
|
+
) -> None:
|
|
893
|
+
"""Add given user to a group."""
|
|
894
|
+
try:
|
|
895
|
+
self._client.add_user_to_group(username=username, group_name=group_name, account_id=account_id) # type: ignore[attr-defined]
|
|
896
|
+
except Exception as exc:
|
|
897
|
+
_raise_mapped(exc)
|
|
898
|
+
|
|
899
|
+
def remove_user_from_group(
|
|
900
|
+
self, username: str | None = None, group_name: str | None = None, account_id: str | None = None
|
|
901
|
+
) -> None:
|
|
902
|
+
"""Remove given user from a group."""
|
|
903
|
+
try:
|
|
904
|
+
self._client.remove_user_from_group(username=username, group_name=group_name, account_id=account_id) # type: ignore[attr-defined]
|
|
905
|
+
except Exception as exc:
|
|
906
|
+
_raise_mapped(exc)
|
|
907
|
+
|
|
908
|
+
# --- permissions ---
|
|
909
|
+
def get_permissions(
|
|
910
|
+
self,
|
|
911
|
+
permissions: list[str] | None = None,
|
|
912
|
+
project_id: str | None = None,
|
|
913
|
+
project_key: str | None = None,
|
|
914
|
+
issue_id: str | None = None,
|
|
915
|
+
issue_key: str | None = None,
|
|
916
|
+
) -> dict[str, Any]:
|
|
917
|
+
"""Get permissions."""
|
|
918
|
+
try:
|
|
919
|
+
permissions_value = ",".join(permissions) if permissions else ""
|
|
920
|
+
if hasattr(self._client, "get_permissions"):
|
|
921
|
+
return self._client.get_permissions( # type: ignore[attr-defined]
|
|
922
|
+
permissions=permissions_value,
|
|
923
|
+
project_id=project_id,
|
|
924
|
+
project_key=project_key,
|
|
925
|
+
issue_id=issue_id,
|
|
926
|
+
issue_key=issue_key,
|
|
927
|
+
)
|
|
928
|
+
raise VDSClientError("Jira client does not support permissions lookup")
|
|
929
|
+
except Exception as exc:
|
|
930
|
+
_raise_mapped(exc)
|
|
931
|
+
|
|
932
|
+
def get_all_permissions(self) -> list[dict[str, Any]]:
|
|
933
|
+
"""Get all permissions."""
|
|
934
|
+
try:
|
|
935
|
+
return self._client.get_all_permissions() # type: ignore[attr-defined]
|
|
936
|
+
except Exception as exc:
|
|
937
|
+
_raise_mapped(exc)
|
|
938
|
+
|
|
939
|
+
# --- application properties ---
|
|
940
|
+
def get_property(
|
|
941
|
+
self,
|
|
942
|
+
key: str | None = None,
|
|
943
|
+
permission_level: str | None = None,
|
|
944
|
+
key_filter: str | None = None,
|
|
945
|
+
) -> dict[str, Any]:
|
|
946
|
+
"""Get an application property."""
|
|
947
|
+
try:
|
|
948
|
+
return self._client.get_property(key=key, permission_level=permission_level, key_filter=key_filter) # type: ignore[attr-defined]
|
|
949
|
+
except Exception as exc:
|
|
950
|
+
_raise_mapped(exc)
|
|
951
|
+
|
|
952
|
+
def set_property(self, property_id: str, value: Any) -> None:
|
|
953
|
+
"""Set an application property."""
|
|
954
|
+
try:
|
|
955
|
+
self._client.set_property(property_id, value) # type: ignore[attr-defined]
|
|
956
|
+
except Exception as exc:
|
|
957
|
+
_raise_mapped(exc)
|
|
958
|
+
|
|
959
|
+
def get_advanced_settings(self) -> dict[str, Any]:
|
|
960
|
+
"""Get advanced settings."""
|
|
961
|
+
try:
|
|
962
|
+
return self._client.get_advanced_settings() # type: ignore[attr-defined]
|
|
963
|
+
except Exception as exc:
|
|
964
|
+
_raise_mapped(exc)
|
|
965
|
+
|
|
966
|
+
# --- issue links ---
|
|
967
|
+
def create_issue_link(self, payload: dict[str, Any]) -> dict[str, Any]:
|
|
968
|
+
"""Create an issue-to-issue link."""
|
|
969
|
+
try:
|
|
970
|
+
return self._client.create_issue_link(payload) # type: ignore[attr-defined]
|
|
971
|
+
except Exception as exc:
|
|
972
|
+
_raise_mapped(exc)
|
|
973
|
+
|
|
974
|
+
def remove_issue_link(self, issue_link_id: str | int) -> None:
|
|
975
|
+
"""Remove an issue-to-issue link by ID."""
|
|
976
|
+
try:
|
|
977
|
+
self._client.remove_issue_link(issue_link_id) # type: ignore[attr-defined]
|
|
978
|
+
except Exception as exc:
|
|
979
|
+
_raise_mapped(exc)
|
|
980
|
+
|
|
981
|
+
# --- issue link types ---
|
|
982
|
+
def get_issue_link_types(self) -> list[dict[str, Any]]:
|
|
983
|
+
"""Get issue link types."""
|
|
984
|
+
try:
|
|
985
|
+
return self._client.get_issue_link_types() # type: ignore[attr-defined]
|
|
986
|
+
except Exception as exc:
|
|
987
|
+
_raise_mapped(exc)
|
|
988
|
+
|
|
989
|
+
def create_issue_link_type(self, data: dict[str, str]) -> dict[str, Any]:
|
|
990
|
+
"""Create issue link type."""
|
|
991
|
+
try:
|
|
992
|
+
return self._client.create_issue_link_type(data) # type: ignore[attr-defined]
|
|
993
|
+
except Exception as exc:
|
|
994
|
+
_raise_mapped(exc)
|
|
995
|
+
|
|
996
|
+
def get_issue_link_type(self, issue_link_type_id: str) -> dict[str, Any]:
|
|
997
|
+
"""Get issue link type by ID."""
|
|
998
|
+
try:
|
|
999
|
+
return self._client.get_issue_link_type(issue_link_type_id) # type: ignore[attr-defined]
|
|
1000
|
+
except Exception as exc:
|
|
1001
|
+
_raise_mapped(exc)
|
|
1002
|
+
|
|
1003
|
+
def delete_issue_link_type(self, issue_link_type_id: str) -> None:
|
|
1004
|
+
"""Delete issue link type."""
|
|
1005
|
+
try:
|
|
1006
|
+
self._client.delete_issue_link_type(issue_link_type_id) # type: ignore[attr-defined]
|
|
1007
|
+
except Exception as exc:
|
|
1008
|
+
_raise_mapped(exc)
|
|
1009
|
+
|
|
1010
|
+
def update_issue_link_type(self, issue_link_type_id: str, data: dict[str, str]) -> dict[str, Any]:
|
|
1011
|
+
"""Update issue link type."""
|
|
1012
|
+
try:
|
|
1013
|
+
return self._client.update_issue_link_type(issue_link_type_id, data) # type: ignore[attr-defined]
|
|
1014
|
+
except Exception as exc:
|
|
1015
|
+
_raise_mapped(exc)
|
|
1016
|
+
|
|
1017
|
+
# --- issue remote links ---
|
|
1018
|
+
def get_issue_remote_links(self, issue_key: str) -> list[dict[str, Any]]:
|
|
1019
|
+
"""List remote links for an issue."""
|
|
1020
|
+
try:
|
|
1021
|
+
result = self._client.get_issue_remote_links(issue_key) # type: ignore[attr-defined]
|
|
1022
|
+
if isinstance(result, list):
|
|
1023
|
+
return result
|
|
1024
|
+
return result or []
|
|
1025
|
+
except Exception as exc:
|
|
1026
|
+
_raise_mapped(exc)
|
|
1027
|
+
|
|
1028
|
+
def create_or_update_issue_remote_link(self, issue_key: str, payload: dict[str, Any]) -> dict[str, Any]:
|
|
1029
|
+
"""Create or update a remote link for an issue."""
|
|
1030
|
+
try:
|
|
1031
|
+
return self._client.create_or_update_issue_remote_links(issue_key, payload) # type: ignore[attr-defined]
|
|
1032
|
+
except Exception as exc:
|
|
1033
|
+
_raise_mapped(exc)
|
|
1034
|
+
|
|
1035
|
+
def get_issue_remote_link_by_id(self, issue_key: str, remote_link_id: str | int) -> dict[str, Any]:
|
|
1036
|
+
"""Get a remote link by ID."""
|
|
1037
|
+
try:
|
|
1038
|
+
return self._client.get_issue_remote_link_by_id(issue_key, remote_link_id) # type: ignore[attr-defined]
|
|
1039
|
+
except Exception as exc:
|
|
1040
|
+
_raise_mapped(exc)
|
|
1041
|
+
|
|
1042
|
+
def update_issue_remote_link_by_id(
|
|
1043
|
+
self,
|
|
1044
|
+
issue_key: str,
|
|
1045
|
+
remote_link_id: str | int,
|
|
1046
|
+
payload: dict[str, Any],
|
|
1047
|
+
) -> dict[str, Any]:
|
|
1048
|
+
"""Update a remote link by ID."""
|
|
1049
|
+
try:
|
|
1050
|
+
return self._client.update_issue_remote_link_by_id(issue_key, remote_link_id, payload) # type: ignore[attr-defined]
|
|
1051
|
+
except Exception as exc:
|
|
1052
|
+
_raise_mapped(exc)
|
|
1053
|
+
|
|
1054
|
+
def delete_issue_remote_link_by_id(self, issue_key: str, remote_link_id: str | int) -> None:
|
|
1055
|
+
"""Delete a remote link by ID."""
|
|
1056
|
+
try:
|
|
1057
|
+
self._client.delete_issue_remote_link_by_id(issue_key, remote_link_id) # type: ignore[attr-defined]
|
|
1058
|
+
except Exception as exc:
|
|
1059
|
+
_raise_mapped(exc)
|
|
1060
|
+
|
|
1061
|
+
# --- issue properties ---
|
|
1062
|
+
def get_issue_property_keys(self, issue_key: str) -> dict[str, Any]:
|
|
1063
|
+
"""Get issue property keys."""
|
|
1064
|
+
try:
|
|
1065
|
+
return self._client.get_issue_property_keys(issue_key) # type: ignore[attr-defined]
|
|
1066
|
+
except Exception as exc:
|
|
1067
|
+
_raise_mapped(exc)
|
|
1068
|
+
|
|
1069
|
+
def set_issue_property(self, issue_key: str, property_key: str, payload: dict[str, Any]) -> None:
|
|
1070
|
+
"""Create or update an issue property."""
|
|
1071
|
+
try:
|
|
1072
|
+
self._client.set_issue_property(issue_key, property_key, payload) # type: ignore[attr-defined]
|
|
1073
|
+
except Exception as exc:
|
|
1074
|
+
_raise_mapped(exc)
|
|
1075
|
+
|
|
1076
|
+
def get_issue_property(self, issue_key: str, property_key: str) -> dict[str, Any]:
|
|
1077
|
+
"""Get an issue property."""
|
|
1078
|
+
try:
|
|
1079
|
+
return self._client.get_issue_property(issue_key, property_key) # type: ignore[attr-defined]
|
|
1080
|
+
except Exception as exc:
|
|
1081
|
+
_raise_mapped(exc)
|
|
1082
|
+
|
|
1083
|
+
def delete_issue_property(self, issue_key: str, property_key: str) -> None:
|
|
1084
|
+
"""Delete an issue property."""
|
|
1085
|
+
try:
|
|
1086
|
+
self._client.delete_issue_property(issue_key, property_key) # type: ignore[attr-defined]
|
|
1087
|
+
except Exception as exc:
|
|
1088
|
+
_raise_mapped(exc)
|
|
1089
|
+
|
|
1090
|
+
# --- issue watchers ---
|
|
1091
|
+
def issue_get_watchers(self, issue_key: str) -> dict[str, Any]:
|
|
1092
|
+
"""List watchers for an issue."""
|
|
1093
|
+
try:
|
|
1094
|
+
return self._client.issue_get_watchers(issue_key) # type: ignore[attr-defined]
|
|
1095
|
+
except Exception as exc:
|
|
1096
|
+
_raise_mapped(exc)
|
|
1097
|
+
|
|
1098
|
+
def issue_add_watcher(self, issue_key: str, username_or_account_id: str) -> None:
|
|
1099
|
+
"""Add a watcher to an issue."""
|
|
1100
|
+
try:
|
|
1101
|
+
self._client.issue_add_watcher(issue_key, username_or_account_id) # type: ignore[attr-defined]
|
|
1102
|
+
except Exception as exc:
|
|
1103
|
+
_raise_mapped(exc)
|
|
1104
|
+
|
|
1105
|
+
def issue_delete_watcher(self, issue_key: str, username_or_account_id: str) -> None:
|
|
1106
|
+
"""Remove a watcher from an issue."""
|
|
1107
|
+
try:
|
|
1108
|
+
self._client.issue_delete_watcher(issue_key, username_or_account_id) # type: ignore[attr-defined]
|
|
1109
|
+
except Exception as exc:
|
|
1110
|
+
_raise_mapped(exc)
|
|
1111
|
+
|
|
1112
|
+
# --- issue security schemes ---
|
|
1113
|
+
def get_issue_security_schemes(self) -> list[dict[str, Any]]:
|
|
1114
|
+
"""Get all security schemes."""
|
|
1115
|
+
try:
|
|
1116
|
+
return self._client.get_issue_security_schemes() # type: ignore[attr-defined]
|
|
1117
|
+
except Exception as exc:
|
|
1118
|
+
_raise_mapped(exc)
|
|
1119
|
+
|
|
1120
|
+
def get_issue_security_scheme(self, scheme_id: str, only_levels: bool = False) -> dict[str, Any]:
|
|
1121
|
+
"""Get issue security scheme."""
|
|
1122
|
+
try:
|
|
1123
|
+
return self._client.get_issue_security_scheme(scheme_id, only_levels=only_levels) # type: ignore[attr-defined]
|
|
1124
|
+
except Exception as exc:
|
|
1125
|
+
_raise_mapped(exc)
|
|
1126
|
+
|
|
1127
|
+
# --- agile board operations ---
|
|
1128
|
+
def get_agile_board_by_filter_id(self, filter_id: int) -> dict[str, Any]:
|
|
1129
|
+
"""Get agile board by filter ID."""
|
|
1130
|
+
try:
|
|
1131
|
+
return self._client.get_agile_board_by_filter_id(filter_id) # type: ignore[attr-defined]
|
|
1132
|
+
except Exception as exc:
|
|
1133
|
+
_raise_mapped(exc)
|
|
1134
|
+
|
|
1135
|
+
def create_agile_board(
|
|
1136
|
+
self, name: str, board_type: str, filter_id: int, location: dict[str, Any] | None = None
|
|
1137
|
+
) -> dict[str, Any]:
|
|
1138
|
+
"""Create a new agile board."""
|
|
1139
|
+
try:
|
|
1140
|
+
return self._client.create_agile_board(name, board_type, filter_id, location=location) # type: ignore[attr-defined]
|
|
1141
|
+
except Exception as exc:
|
|
1142
|
+
_raise_mapped(exc)
|
|
1143
|
+
|
|
1144
|
+
def get_all_agile_boards(
|
|
1145
|
+
self,
|
|
1146
|
+
board_name: str | None = None,
|
|
1147
|
+
project_key: str | None = None,
|
|
1148
|
+
board_type: str | None = None,
|
|
1149
|
+
start: int = 0,
|
|
1150
|
+
limit: int = 50,
|
|
1151
|
+
) -> list[dict[str, Any]]:
|
|
1152
|
+
"""Get all agile boards."""
|
|
1153
|
+
try:
|
|
1154
|
+
result = self._client.get_all_agile_boards(
|
|
1155
|
+
board_name=board_name, project_key=project_key, board_type=board_type, start=start, limit=limit
|
|
1156
|
+
) # type: ignore[attr-defined]
|
|
1157
|
+
return self._coerce_list_items(result, ("values",))
|
|
1158
|
+
except Exception as exc:
|
|
1159
|
+
_raise_mapped(exc)
|
|
1160
|
+
|
|
1161
|
+
def delete_agile_board(self, board_id: int) -> None:
|
|
1162
|
+
"""Delete agile board by ID."""
|
|
1163
|
+
try:
|
|
1164
|
+
self._client.delete_agile_board(board_id) # type: ignore[attr-defined]
|
|
1165
|
+
except Exception as exc:
|
|
1166
|
+
_raise_mapped(exc)
|
|
1167
|
+
|
|
1168
|
+
def get_agile_board(self, board_id: int) -> dict[str, Any]:
|
|
1169
|
+
"""Get agile board by ID."""
|
|
1170
|
+
try:
|
|
1171
|
+
return self._client.get_agile_board(board_id) # type: ignore[attr-defined]
|
|
1172
|
+
except Exception as exc:
|
|
1173
|
+
_raise_mapped(exc)
|
|
1174
|
+
|
|
1175
|
+
def get_issues_for_board(
|
|
1176
|
+
self,
|
|
1177
|
+
board_id: int,
|
|
1178
|
+
jql: str | None = None,
|
|
1179
|
+
fields: str = "*all",
|
|
1180
|
+
start: int = 0,
|
|
1181
|
+
limit: int | None = None,
|
|
1182
|
+
expand: str | None = None,
|
|
1183
|
+
) -> list[dict[str, Any]]:
|
|
1184
|
+
"""Get issues for board."""
|
|
1185
|
+
try:
|
|
1186
|
+
result = self._client.get_issues_for_board(
|
|
1187
|
+
board_id, jql=jql, fields=fields, start=start, limit=limit, expand=expand
|
|
1188
|
+
) # type: ignore[attr-defined]
|
|
1189
|
+
return self._coerce_list_items(result, ("issues", "values"))
|
|
1190
|
+
except Exception as exc:
|
|
1191
|
+
_raise_mapped(exc)
|
|
1192
|
+
|
|
1193
|
+
def get_agile_board_configuration(self, board_id: int) -> dict[str, Any]:
|
|
1194
|
+
"""Get agile board configuration by board ID."""
|
|
1195
|
+
try:
|
|
1196
|
+
return self._client.get_agile_board_configuration(board_id) # type: ignore[attr-defined]
|
|
1197
|
+
except Exception as exc:
|
|
1198
|
+
_raise_mapped(exc)
|
|
1199
|
+
|
|
1200
|
+
# component management is implemented above in "component operations"
|
|
1201
|
+
|
|
1202
|
+
# --- agile board properties ---
|
|
1203
|
+
def get_agile_board_properties(self, board_id: int) -> list[dict[str, Any]]:
|
|
1204
|
+
"""Get all board properties."""
|
|
1205
|
+
try:
|
|
1206
|
+
result = self._client.get_agile_board_properties(board_id) # type: ignore[attr-defined]
|
|
1207
|
+
return self._coerce_list_items(result, ("values", "properties"))
|
|
1208
|
+
except Exception as exc:
|
|
1209
|
+
_raise_mapped(exc)
|
|
1210
|
+
|
|
1211
|
+
def set_agile_board_property(self, board_id: int, property_key: str) -> None:
|
|
1212
|
+
"""Set the value of the specified board's property."""
|
|
1213
|
+
try:
|
|
1214
|
+
self._client.set_agile_board_property(board_id, property_key) # type: ignore[attr-defined]
|
|
1215
|
+
except Exception as exc:
|
|
1216
|
+
_raise_mapped(exc)
|
|
1217
|
+
|
|
1218
|
+
def get_agile_board_property(self, board_id: int, property_key: str) -> dict[str, Any]:
|
|
1219
|
+
"""Get agile board property."""
|
|
1220
|
+
try:
|
|
1221
|
+
return self._client.get_agile_board_property(board_id, property_key) # type: ignore[attr-defined]
|
|
1222
|
+
except Exception as exc:
|
|
1223
|
+
_raise_mapped(exc)
|
|
1224
|
+
|
|
1225
|
+
def delete_agile_board_property(self, board_id: int, property_key: str) -> None:
|
|
1226
|
+
"""Delete agile board property."""
|
|
1227
|
+
try:
|
|
1228
|
+
self._client.delete_agile_board_property(board_id, property_key) # type: ignore[attr-defined]
|
|
1229
|
+
except Exception as exc:
|
|
1230
|
+
_raise_mapped(exc)
|
|
1231
|
+
|
|
1232
|
+
# --- agile board velocity ---
|
|
1233
|
+
def get_agile_board_refined_velocity(self, board_id: int) -> dict[str, Any]:
|
|
1234
|
+
"""Get agile board refined velocity."""
|
|
1235
|
+
try:
|
|
1236
|
+
return self._client.get_agile_board_refined_velocity(board_id) # type: ignore[attr-defined]
|
|
1237
|
+
except Exception as exc:
|
|
1238
|
+
_raise_mapped(exc)
|
|
1239
|
+
|
|
1240
|
+
def set_agile_board_refined_velocity(self, board_id: int, refined_velocity: dict[str, Any]) -> None:
|
|
1241
|
+
"""Set agile board refined velocity."""
|
|
1242
|
+
try:
|
|
1243
|
+
self._client.set_agile_board_refined_velocity(board_id, refined_velocity) # type: ignore[attr-defined]
|
|
1244
|
+
except Exception as exc:
|
|
1245
|
+
_raise_mapped(exc)
|
|
1246
|
+
|
|
1247
|
+
# --- epic operations ---
|
|
1248
|
+
def epic_issues(self, epic_key: str) -> list[dict[str, Any]]:
|
|
1249
|
+
"""Get issues within an epic."""
|
|
1250
|
+
try:
|
|
1251
|
+
result = self._client.epic_issues(epic_key) # type: ignore[attr-defined]
|
|
1252
|
+
return self._coerce_list_items(result, ("issues", "values"))
|
|
1253
|
+
except Exception as exc:
|
|
1254
|
+
_raise_mapped(exc)
|
|
1255
|
+
|
|
1256
|
+
def get_epics(self, board_id: int, done: bool = False, start: int = 0, limit: int = 50) -> list[dict[str, Any]]:
|
|
1257
|
+
"""Get all epics from board."""
|
|
1258
|
+
try:
|
|
1259
|
+
result = self._client.get_epics(board_id, done=done, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1260
|
+
return self._coerce_list_items(result, ("values", "epics"))
|
|
1261
|
+
except Exception as exc:
|
|
1262
|
+
_raise_mapped(exc)
|
|
1263
|
+
|
|
1264
|
+
def get_issues_for_epic(
|
|
1265
|
+
self,
|
|
1266
|
+
board_id: int,
|
|
1267
|
+
epic_id: int,
|
|
1268
|
+
jql: str = "",
|
|
1269
|
+
validate_query: str = "",
|
|
1270
|
+
fields: str = "*all",
|
|
1271
|
+
expand: str = "",
|
|
1272
|
+
start: int = 0,
|
|
1273
|
+
limit: int = 50,
|
|
1274
|
+
) -> list[dict[str, Any]]:
|
|
1275
|
+
"""Get all issues that belong to an epic on the board."""
|
|
1276
|
+
try:
|
|
1277
|
+
result = self._client.get_issues_for_epic(
|
|
1278
|
+
board_id,
|
|
1279
|
+
epic_id,
|
|
1280
|
+
jql=jql,
|
|
1281
|
+
validate_query=validate_query,
|
|
1282
|
+
fields=fields,
|
|
1283
|
+
expand=expand,
|
|
1284
|
+
start=start,
|
|
1285
|
+
limit=limit,
|
|
1286
|
+
) # type: ignore[attr-defined]
|
|
1287
|
+
return self._coerce_list_items(result, ("issues", "values"))
|
|
1288
|
+
except Exception as exc:
|
|
1289
|
+
_raise_mapped(exc)
|
|
1290
|
+
|
|
1291
|
+
# --- sprint operations ---
|
|
1292
|
+
def get_all_sprints_from_board(
|
|
1293
|
+
self, board_id: int, state: str | None = None, start: int = 0, limit: int = 50
|
|
1294
|
+
) -> list[dict[str, Any]]:
|
|
1295
|
+
"""Get all sprints from board."""
|
|
1296
|
+
try:
|
|
1297
|
+
result = self._client.get_all_sprints_from_board(board_id, state=state, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1298
|
+
return self._coerce_list_items(result, ("values", "sprints"))
|
|
1299
|
+
except Exception as exc:
|
|
1300
|
+
_raise_mapped(exc)
|
|
1301
|
+
|
|
1302
|
+
def get_all_issues_for_sprint_in_board(
|
|
1303
|
+
self, board_id: int, state: str | None = None, start: int = 0, limit: int = 50
|
|
1304
|
+
) -> list[dict[str, Any]]:
|
|
1305
|
+
"""Get all issues for sprint in board."""
|
|
1306
|
+
try:
|
|
1307
|
+
result = self._client.get_all_issues_for_sprint_in_board(board_id, state=state, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1308
|
+
return self._coerce_list_items(result, ("issues", "values"))
|
|
1309
|
+
except Exception as exc:
|
|
1310
|
+
_raise_mapped(exc)
|
|
1311
|
+
|
|
1312
|
+
def get_all_versions_from_board(
|
|
1313
|
+
self, board_id: int, released: str = "true", start: int = 0, limit: int = 50
|
|
1314
|
+
) -> list[dict[str, Any]]:
|
|
1315
|
+
"""Get all versions for sprint in board."""
|
|
1316
|
+
try:
|
|
1317
|
+
result = self._client.get_all_versions_from_board(board_id, released=released, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1318
|
+
return self._coerce_list_items(result, ("values", "versions"))
|
|
1319
|
+
except Exception as exc:
|
|
1320
|
+
_raise_mapped(exc)
|
|
1321
|
+
|
|
1322
|
+
def create_sprint(
|
|
1323
|
+
self,
|
|
1324
|
+
sprint_name: str,
|
|
1325
|
+
origin_board_id: int,
|
|
1326
|
+
start_datetime: str | None = None,
|
|
1327
|
+
end_datetime: str | None = None,
|
|
1328
|
+
goal: str | None = None,
|
|
1329
|
+
) -> dict[str, Any]:
|
|
1330
|
+
"""Create sprint."""
|
|
1331
|
+
try:
|
|
1332
|
+
return self._client.create_sprint(sprint_name, origin_board_id, start_datetime, end_datetime, goal) # type: ignore[attr-defined]
|
|
1333
|
+
except Exception as exc:
|
|
1334
|
+
_raise_mapped(exc)
|
|
1335
|
+
|
|
1336
|
+
def rename_sprint(
|
|
1337
|
+
self, sprint_id: int, name: str | None = None, start_date: str | None = None, end_date: str | None = None
|
|
1338
|
+
) -> dict[str, Any]:
|
|
1339
|
+
"""Rename sprint."""
|
|
1340
|
+
try:
|
|
1341
|
+
return self._client.rename_sprint(sprint_id, name, start_date, end_date) # type: ignore[attr-defined]
|
|
1342
|
+
except Exception as exc:
|
|
1343
|
+
_raise_mapped(exc)
|
|
1344
|
+
|
|
1345
|
+
def add_issues_to_sprint(self, sprint_id: int, issues_list: list[str]) -> None:
|
|
1346
|
+
"""Add/Move issues to sprint."""
|
|
1347
|
+
try:
|
|
1348
|
+
self._client.add_issues_to_sprint(sprint_id, issues_list) # type: ignore[attr-defined]
|
|
1349
|
+
except Exception as exc:
|
|
1350
|
+
_raise_mapped(exc)
|
|
1351
|
+
|
|
1352
|
+
# --- backlog operations ---
|
|
1353
|
+
def move_issues_to_backlog(self, issue_keys: list[str]) -> None:
|
|
1354
|
+
"""Move issues to backlog."""
|
|
1355
|
+
try:
|
|
1356
|
+
self._client.move_issues_to_backlog(issue_keys) # type: ignore[attr-defined]
|
|
1357
|
+
except Exception as exc:
|
|
1358
|
+
_raise_mapped(exc)
|
|
1359
|
+
|
|
1360
|
+
def add_issues_to_backlog(self, issue_keys: list[str]) -> None:
|
|
1361
|
+
"""Add issues to backlog."""
|
|
1362
|
+
try:
|
|
1363
|
+
self._client.add_issues_to_backlog(issue_keys) # type: ignore[attr-defined]
|
|
1364
|
+
except Exception as exc:
|
|
1365
|
+
_raise_mapped(exc)
|
|
1366
|
+
|
|
1367
|
+
# --- worklog operations ---
|
|
1368
|
+
def get_worklogs(self, issue_key: str) -> dict[str, Any]:
|
|
1369
|
+
"""Get worklogs for an issue."""
|
|
1370
|
+
try:
|
|
1371
|
+
return self._client.issue_get_worklog(issue_key) # type: ignore[attr-defined]
|
|
1372
|
+
except Exception as exc:
|
|
1373
|
+
_raise_mapped(exc)
|
|
1374
|
+
|
|
1375
|
+
def issue_add_worklog(
|
|
1376
|
+
self,
|
|
1377
|
+
issue_key: str,
|
|
1378
|
+
time_spent: str,
|
|
1379
|
+
comment: str | None = None,
|
|
1380
|
+
started: str | None = None,
|
|
1381
|
+
time_sec: int | None = None,
|
|
1382
|
+
) -> dict[str, Any]:
|
|
1383
|
+
"""Add worklog entry to an issue.
|
|
1384
|
+
|
|
1385
|
+
Args:
|
|
1386
|
+
issue_key: Issue key (e.g., 'PROJ-123')
|
|
1387
|
+
time_spent: Time spent string (e.g., '2h 30m')
|
|
1388
|
+
comment: Optional comment
|
|
1389
|
+
started: Optional start datetime (ISO format)
|
|
1390
|
+
time_sec: Optional time in seconds (alternative to time_spent)
|
|
1391
|
+
"""
|
|
1392
|
+
try:
|
|
1393
|
+
if started and time_sec is not None:
|
|
1394
|
+
# Use simple worklog method if we have started and time_sec
|
|
1395
|
+
return self._client.issue_worklog(issue_key, started, time_sec, comment) # type: ignore[attr-defined]
|
|
1396
|
+
else:
|
|
1397
|
+
# Use JSON worklog method for more flexibility
|
|
1398
|
+
worklog: dict[str, Any] = {"timeSpent": time_spent}
|
|
1399
|
+
if comment:
|
|
1400
|
+
worklog["comment"] = comment
|
|
1401
|
+
if started:
|
|
1402
|
+
worklog["started"] = started
|
|
1403
|
+
return self._client.issue_add_json_worklog(issue_key, worklog) # type: ignore[attr-defined]
|
|
1404
|
+
except Exception as exc:
|
|
1405
|
+
_raise_mapped(exc)
|
|
1406
|
+
|
|
1407
|
+
def get_updated_worklogs(self, since: str, expand: str | None = None) -> dict[str, Any]:
|
|
1408
|
+
"""Get worklogs updated since timestamp.
|
|
1409
|
+
|
|
1410
|
+
Args:
|
|
1411
|
+
since: Timestamp in format 'YYYY-MM-DD HH:mm' or ISO format
|
|
1412
|
+
expand: Optional expand parameter
|
|
1413
|
+
"""
|
|
1414
|
+
try:
|
|
1415
|
+
return self._client.get_updated_worklogs(since, expand=expand) # type: ignore[attr-defined]
|
|
1416
|
+
except Exception as exc:
|
|
1417
|
+
_raise_mapped(exc)
|
|
1418
|
+
|
|
1419
|
+
def get_deleted_worklogs(self, since: str) -> dict[str, Any]:
|
|
1420
|
+
"""Get deleted worklogs since timestamp.
|
|
1421
|
+
|
|
1422
|
+
Args:
|
|
1423
|
+
since: Timestamp in format 'YYYY-MM-DD HH:mm' or ISO format
|
|
1424
|
+
"""
|
|
1425
|
+
try:
|
|
1426
|
+
return self._client.get_deleted_worklogs(since) # type: ignore[attr-defined]
|
|
1427
|
+
except Exception as exc:
|
|
1428
|
+
_raise_mapped(exc)
|
|
1429
|
+
|
|
1430
|
+
# --- transitions and changelog operations ---
|
|
1431
|
+
def get_issue_transitions(self, issue_key: str) -> list[dict[str, Any]]:
|
|
1432
|
+
"""Get available transitions for an issue."""
|
|
1433
|
+
try:
|
|
1434
|
+
if hasattr(self._client, "get_issue_transitions"):
|
|
1435
|
+
transitions = self._client.get_issue_transitions(issue_key) # type: ignore[attr-defined]
|
|
1436
|
+
if isinstance(transitions, list):
|
|
1437
|
+
return transitions
|
|
1438
|
+
if hasattr(self._client, "get_issue_transitions_full"):
|
|
1439
|
+
payload = self._client.get_issue_transitions_full(issue_key) # type: ignore[attr-defined]
|
|
1440
|
+
if isinstance(payload, dict) and isinstance(payload.get("transitions"), list):
|
|
1441
|
+
return payload["transitions"]
|
|
1442
|
+
raise VDSClientError("Jira client does not support transitions lookup")
|
|
1443
|
+
except Exception as exc:
|
|
1444
|
+
_raise_mapped(exc)
|
|
1445
|
+
|
|
1446
|
+
def get_issue_changelog(self, issue_key: str, start: int | None = None, limit: int | None = None) -> dict[str, Any]:
|
|
1447
|
+
"""Get complete change history for an issue.
|
|
1448
|
+
|
|
1449
|
+
Args:
|
|
1450
|
+
issue_key: Issue key (e.g., 'PROJ-123')
|
|
1451
|
+
start: Optional start index for pagination
|
|
1452
|
+
limit: Optional limit for pagination
|
|
1453
|
+
"""
|
|
1454
|
+
try:
|
|
1455
|
+
return self._client.get_issue_changelog(issue_key, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1456
|
+
except Exception as exc:
|
|
1457
|
+
_raise_mapped(exc)
|
|
1458
|
+
|
|
1459
|
+
def get_issue_status_changelog(self, issue_key: str) -> dict[str, Any]:
|
|
1460
|
+
"""Get status change history for an issue.
|
|
1461
|
+
|
|
1462
|
+
Args:
|
|
1463
|
+
issue_key: Issue key (e.g., 'PROJ-123')
|
|
1464
|
+
"""
|
|
1465
|
+
try:
|
|
1466
|
+
return self._client.get_issue_status_changelog(issue_key) # type: ignore[attr-defined]
|
|
1467
|
+
except Exception as exc:
|
|
1468
|
+
_raise_mapped(exc)
|
|
1469
|
+
|
|
1470
|
+
# --- dashboard operations ---
|
|
1471
|
+
def get_dashboard(self, dashboard_id: str | int) -> dict[str, Any]:
|
|
1472
|
+
"""Get dashboard by ID.
|
|
1473
|
+
|
|
1474
|
+
Args:
|
|
1475
|
+
dashboard_id: Dashboard ID (string or integer)
|
|
1476
|
+
"""
|
|
1477
|
+
try:
|
|
1478
|
+
result = self._client.get_dashboard(dashboard_id) # type: ignore[attr-defined]
|
|
1479
|
+
if not result:
|
|
1480
|
+
raise NotFoundError(f"Dashboard not found: {dashboard_id}")
|
|
1481
|
+
return result
|
|
1482
|
+
except Exception as exc:
|
|
1483
|
+
_raise_mapped(exc)
|
|
1484
|
+
|
|
1485
|
+
def get_dashboards(self, filter: str = "", start: int = 0, limit: int = 10) -> dict[str, Any]:
|
|
1486
|
+
"""List dashboards with optional filter.
|
|
1487
|
+
|
|
1488
|
+
Args:
|
|
1489
|
+
filter: Optional filter string
|
|
1490
|
+
start: Start index for pagination
|
|
1491
|
+
limit: Maximum number of results
|
|
1492
|
+
"""
|
|
1493
|
+
try:
|
|
1494
|
+
result = self._client.get_dashboards(filter=filter, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1495
|
+
return result if result else {}
|
|
1496
|
+
except Exception as exc:
|
|
1497
|
+
_raise_mapped(exc)
|
|
1498
|
+
|
|
1499
|
+
# --- reindex operations ---
|
|
1500
|
+
def reindex(self) -> dict[str, Any]:
|
|
1501
|
+
"""Trigger reindex."""
|
|
1502
|
+
try:
|
|
1503
|
+
return self._client.reindex() # type: ignore[attr-defined]
|
|
1504
|
+
except Exception as exc:
|
|
1505
|
+
_raise_mapped(exc)
|
|
1506
|
+
|
|
1507
|
+
def reindex_status(self) -> dict[str, Any]:
|
|
1508
|
+
"""Get reindex status."""
|
|
1509
|
+
try:
|
|
1510
|
+
return self._client.reindex_status() # type: ignore[attr-defined]
|
|
1511
|
+
except Exception as exc:
|
|
1512
|
+
_raise_mapped(exc)
|
|
1513
|
+
|
|
1514
|
+
def reindex_with_type(self, reindex_type: str) -> dict[str, Any]:
|
|
1515
|
+
"""Reindex with type."""
|
|
1516
|
+
try:
|
|
1517
|
+
return self._client.reindex_with_type(reindex_type) # type: ignore[attr-defined]
|
|
1518
|
+
except Exception as exc:
|
|
1519
|
+
_raise_mapped(exc)
|
|
1520
|
+
|
|
1521
|
+
# --- filter operations ---
|
|
1522
|
+
def get_filters(self, owner: str | None = None) -> list[dict[str, Any]]:
|
|
1523
|
+
"""Get list of filters, optionally filtered by owner.
|
|
1524
|
+
|
|
1525
|
+
Args:
|
|
1526
|
+
owner: Optional username to filter by owner
|
|
1527
|
+
"""
|
|
1528
|
+
try:
|
|
1529
|
+
# SDK doesn't have get_filters, use REST API directly
|
|
1530
|
+
# Endpoint: /rest/api/2/filter/search
|
|
1531
|
+
params: dict[str, Any] = {}
|
|
1532
|
+
if owner:
|
|
1533
|
+
params["username"] = owner
|
|
1534
|
+
|
|
1535
|
+
# Use SDK's get method with resource URL
|
|
1536
|
+
base_url = self._client.resource_url("filter") # type: ignore[attr-defined]
|
|
1537
|
+
url = f"{base_url}/search"
|
|
1538
|
+
result = self._client.get(url, params=params) # type: ignore[attr-defined]
|
|
1539
|
+
return (
|
|
1540
|
+
result.get("values", []) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1541
|
+
)
|
|
1542
|
+
except Exception as exc:
|
|
1543
|
+
_raise_mapped(exc)
|
|
1544
|
+
|
|
1545
|
+
def get_filter(self, filter_id: int) -> dict[str, Any]:
|
|
1546
|
+
"""Get filter by ID.
|
|
1547
|
+
|
|
1548
|
+
Args:
|
|
1549
|
+
filter_id: Filter ID
|
|
1550
|
+
"""
|
|
1551
|
+
try:
|
|
1552
|
+
result = self._client.get_filter(filter_id) # type: ignore[attr-defined]
|
|
1553
|
+
if not result:
|
|
1554
|
+
raise NotFoundError(f"Filter not found: {filter_id}")
|
|
1555
|
+
return result
|
|
1556
|
+
except Exception as exc:
|
|
1557
|
+
_raise_mapped(exc)
|
|
1558
|
+
|
|
1559
|
+
def create_filter(
|
|
1560
|
+
self, name: str, jql: str, description: str | None = None, favourite: bool = False
|
|
1561
|
+
) -> dict[str, Any]:
|
|
1562
|
+
"""Create a new filter.
|
|
1563
|
+
|
|
1564
|
+
Args:
|
|
1565
|
+
name: Filter name
|
|
1566
|
+
jql: JQL query string
|
|
1567
|
+
description: Optional description
|
|
1568
|
+
favourite: Whether to mark as favourite (default: False)
|
|
1569
|
+
"""
|
|
1570
|
+
try:
|
|
1571
|
+
return self._client.create_filter(name=name, jql=jql, description=description, favourite=favourite) # type: ignore[attr-defined]
|
|
1572
|
+
except Exception as exc:
|
|
1573
|
+
_raise_mapped(exc)
|
|
1574
|
+
|
|
1575
|
+
def update_filter(
|
|
1576
|
+
self,
|
|
1577
|
+
filter_id: int,
|
|
1578
|
+
name: str | None = None,
|
|
1579
|
+
jql: str | None = None,
|
|
1580
|
+
description: str | None = None,
|
|
1581
|
+
favourite: bool | None = None,
|
|
1582
|
+
) -> dict[str, Any]:
|
|
1583
|
+
"""Update an existing filter.
|
|
1584
|
+
|
|
1585
|
+
Args:
|
|
1586
|
+
filter_id: Filter ID
|
|
1587
|
+
name: Optional new name
|
|
1588
|
+
jql: Optional new JQL query (required if not updating other fields)
|
|
1589
|
+
description: Optional new description
|
|
1590
|
+
favourite: Optional favourite status
|
|
1591
|
+
"""
|
|
1592
|
+
try:
|
|
1593
|
+
# SDK's update_filter requires jql, but we allow partial updates
|
|
1594
|
+
# If jql is not provided, we need to get the current filter first
|
|
1595
|
+
if jql is None:
|
|
1596
|
+
# Get current filter to preserve existing JQL
|
|
1597
|
+
current = self.get_filter(filter_id)
|
|
1598
|
+
jql = current.get("jql", "")
|
|
1599
|
+
|
|
1600
|
+
kwargs: dict[str, Any] = {}
|
|
1601
|
+
if name is not None:
|
|
1602
|
+
kwargs["name"] = name
|
|
1603
|
+
if description is not None:
|
|
1604
|
+
kwargs["description"] = description
|
|
1605
|
+
if favourite is not None:
|
|
1606
|
+
kwargs["favourite"] = favourite
|
|
1607
|
+
|
|
1608
|
+
return self._client.update_filter(filter_id, jql=jql, **kwargs) # type: ignore[attr-defined]
|
|
1609
|
+
except Exception as exc:
|
|
1610
|
+
_raise_mapped(exc)
|
|
1611
|
+
|
|
1612
|
+
def delete_filter(self, filter_id: int) -> None:
|
|
1613
|
+
"""Delete a filter.
|
|
1614
|
+
|
|
1615
|
+
Args:
|
|
1616
|
+
filter_id: Filter ID
|
|
1617
|
+
"""
|
|
1618
|
+
try:
|
|
1619
|
+
self._client.delete_filter(filter_id) # type: ignore[attr-defined]
|
|
1620
|
+
except Exception as exc:
|
|
1621
|
+
_raise_mapped(exc)
|
|
1622
|
+
|
|
1623
|
+
# --- advanced search operations ---
|
|
1624
|
+
def search_issues_advanced(
|
|
1625
|
+
self,
|
|
1626
|
+
jql: str,
|
|
1627
|
+
*,
|
|
1628
|
+
start: int = 0,
|
|
1629
|
+
limit: int = 50,
|
|
1630
|
+
fields: Iterable[str] | None = None,
|
|
1631
|
+
) -> dict[str, Any]:
|
|
1632
|
+
"""Advanced JQL search with pagination support.
|
|
1633
|
+
|
|
1634
|
+
Args:
|
|
1635
|
+
jql: JQL query string
|
|
1636
|
+
start: Start index for pagination (default: 0)
|
|
1637
|
+
limit: Maximum number of results (default: 50)
|
|
1638
|
+
fields: Optional list of fields to return (default: *all)
|
|
1639
|
+
"""
|
|
1640
|
+
try:
|
|
1641
|
+
fields_str = ",".join(fields) if fields else "*all"
|
|
1642
|
+
return self._client.jql(jql, fields=fields_str, start=start, limit=limit) # type: ignore[attr-defined]
|
|
1643
|
+
except Exception as exc:
|
|
1644
|
+
_raise_mapped(exc)
|
|
1645
|
+
|
|
1646
|
+
def search_issues_by_filter(
|
|
1647
|
+
self,
|
|
1648
|
+
filter_id: int,
|
|
1649
|
+
*,
|
|
1650
|
+
start: int = 0,
|
|
1651
|
+
limit: int = 50,
|
|
1652
|
+
fields: Iterable[str] | None = None,
|
|
1653
|
+
) -> dict[str, Any]:
|
|
1654
|
+
"""Search issues using a saved filter.
|
|
1655
|
+
|
|
1656
|
+
Args:
|
|
1657
|
+
filter_id: Filter ID
|
|
1658
|
+
start: Start index for pagination (default: 0)
|
|
1659
|
+
limit: Maximum number of results (default: 50)
|
|
1660
|
+
fields: Optional list of fields to return (default: *all)
|
|
1661
|
+
"""
|
|
1662
|
+
try:
|
|
1663
|
+
# Get the filter to extract its JQL
|
|
1664
|
+
filter_data = self.get_filter(filter_id)
|
|
1665
|
+
jql = filter_data.get("jql", "")
|
|
1666
|
+
if not jql:
|
|
1667
|
+
raise VDSClientError(f"Filter {filter_id} does not have a JQL query")
|
|
1668
|
+
|
|
1669
|
+
# Use the filter's JQL for search
|
|
1670
|
+
return self.search_issues_advanced(jql, start=start, limit=limit, fields=fields)
|
|
1671
|
+
except Exception as exc:
|
|
1672
|
+
_raise_mapped(exc)
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
def _raise_mapped(exc: Exception) -> None:
|
|
1676
|
+
text = str(exc).lower()
|
|
1677
|
+
if "401" in text or "403" in text or "unauthorized" in text:
|
|
1678
|
+
raise AuthError(str(exc)) from exc
|
|
1679
|
+
if "404" in text or "not found" in text:
|
|
1680
|
+
raise NotFoundError(str(exc)) from exc
|
|
1681
|
+
if "429" in text or "rate limit" in text:
|
|
1682
|
+
raise RateLimitError(str(exc)) from exc
|
|
1683
|
+
if "409" in text or "conflict" in text:
|
|
1684
|
+
raise ConflictError(str(exc)) from exc
|
|
1685
|
+
if "500" in text or "server error" in text:
|
|
1686
|
+
raise ResponseError(str(exc)) from exc
|
|
1687
|
+
if "connection" in text or "network" in text or "timeout" in text:
|
|
1688
|
+
raise TransportError(str(exc)) from exc
|
|
1689
|
+
raise VDSClientError(str(exc)) from exc
|