@ngocsangairvds/vsaf 4.1.8 → 4.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1065) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/dist/commands/skill.js +1 -1
  3. package/packages/cli/dist/commands/skill.js.map +1 -1
  4. package/skills/vds-skill/_shared/config-check.js +0 -76
  5. package/skills/vds-skill/_shared/credentials.js +0 -139
  6. package/skills/vds-skill/create-bitbucket-pr/SKILL.md +0 -57
  7. package/skills/vds-skill/create-bitbucket-pr/scripts/create-pr.js +0 -125
  8. package/skills/vds-skill/create-jira-epic/SKILL.md +0 -55
  9. package/skills/vds-skill/create-jira-epic/scripts/create-epic.js +0 -120
  10. package/skills/vds-skill/install-deps.mjs +0 -567
  11. package/skills/vds-skill/pack.yaml +0 -24
  12. package/skills/vds-skill/pull/SKILL.md +0 -38
  13. package/skills/vds-skill/pull/scripts/pull.js +0 -59
  14. package/skills/vds-skill/push-prd/SKILL.md +0 -227
  15. package/skills/vds-skill/push-srs/SKILL.md +0 -116
  16. package/skills/vds-skill/search-confluence/SKILL.md +0 -53
  17. package/skills/vds-skill/search-confluence/scripts/search.js +0 -114
  18. package/skills/vds-skill/vds-scripts/.claude/phase7-CLOSURE.md +0 -100
  19. package/skills/vds-skill/vds-scripts/.dockerignore +0 -62
  20. package/skills/vds-skill/vds-scripts/.github/ISSUE_TEMPLATE/cli-change.md +0 -92
  21. package/skills/vds-skill/vds-scripts/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -48
  22. package/skills/vds-skill/vds-scripts/.github/workflows/chaos-smoke.yml +0 -266
  23. package/skills/vds-skill/vds-scripts/.github/workflows/confluence-sync.yml +0 -44
  24. package/skills/vds-skill/vds-scripts/.github/workflows/docs-confluence-evidence.yml +0 -170
  25. package/skills/vds-skill/vds-scripts/.github/workflows/docs-quality.yml +0 -59
  26. package/skills/vds-skill/vds-scripts/.github/workflows/lint-and-test.yml +0 -90
  27. package/skills/vds-skill/vds-scripts/.github/workflows/scheduler-load-smoke.yml +0 -104
  28. package/skills/vds-skill/vds-scripts/.github/workflows/telegram-bridge-ci.yml +0 -131
  29. package/skills/vds-skill/vds-scripts/.graphifyignore +0 -29
  30. package/skills/vds-skill/vds-scripts/.importlinter +0 -86
  31. package/skills/vds-skill/vds-scripts/.mcp.json +0 -11
  32. package/skills/vds-skill/vds-scripts/.pre-commit-config.yaml +0 -62
  33. package/skills/vds-skill/vds-scripts/.ruffignore +0 -3
  34. package/skills/vds-skill/vds-scripts/.secrets.baseline +0 -133
  35. package/skills/vds-skill/vds-scripts/AGENTS.md +0 -250
  36. package/skills/vds-skill/vds-scripts/AGENTS.vi.md +0 -92
  37. package/skills/vds-skill/vds-scripts/ECOSYSTEM-CHANGELOG.md +0 -52
  38. package/skills/vds-skill/vds-scripts/ECOSYSTEM-DOCS.md +0 -602
  39. package/skills/vds-skill/vds-scripts/ECOSYSTEM_ALIGNMENT.md +0 -133
  40. package/skills/vds-skill/vds-scripts/Makefile +0 -119
  41. package/skills/vds-skill/vds-scripts/README.md +0 -103
  42. package/skills/vds-skill/vds-scripts/bitbucket_manifest_mapping.toml +0 -34
  43. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/ARCHITECTURE_ANALYSIS.md +0 -258
  44. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/BITBUCKET_API_PRACTICES.md +0 -393
  45. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/EVALUATION_REPORT.md +0 -61
  46. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/FEATURES.md +0 -908
  47. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/README.md +0 -817
  48. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/pyproject.toml +0 -49
  49. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/__init__.py +0 -50
  50. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py +0 -641
  51. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/cli.py +0 -2271
  52. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/client.py +0 -2693
  53. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/config.py +0 -186
  54. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/errors.py +0 -34
  55. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/factory.py +0 -185
  56. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/parsers.py +0 -113
  57. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/protocols.py +0 -244
  58. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/repo_ops.py +0 -325
  59. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/__init__.py +0 -8
  60. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/conftest.py +0 -65
  61. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_advanced_search.py +0 -155
  62. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_async_client.py +0 -505
  63. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_branch_permissions.py +0 -172
  64. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_cli.py +0 -113
  65. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_cli_archive.py +0 -122
  66. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_cli_clone.py +0 -131
  67. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client.py +0 -207
  68. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_archive.py +0 -73
  69. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_branch_conditions.py +0 -101
  70. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_code_advanced.py +0 -180
  71. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_code_file.py +0 -33
  72. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_deployment_environments.py +0 -193
  73. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_issues.py +0 -163
  74. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_pipelines_advanced.py +0 -171
  75. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_pr_blockers.py +0 -118
  76. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_client_repository_variables.py +0 -155
  77. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_code.py +0 -98
  78. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_code_advanced.py +0 -279
  79. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_code_insights.py +0 -334
  80. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_conditions.py +0 -149
  81. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_config.py +0 -297
  82. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_deployment_env.py +0 -352
  83. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_errors.py +0 -67
  84. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_factory.py +0 -352
  85. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_fork_operations.py +0 -203
  86. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_issue_cli.py +0 -262
  87. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_pipeline_advanced.py +0 -265
  88. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_pr_blocker.py +0 -206
  89. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_protocols.py +0 -336
  90. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_ops_archive.py +0 -169
  91. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_ops_clone.py +0 -115
  92. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_ops_parsing.py +0 -149
  93. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_settings.py +0 -336
  94. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_repo_variables.py +0 -266
  95. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_webhooks.py +0 -188
  96. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/test_workspace.py +0 -234
  97. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/unit/__init__.py +0 -0
  98. package/skills/vds-skill/vds-scripts/bitbucket_orchestrator/tests/unit/test_parsers.py +0 -254
  99. package/skills/vds-skill/vds-scripts/brd_orchestrator/README.md +0 -29
  100. package/skills/vds-skill/vds-scripts/brd_orchestrator/pyproject.toml +0 -63
  101. package/skills/vds-skill/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/__init__.py +0 -17
  102. package/skills/vds-skill/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/cli.py +0 -187
  103. package/skills/vds-skill/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/validator.py +0 -121
  104. package/skills/vds-skill/vds-scripts/brd_orchestrator/tests/__init__.py +0 -0
  105. package/skills/vds-skill/vds-scripts/brd_orchestrator/tests/test_cli.py +0 -62
  106. package/skills/vds-skill/vds-scripts/brd_orchestrator/tests/test_validator.py +0 -33
  107. package/skills/vds-skill/vds-scripts/code/code_evidence_pack.json +0 -435
  108. package/skills/vds-skill/vds-scripts/confluence_orchestrator/Dockerfile +0 -19
  109. package/skills/vds-skill/vds-scripts/confluence_orchestrator/README.md +0 -479
  110. package/skills/vds-skill/vds-scripts/confluence_orchestrator/SYNC_SCRIPTS.md +0 -127
  111. package/skills/vds-skill/vds-scripts/confluence_orchestrator/SYNC_STANDARDIZATION.md +0 -108
  112. package/skills/vds-skill/vds-scripts/confluence_orchestrator/pyproject.toml +0 -50
  113. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/__init__.py +0 -56
  114. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/async_client.py +0 -100
  115. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/cli.py +0 -3160
  116. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/config.py +0 -215
  117. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content.py +0 -368
  118. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/content_v2.py +0 -144
  119. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/crawl_tree.py +0 -1833
  120. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/errors.py +0 -44
  121. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/eventing.py +0 -111
  122. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/http.py +0 -1850
  123. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/orchestration.py +0 -166
  124. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/protocols.py +0 -61
  125. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/reporting.py +0 -78
  126. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/tree.py +0 -122
  127. package/skills/vds-skill/vds-scripts/confluence_orchestrator/src/confluence_orchestrator/tree_copier.py +0 -431
  128. package/skills/vds-skill/vds-scripts/confluence_orchestrator/sync_pdfs_from_markdown.py +0 -203
  129. package/skills/vds-skill/vds-scripts/confluence_orchestrator/sync_pdfs_to_confluence.py +0 -299
  130. package/skills/vds-skill/vds-scripts/confluence_orchestrator/sync_png_attachments.py +0 -299
  131. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/conftest.py +0 -46
  132. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_advanced_content.py +0 -252
  133. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_advanced_search.py +0 -193
  134. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_async_client.py +0 -104
  135. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_cache_management.py +0 -246
  136. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_cli.py +0 -716
  137. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_config.py +0 -130
  138. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_content.py +0 -192
  139. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_content_flags.py +0 -27
  140. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_content_labels.py +0 -94
  141. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_crawl_tree.py +0 -2252
  142. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_degraded_write_safety.py +0 -176
  143. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_draft_management.py +0 -225
  144. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_errors.py +0 -75
  145. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing.py +0 -73
  146. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing_chaos.py +0 -37
  147. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing_rate_limit.py +0 -44
  148. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_eventing_timeout.py +0 -49
  149. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_export.py +0 -231
  150. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_history.py +0 -217
  151. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_http.py +0 -375
  152. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_orchestration.py +0 -93
  153. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_reporting.py +0 -24
  154. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_search_cql.py +0 -36
  155. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_space_management.py +0 -236
  156. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_space_permissions.py +0 -384
  157. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_tree_copier.py +0 -644
  158. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_tree_copier_remap.py +0 -289
  159. package/skills/vds-skill/vds-scripts/confluence_orchestrator/tests/test_user_group_management.py +0 -387
  160. package/skills/vds-skill/vds-scripts/diagram_generator/README.md +0 -663
  161. package/skills/vds-skill/vds-scripts/diagram_generator/ci_validate.sh +0 -16
  162. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.png +0 -0
  163. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.puml +0 -23
  164. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.png +0 -0
  165. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.puml +0 -21
  166. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.png +0 -0
  167. package/skills/vds-skill/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.puml +0 -14
  168. package/skills/vds-skill/vds-scripts/diagram_generator/examples/github-actions-validate.yml +0 -39
  169. package/skills/vds-skill/vds-scripts/diagram_generator/generate_all_diagrams.py +0 -827
  170. package/skills/vds-skill/vds-scripts/diagram_generator/generate_insurance_c4_diagrams.py +0 -261
  171. package/skills/vds-skill/vds-scripts/diagram_generator/generate_insurance_c4_quick.py +0 -486
  172. package/skills/vds-skill/vds-scripts/diagram_generator/pyproject.toml +0 -28
  173. package/skills/vds-skill/vds-scripts/diagram_generator/render_png.py +0 -59
  174. package/skills/vds-skill/vds-scripts/diagram_generator/src/vds_diagram_generator/__init__.py +0 -3
  175. package/skills/vds-skill/vds-scripts/diagram_generator/src/vds_diagram_generator/cli.py +0 -50
  176. package/skills/vds-skill/vds-scripts/diagram_generator/test_c4_hierarchical.py +0 -142
  177. package/skills/vds-skill/vds-scripts/diagram_generator/test_c4_quick.py +0 -131
  178. package/skills/vds-skill/vds-scripts/diagram_generator/tests/__init__.py +0 -0
  179. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_analyzer_completeness.py +0 -260
  180. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_c4_syntax_correctness.py +0 -138
  181. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_component_coverage.py +0 -182
  182. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_mermaid_output.py +0 -80
  183. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_png_generation.py +0 -112
  184. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_scenario_templates.py +0 -15
  185. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_sequence_accuracy.py +0 -93
  186. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_structurizr_export.py +0 -177
  187. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_style_consistency.py +0 -174
  188. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_usecase_generator.py +0 -201
  189. package/skills/vds-skill/vds-scripts/diagram_generator/tests/test_usecase_integration.py +0 -124
  190. package/skills/vds-skill/vds-scripts/docker/.dockerignore +0 -38
  191. package/skills/vds-skill/vds-scripts/docker/ADR.md +0 -392
  192. package/skills/vds-skill/vds-scripts/docker/Dockerfile +0 -68
  193. package/skills/vds-skill/vds-scripts/docker/MIGRATION.md +0 -453
  194. package/skills/vds-skill/vds-scripts/docker/README.md +0 -347
  195. package/skills/vds-skill/vds-scripts/docker/ROLLBACK.md +0 -596
  196. package/skills/vds-skill/vds-scripts/docker/compose.phase2-verification.yml +0 -31
  197. package/skills/vds-skill/vds-scripts/docker/docker-compose.cli.yml +0 -206
  198. package/skills/vds-skill/vds-scripts/docker/docker-compose.infra.yml +0 -276
  199. package/skills/vds-skill/vds-scripts/docker/docker-compose.services.yml +0 -425
  200. package/skills/vds-skill/vds-scripts/docker/infrastructure/init-schemas.sql +0 -177
  201. package/skills/vds-skill/vds-scripts/docker/infrastructure/pgbouncer/pgbouncer.ini +0 -75
  202. package/skills/vds-skill/vds-scripts/docker/infrastructure/pgbouncer/userlist.txt +0 -50
  203. package/skills/vds-skill/vds-scripts/docker/infrastructure/pgbouncer/userlist.txt.template +0 -36
  204. package/skills/vds-skill/vds-scripts/docs/.confluence-evidence/.gitkeep +0 -0
  205. package/skills/vds-skill/vds-scripts/docs/.confluence-evidence/PREFLIGHT.md +0 -132
  206. package/skills/vds-skill/vds-scripts/docs/.confluence-evidence/README.md +0 -84
  207. package/skills/vds-skill/vds-scripts/docs/.confluence.yaml +0 -157
  208. package/skills/vds-skill/vds-scripts/docs/.freshness.yaml +0 -54
  209. package/skills/vds-skill/vds-scripts/docs/README.md +0 -235
  210. package/skills/vds-skill/vds-scripts/docs/agents/README.md +0 -33
  211. package/skills/vds-skill/vds-scripts/docs/agents/explanation/data-flow.md +0 -132
  212. package/skills/vds-skill/vds-scripts/docs/agents/explanation/development-roadmap.md +0 -49
  213. package/skills/vds-skill/vds-scripts/docs/agents/explanation/features-overview.md +0 -62
  214. package/skills/vds-skill/vds-scripts/docs/agents/explanation/index.md +0 -36
  215. package/skills/vds-skill/vds-scripts/docs/agents/explanation/runtime-verification-and-gap-reporting.md +0 -127
  216. package/skills/vds-skill/vds-scripts/docs/agents/explanation/system-architecture.md +0 -139
  217. package/skills/vds-skill/vds-scripts/docs/agents/explanation/whats-new.md +0 -75
  218. package/skills/vds-skill/vds-scripts/docs/agents/explanation/who-ecosystem-introduction.md +0 -65
  219. package/skills/vds-skill/vds-scripts/docs/agents/explanation/who-ecosystem-model.md +0 -41
  220. package/skills/vds-skill/vds-scripts/docs/agents/how-to/02-using-vds-ai-memory.md +0 -98
  221. package/skills/vds-skill/vds-scripts/docs/agents/how-to/03-memory-cross-agent.md +0 -241
  222. package/skills/vds-skill/vds-scripts/docs/agents/how-to/04-using-progress-reports.md +0 -240
  223. package/skills/vds-skill/vds-scripts/docs/agents/how-to/08-semantic-search.md +0 -46
  224. package/skills/vds-skill/vds-scripts/docs/agents/how-to/apply-phase3-migration.md +0 -148
  225. package/skills/vds-skill/vds-scripts/docs/agents/how-to/choose-the-right-command-or-skill.md +0 -34
  226. package/skills/vds-skill/vds-scripts/docs/agents/how-to/contribute-new-orchestrator.md +0 -149
  227. package/skills/vds-skill/vds-scripts/docs/agents/how-to/decision-tree.md +0 -63
  228. package/skills/vds-skill/vds-scripts/docs/agents/how-to/first-audit-run.md +0 -83
  229. package/skills/vds-skill/vds-scripts/docs/agents/how-to/index.md +0 -49
  230. package/skills/vds-skill/vds-scripts/docs/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +0 -314
  231. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +0 -165
  232. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +0 -138
  233. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +0 -130
  234. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +0 -142
  235. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +0 -140
  236. package/skills/vds-skill/vds-scripts/docs/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +0 -135
  237. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase131-all-project-preparation.md +0 -211
  238. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase131-bounded-parallel-analysis.md +0 -123
  239. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase131-confluence-upload-recovery.md +0 -204
  240. package/skills/vds-skill/vds-scripts/docs/agents/how-to/phase132-department-preparation.md +0 -144
  241. package/skills/vds-skill/vds-scripts/docs/agents/how-to/run-ecosystem-daily-report.md +0 -213
  242. package/skills/vds-skill/vds-scripts/docs/agents/how-to/tips-and-tricks.md +0 -138
  243. package/skills/vds-skill/vds-scripts/docs/agents/how-to/troubleshooting-guide.md +0 -221
  244. package/skills/vds-skill/vds-scripts/docs/agents/reference/agent-operational-contract.md +0 -162
  245. package/skills/vds-skill/vds-scripts/docs/agents/reference/alignment-phase179-report.md +0 -144
  246. package/skills/vds-skill/vds-scripts/docs/agents/reference/audit-triage-playbook.md +0 -256
  247. package/skills/vds-skill/vds-scripts/docs/agents/reference/backup-restore.md +0 -132
  248. package/skills/vds-skill/vds-scripts/docs/agents/reference/bitbucket-orchestrator.md +0 -56
  249. package/skills/vds-skill/vds-scripts/docs/agents/reference/brd-orchestrator.md +0 -52
  250. package/skills/vds-skill/vds-scripts/docs/agents/reference/capability-coverage-review.md +0 -51
  251. package/skills/vds-skill/vds-scripts/docs/agents/reference/ci-workflows.md +0 -98
  252. package/skills/vds-skill/vds-scripts/docs/agents/reference/circular-dependency-orchestrator.md +0 -55
  253. package/skills/vds-skill/vds-scripts/docs/agents/reference/cli-commands.md +0 -583
  254. package/skills/vds-skill/vds-scripts/docs/agents/reference/cli-development-standards.md +0 -41
  255. package/skills/vds-skill/vds-scripts/docs/agents/reference/cli-help-matrix.md +0 -84
  256. package/skills/vds-skill/vds-scripts/docs/agents/reference/common-errors.md +0 -126
  257. package/skills/vds-skill/vds-scripts/docs/agents/reference/configuration-reference.md +0 -128
  258. package/skills/vds-skill/vds-scripts/docs/agents/reference/confluence-orchestrator.md +0 -56
  259. package/skills/vds-skill/vds-scripts/docs/agents/reference/confluence-sync-target.md +0 -111
  260. package/skills/vds-skill/vds-scripts/docs/agents/reference/confluence-sync.md +0 -46
  261. package/skills/vds-skill/vds-scripts/docs/agents/reference/db-query-orchestrator.md +0 -93
  262. package/skills/vds-skill/vds-scripts/docs/agents/reference/diagrams-orchestrator.md +0 -52
  263. package/skills/vds-skill/vds-scripts/docs/agents/reference/ecosystem-daily-report.md +0 -229
  264. package/skills/vds-skill/vds-scripts/docs/agents/reference/elastic-orchestrator.md +0 -57
  265. package/skills/vds-skill/vds-scripts/docs/agents/reference/env-git-helper.md +0 -216
  266. package/skills/vds-skill/vds-scripts/docs/agents/reference/evolution-orchestrator.md +0 -113
  267. package/skills/vds-skill/vds-scripts/docs/agents/reference/excel-orchestrator.md +0 -51
  268. package/skills/vds-skill/vds-scripts/docs/agents/reference/git-orchestrator.md +0 -62
  269. package/skills/vds-skill/vds-scripts/docs/agents/reference/google-sheets-orchestrator.md +0 -51
  270. package/skills/vds-skill/vds-scripts/docs/agents/reference/grafana-orchestrator.md +0 -52
  271. package/skills/vds-skill/vds-scripts/docs/agents/reference/hexagonal-orchestrator.md +0 -64
  272. package/skills/vds-skill/vds-scripts/docs/agents/reference/index.md +0 -36
  273. package/skills/vds-skill/vds-scripts/docs/agents/reference/infrastructure-v2.15.md +0 -67
  274. package/skills/vds-skill/vds-scripts/docs/agents/reference/intellij-orchestrator.md +0 -50
  275. package/skills/vds-skill/vds-scripts/docs/agents/reference/jira-orchestrator.md +0 -60
  276. package/skills/vds-skill/vds-scripts/docs/agents/reference/links-orchestrator.md +0 -57
  277. package/skills/vds-skill/vds-scripts/docs/agents/reference/lint-cli.md +0 -99
  278. package/skills/vds-skill/vds-scripts/docs/agents/reference/lsp-orchestrator.md +0 -51
  279. package/skills/vds-skill/vds-scripts/docs/agents/reference/markdown-orchestrator.md +0 -53
  280. package/skills/vds-skill/vds-scripts/docs/agents/reference/mcp-orchestrator.md +0 -88
  281. package/skills/vds-skill/vds-scripts/docs/agents/reference/memory-orchestrator.md +0 -53
  282. package/skills/vds-skill/vds-scripts/docs/agents/reference/metabase-orchestrator.md +0 -51
  283. package/skills/vds-skill/vds-scripts/docs/agents/reference/migration-playbook.md +0 -71
  284. package/skills/vds-skill/vds-scripts/docs/agents/reference/multi-agent-orchestrator.md +0 -52
  285. package/skills/vds-skill/vds-scripts/docs/agents/reference/openapi-orchestrator.md +0 -57
  286. package/skills/vds-skill/vds-scripts/docs/agents/reference/orchestrator-architecture.md +0 -194
  287. package/skills/vds-skill/vds-scripts/docs/agents/reference/orchestrator-comparison-matrix.md +0 -79
  288. package/skills/vds-skill/vds-scripts/docs/agents/reference/orchestrator-index.md +0 -73
  289. package/skills/vds-skill/vds-scripts/docs/agents/reference/pdf-orchestrator.md +0 -57
  290. package/skills/vds-skill/vds-scripts/docs/agents/reference/portable-paths-and-config.md +0 -0
  291. package/skills/vds-skill/vds-scripts/docs/agents/reference/portable-paths-validation-matrix.md +0 -129
  292. package/skills/vds-skill/vds-scripts/docs/agents/reference/progress-orchestrator.md +0 -51
  293. package/skills/vds-skill/vds-scripts/docs/agents/reference/progress-report-cli.md +0 -215
  294. package/skills/vds-skill/vds-scripts/docs/agents/reference/public-interface-orchestrator.md +0 -73
  295. package/skills/vds-skill/vds-scripts/docs/agents/reference/research-orchestrator.md +0 -53
  296. package/skills/vds-skill/vds-scripts/docs/agents/reference/schema-orchestrator.md +0 -57
  297. package/skills/vds-skill/vds-scripts/docs/agents/reference/search-tools.md +0 -34
  298. package/skills/vds-skill/vds-scripts/docs/agents/reference/skills-commands.md +0 -256
  299. package/skills/vds-skill/vds-scripts/docs/agents/reference/skills-reference.md +0 -32
  300. package/skills/vds-skill/vds-scripts/docs/agents/reference/sonarqube-orchestrator.md +0 -62
  301. package/skills/vds-skill/vds-scripts/docs/agents/reference/spec-orchestrator.md +0 -56
  302. package/skills/vds-skill/vds-scripts/docs/agents/reference/structure-orchestrator.md +0 -69
  303. package/skills/vds-skill/vds-scripts/docs/agents/reference/system-requirements.md +0 -76
  304. package/skills/vds-skill/vds-scripts/docs/agents/reference/tasks-orchestrator.md +0 -53
  305. package/skills/vds-skill/vds-scripts/docs/agents/reference/validation-and-sync-notes.md +0 -54
  306. package/skills/vds-skill/vds-scripts/docs/agents/reference/vds-ai-memory-api.md +0 -51
  307. package/skills/vds-skill/vds-scripts/docs/agents/reference/vds-cli-reference.md +0 -34
  308. package/skills/vds-skill/vds-scripts/docs/agents/reference/who-capability-inventory.md +0 -96
  309. package/skills/vds-skill/vds-scripts/docs/agents/reference/who-capability-routing-matrix.md +0 -14
  310. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/feature-progression-guide.md +0 -112
  311. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/index.md +0 -36
  312. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/quick-start.md +0 -50
  313. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/who-skills-and-scripts-onboarding.md +0 -47
  314. package/skills/vds-skill/vds-scripts/docs/agents/tutorials/zero-to-productive-developer.md +0 -339
  315. package/skills/vds-skill/vds-scripts/docs/confluence/IMPLEMENTATION-SUMMARY.md +0 -78
  316. package/skills/vds-skill/vds-scripts/docs/confluence/SYNC-GUIDE.md +0 -47
  317. package/skills/vds-skill/vds-scripts/docs/deployment/offline-docker-image-load.md +0 -59
  318. package/skills/vds-skill/vds-scripts/docs/evolution-auto-run-rollout.md +0 -325
  319. package/skills/vds-skill/vds-scripts/docs/evolution-loop-deep-integration.md +0 -496
  320. package/skills/vds-skill/vds-scripts/docs/evolution-loop-integration-guide.md +0 -359
  321. package/skills/vds-skill/vds-scripts/docs/openspace-schema-snapshot.md +0 -73
  322. package/skills/vds-skill/vds-scripts/docs/operations/sla-mttr-policy.md +0 -44
  323. package/skills/vds-skill/vds-scripts/docs/p0-closure-evidence/SUMMARY.md +0 -58
  324. package/skills/vds-skill/vds-scripts/docs/p4-closure-evidence/.gitkeep +0 -0
  325. package/skills/vds-skill/vds-scripts/docs/p4-closure-evidence/smoke-20260427T024137Z-b95b586b.json +0 -15
  326. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/alembic-and-runtime-advisory-locks.md +0 -45
  327. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/dbos-listen-notify.md +0 -54
  328. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/pgbouncer-search-path-empirical.md +0 -110
  329. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/pgvector-set-local-audit.md +0 -51
  330. package/skills/vds-skill/vds-scripts/docs/p8-preflight-evidence/topology-decision-session-mode.md +0 -57
  331. package/skills/vds-skill/vds-scripts/docs/phases/CHANGELOG.md +0 -103
  332. package/skills/vds-skill/vds-scripts/docs/phases/PHASE_125_COMPLETION_AND_MERGE.md +0 -212
  333. package/skills/vds-skill/vds-scripts/docs/phases/phase125/IMPLEMENTATION_REPORT.md +0 -227
  334. package/skills/vds-skill/vds-scripts/docs/phases/phase125/TSK-125.10-11-implementation-summary.md +0 -196
  335. package/skills/vds-skill/vds-scripts/docs/phases/phase125/profile-patch-ollama-local-anthropic.md +0 -122
  336. package/skills/vds-skill/vds-scripts/docs/phases/phase125_completion_summary.md +0 -369
  337. package/skills/vds-skill/vds-scripts/docs/phases/phase125_llm_analysis_skill.md +0 -164
  338. package/skills/vds-skill/vds-scripts/docs/phases/phase125_merge_complete.md +0 -147
  339. package/skills/vds-skill/vds-scripts/docs/phases/phase125_skill_runtime_closure_20260321.md +0 -91
  340. package/skills/vds-skill/vds-scripts/docs/phases/phase2-portable-paths/closure-handoff-summary-2026-03-23.md +0 -290
  341. package/skills/vds-skill/vds-scripts/docs/phases/phase2-portable-paths/remaining-risk-register-2026-03-25.md +0 -143
  342. package/skills/vds-skill/vds-scripts/docs/phases/phase2-portable-paths/verification-evidence-2026-03-23.md +0 -135
  343. package/skills/vds-skill/vds-scripts/docs/v0-sunset-known-issues.md +0 -88
  344. package/skills/vds-skill/vds-scripts/docs/vi/TRANSLATION-BACKLOG.md +0 -72
  345. package/skills/vds-skill/vds-scripts/docs/vi/agents/README.md +0 -41
  346. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/features-overview.md +0 -29
  347. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/index.md +0 -14
  348. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/runtime-verification-and-gap-reporting.md +0 -129
  349. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/whats-new.md +0 -37
  350. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/who-ecosystem-introduction.md +0 -21
  351. package/skills/vds-skill/vds-scripts/docs/vi/agents/explanation/who-ecosystem-model.md +0 -36
  352. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/02-using-vds-ai-memory.md +0 -100
  353. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/03-memory-cross-agent.md +0 -243
  354. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/04-using-progress-reports.md +0 -242
  355. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/08-semantic-search.md +0 -16
  356. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/choose-the-right-command-or-skill.md +0 -36
  357. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/decision-tree.md +0 -77
  358. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/first-audit-run.md +0 -85
  359. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/index.md +0 -21
  360. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +0 -156
  361. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +0 -174
  362. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +0 -147
  363. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +0 -139
  364. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +0 -151
  365. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +0 -149
  366. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +0 -144
  367. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase131-all-project-preparation.md +0 -213
  368. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase131-bounded-parallel-analysis.md +0 -125
  369. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase131-confluence-upload-recovery.md +0 -206
  370. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/phase132-department-preparation.md +0 -146
  371. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/tips-and-tricks.md +0 -34
  372. package/skills/vds-skill/vds-scripts/docs/vi/agents/how-to/troubleshooting-guide.md +0 -36
  373. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/agent-operational-contract.md +0 -98
  374. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/audit-triage-playbook.md +0 -258
  375. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/bitbucket-orchestrator.md +0 -30
  376. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/brd-orchestrator.md +0 -29
  377. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/capability-coverage-review.md +0 -46
  378. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/circular-dependency-orchestrator.md +0 -29
  379. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/cli-commands.md +0 -409
  380. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/cli-development-standards.md +0 -19
  381. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/cli-help-matrix.md +0 -71
  382. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/common-errors.md +0 -133
  383. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/configuration-reference.md +0 -25
  384. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/confluence-orchestrator.md +0 -30
  385. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/db-query-orchestrator.md +0 -34
  386. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/diagrams-orchestrator.md +0 -31
  387. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/elastic-orchestrator.md +0 -30
  388. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/evolution-orchestrator.md +0 -31
  389. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/excel-orchestrator.md +0 -60
  390. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/git-orchestrator.md +0 -31
  391. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/google-sheets-orchestrator.md +0 -60
  392. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/grafana-orchestrator.md +0 -30
  393. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/hexagonal-orchestrator.md +0 -73
  394. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/index.md +0 -25
  395. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/intellij-orchestrator.md +0 -59
  396. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/jira-orchestrator.md +0 -32
  397. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/links-orchestrator.md +0 -66
  398. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/lsp-orchestrator.md +0 -60
  399. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/markdown-orchestrator.md +0 -62
  400. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/mcp-orchestrator.md +0 -34
  401. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/memory-orchestrator.md +0 -45
  402. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/metabase-orchestrator.md +0 -30
  403. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/multi-agent-orchestrator.md +0 -61
  404. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/openapi-orchestrator.md +0 -66
  405. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/orchestrator-architecture.md +0 -24
  406. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/orchestrator-index.md +0 -73
  407. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/pdf-orchestrator.md +0 -30
  408. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/portable-paths-and-config.md +0 -123
  409. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/portable-paths-validation-matrix.md +0 -131
  410. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/progress-orchestrator.md +0 -43
  411. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/progress-report-cli.md +0 -217
  412. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/public-interface-orchestrator.md +0 -82
  413. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/research-orchestrator.md +0 -45
  414. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/schema-orchestrator.md +0 -66
  415. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/search-tools.md +0 -19
  416. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/skills-reference.md +0 -27
  417. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/sonarqube-orchestrator.md +0 -71
  418. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/spec-orchestrator.md +0 -56
  419. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/structure-orchestrator.md +0 -78
  420. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/system-requirements.md +0 -30
  421. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/tasks-orchestrator.md +0 -45
  422. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/validation-and-sync-notes.md +0 -26
  423. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/vds-ai-memory-api.md +0 -53
  424. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/vds-cli-reference.md +0 -34
  425. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/who-capability-inventory.md +0 -98
  426. package/skills/vds-skill/vds-scripts/docs/vi/agents/reference/who-capability-routing-matrix.md +0 -16
  427. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/feature-progression-guide.md +0 -124
  428. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/index.md +0 -13
  429. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/quick-start.md +0 -30
  430. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/who-skills-and-scripts-onboarding.md +0 -42
  431. package/skills/vds-skill/vds-scripts/docs/vi/agents/tutorials/zero-to-productive-developer.md +0 -137
  432. package/skills/vds-skill/vds-scripts/elastic_orchestrator/README.md +0 -450
  433. package/skills/vds-skill/vds-scripts/elastic_orchestrator/pyproject.toml +0 -97
  434. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/__init__.py +0 -81
  435. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/cli.py +0 -652
  436. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/client.py +0 -743
  437. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/config.py +0 -208
  438. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/errors.py +0 -34
  439. package/skills/vds-skill/vds-scripts/elastic_orchestrator/src/vds_elastic_orchestrator/py.typed +0 -0
  440. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/__init__.py +0 -0
  441. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/conftest.py +0 -227
  442. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_client.py +0 -990
  443. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_config.py +0 -268
  444. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_e2e_verification.py +0 -272
  445. package/skills/vds-skill/vds-scripts/elastic_orchestrator/tests/test_errors.py +0 -78
  446. package/skills/vds-skill/vds-scripts/excel_orchestrator/README.md +0 -288
  447. package/skills/vds-skill/vds-scripts/excel_orchestrator/RESEARCH_BASED_UPDATES_REPORT.md +0 -261
  448. package/skills/vds-skill/vds-scripts/excel_orchestrator/add_essential_missing_effort.py +0 -255
  449. package/skills/vds-skill/vds-scripts/excel_orchestrator/adjust_effort_complexity.py +0 -184
  450. package/skills/vds-skill/vds-scripts/excel_orchestrator/brd_analysis_and_task_breakdown.py +0 -632
  451. package/skills/vds-skill/vds-scripts/excel_orchestrator/brd_analysis_comprehensive.py +0 -1029
  452. package/skills/vds-skill/vds-scripts/excel_orchestrator/check_overlaps_and_brd_coverage.py +0 -570
  453. package/skills/vds-skill/vds-scripts/excel_orchestrator/clean_remarks_column.py +0 -127
  454. package/skills/vds-skill/vds-scripts/excel_orchestrator/comprehensive_brd_check.py +0 -322
  455. package/skills/vds-skill/vds-scripts/excel_orchestrator/create_buffered_summary.py +0 -119
  456. package/skills/vds-skill/vds-scripts/excel_orchestrator/create_service_totals_sheet.py +0 -118
  457. package/skills/vds-skill/vds-scripts/excel_orchestrator/examples/basic_operations.py +0 -85
  458. package/skills/vds-skill/vds-scripts/excel_orchestrator/expand_all_tasks.py +0 -341
  459. package/skills/vds-skill/vds-scripts/excel_orchestrator/expand_tasks.py +0 -304
  460. package/skills/vds-skill/vds-scripts/excel_orchestrator/fill_brd_references.py +0 -347
  461. package/skills/vds-skill/vds-scripts/excel_orchestrator/fill_remarks_and_colors.py +0 -132
  462. package/skills/vds-skill/vds-scripts/excel_orchestrator/finalize_brd_and_cleanup.py +0 -295
  463. package/skills/vds-skill/vds-scripts/excel_orchestrator/finalize_brd_coverage.py +0 -327
  464. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_all_formulas.py +0 -99
  465. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_detail_presentation.py +0 -113
  466. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_presentation_and_effort.py +0 -116
  467. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_presentation_consistency.py +0 -231
  468. package/skills/vds-skill/vds-scripts/excel_orchestrator/fix_remarks_matching.py +0 -179
  469. package/skills/vds-skill/vds-scripts/excel_orchestrator/group_tasks_by_service_id.py +0 -210
  470. package/skills/vds-skill/vds-scripts/excel_orchestrator/increase_brd_coverage.py +0 -497
  471. package/skills/vds-skill/vds-scripts/excel_orchestrator/increase_effort_complexity.py +0 -155
  472. package/skills/vds-skill/vds-scripts/excel_orchestrator/organize_and_deduplicate.py +0 -273
  473. package/skills/vds-skill/vds-scripts/excel_orchestrator/pyproject.toml +0 -64
  474. package/skills/vds-skill/vds-scripts/excel_orchestrator/rebuild_all_formulas.py +0 -146
  475. package/skills/vds-skill/vds-scripts/excel_orchestrator/remove_base_multiplier_and_check_duplicates.py +0 -310
  476. package/skills/vds-skill/vds-scripts/excel_orchestrator/remove_duplicate_brd_tasks.py +0 -137
  477. package/skills/vds-skill/vds-scripts/excel_orchestrator/research_based_updates.py +0 -457
  478. package/skills/vds-skill/vds-scripts/excel_orchestrator/restore_e_values.py +0 -172
  479. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/__init__.py +0 -5
  480. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/cli.py +0 -746
  481. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/config.py +0 -74
  482. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/converters.py +0 -226
  483. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/errors.py +0 -88
  484. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/excel_client.py +0 -443
  485. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/formatters.py +0 -211
  486. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/logging.py +0 -57
  487. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/source_contract.py +0 -29
  488. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/target_state_status.py +0 -837
  489. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/ulnc_alignment.py +0 -1291
  490. package/skills/vds-skill/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/validators.py +0 -164
  491. package/skills/vds-skill/vds-scripts/excel_orchestrator/sync_detail_and_total_sheets.py +0 -211
  492. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/__init__.py +0 -1
  493. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/conftest.py +0 -36
  494. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_cli.py +0 -383
  495. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_excel_client.py +0 -129
  496. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_ulnc_alignment.py +0 -373
  497. package/skills/vds-skill/vds-scripts/excel_orchestrator/tests/test_validators.py +0 -64
  498. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_api_database_effort.py +0 -261
  499. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_buffers_inline.py +0 -115
  500. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_complex_services_and_add_new.py +0 -336
  501. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_responsibility_and_fix_rows.py +0 -208
  502. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_task_breakdown_vietnamese.py +0 -309
  503. package/skills/vds-skill/vds-scripts/excel_orchestrator/update_vietnamese_and_responsibility.py +0 -415
  504. package/skills/vds-skill/vds-scripts/excel_orchestrator/verify_brd_coverage_comprehensive.py +0 -401
  505. package/skills/vds-skill/vds-scripts/git_orchestrator/ENHANCEMENT_SUMMARY.md +0 -119
  506. package/skills/vds-skill/vds-scripts/git_orchestrator/README.md +0 -286
  507. package/skills/vds-skill/vds-scripts/git_orchestrator/VERIFICATION_REPORT.md +0 -152
  508. package/skills/vds-skill/vds-scripts/git_orchestrator/pyproject.toml +0 -37
  509. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__init__.py +0 -30
  510. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/__main__.py +0 -4
  511. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/branch_probe.py +0 -271
  512. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/cli.py +0 -892
  513. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/logging_config.py +0 -63
  514. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/manifest.py +0 -249
  515. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/orchestrator.py +0 -1647
  516. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/protocols.py +0 -35
  517. package/skills/vds-skill/vds-scripts/git_orchestrator/src/vds_git_orchestrator/reporting.py +0 -55
  518. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/__init__.py +0 -0
  519. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_cli_settings.py +0 -19
  520. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_integration.py +0 -79
  521. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_manifest.py +0 -79
  522. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_orchestrator.py +0 -207
  523. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_public_api.py +0 -235
  524. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/test_resilience.py +0 -343
  525. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/unit/__init__.py +0 -0
  526. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/unit/test_branch_probe.py +0 -327
  527. package/skills/vds-skill/vds-scripts/git_orchestrator/tests/unit/test_protocols.py +0 -132
  528. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/README.md +0 -241
  529. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/pyproject.toml +0 -45
  530. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/__init__.py +0 -69
  531. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/cli.py +0 -568
  532. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/client.py +0 -186
  533. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/config.py +0 -46
  534. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/errors.py +0 -41
  535. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/__init__.py +0 -1
  536. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/conftest.py +0 -1
  537. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/__init__.py +0 -1
  538. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/test_cli.py +0 -212
  539. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/test_client.py +0 -24
  540. package/skills/vds-skill/vds-scripts/google_sheets_orchestrator/tests/unit/test_config.py +0 -16
  541. package/skills/vds-skill/vds-scripts/grafana_orchestrator/README.md +0 -572
  542. package/skills/vds-skill/vds-scripts/grafana_orchestrator/pyproject.toml +0 -102
  543. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/__init__.py +0 -78
  544. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/cli.py +0 -455
  545. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/client.py +0 -700
  546. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/config.py +0 -243
  547. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/errors.py +0 -34
  548. package/skills/vds-skill/vds-scripts/grafana_orchestrator/src/vds_grafana_orchestrator/py.typed +0 -1
  549. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/__init__.py +0 -1
  550. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/conftest.py +0 -308
  551. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/test_client.py +0 -458
  552. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/test_config.py +0 -203
  553. package/skills/vds-skill/vds-scripts/grafana_orchestrator/tests/test_errors.py +0 -78
  554. package/skills/vds-skill/vds-scripts/jira_orchestrator/README.md +0 -864
  555. package/skills/vds-skill/vds-scripts/jira_orchestrator/pyproject.toml +0 -43
  556. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/__init__.py +0 -65
  557. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/adapter.py +0 -1685
  558. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/cli.py +0 -2806
  559. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/config.py +0 -168
  560. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/errors.py +0 -34
  561. package/skills/vds-skill/vds-scripts/jira_orchestrator/src/vds_jira_orchestrator/reporting.py +0 -66
  562. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/__init__.py +0 -1
  563. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/conftest.py +0 -86
  564. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_agile_list_payloads.py +0 -54
  565. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_bulk_operations.py +0 -91
  566. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_components.py +0 -56
  567. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_createmeta.py +0 -45
  568. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_dashboard.py +0 -119
  569. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_issue_properties.py +0 -53
  570. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_permissions_compat.py +0 -41
  571. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_reindex.py +0 -42
  572. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_remote_links.py +0 -75
  573. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_transitions.py +0 -90
  574. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_user_management.py +0 -116
  575. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_version_management.py +0 -181
  576. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_adapter_watchers.py +0 -43
  577. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_advanced_search.py +0 -179
  578. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_agile.py +0 -304
  579. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_application_properties.py +0 -243
  580. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_backlog.py +0 -91
  581. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_bulk_operations.py +0 -403
  582. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_cli.py +0 -108
  583. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_components.py +0 -119
  584. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_config.py +0 -166
  585. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_dashboard.py +0 -122
  586. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_discover_fields.py +0 -207
  587. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_errors.py +0 -72
  588. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_filter_management.py +0 -411
  589. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_issue_archiving.py +0 -179
  590. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_issue_links.py +0 -257
  591. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_issue_properties.py +0 -189
  592. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_link_types.py +0 -407
  593. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_parse_set.py +0 -37
  594. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_permissions.py +0 -343
  595. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_reindex.py +0 -81
  596. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_remote_links.py +0 -269
  597. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_security_schemes.py +0 -202
  598. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_transitions_changelog.py +0 -109
  599. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_user_management.py +0 -246
  600. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_version_management.py +0 -503
  601. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_watchers.py +0 -116
  602. package/skills/vds-skill/vds-scripts/jira_orchestrator/tests/test_worklog.py +0 -243
  603. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/README.md +0 -864
  604. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/pyproject.toml +0 -43
  605. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/__init__.py +0 -65
  606. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/adapter.py +0 -1689
  607. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/cli.py +0 -2799
  608. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/config.py +0 -137
  609. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/errors.py +0 -34
  610. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/reporting.py +0 -65
  611. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/__init__.py +0 -1
  612. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/conftest.py +0 -86
  613. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_agile_list_payloads.py +0 -54
  614. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_bulk_operations.py +0 -101
  615. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_components.py +0 -64
  616. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_createmeta.py +0 -45
  617. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_dashboard.py +0 -135
  618. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_issue_properties.py +0 -63
  619. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_permissions_compat.py +0 -42
  620. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_reindex.py +0 -42
  621. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_remote_links.py +0 -89
  622. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_transitions.py +0 -91
  623. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_user_management.py +0 -130
  624. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_version_management.py +0 -189
  625. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_adapter_watchers.py +0 -49
  626. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_advanced_search.py +0 -213
  627. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_agile.py +0 -334
  628. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_application_properties.py +0 -261
  629. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_backlog.py +0 -91
  630. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_bulk_operations.py +0 -443
  631. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_cli.py +0 -106
  632. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_components.py +0 -133
  633. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_config.py +0 -166
  634. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_dashboard.py +0 -130
  635. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_discover_fields.py +0 -207
  636. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_errors.py +0 -61
  637. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_filter_management.py +0 -478
  638. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_issue_archiving.py +0 -181
  639. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_issue_links.py +0 -257
  640. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_issue_properties.py +0 -203
  641. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_link_types.py +0 -426
  642. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_parse_set.py +0 -37
  643. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_permissions.py +0 -358
  644. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_reindex.py +0 -81
  645. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_remote_links.py +0 -292
  646. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_security_schemes.py +0 -218
  647. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_transitions_changelog.py +0 -121
  648. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_user_management.py +0 -283
  649. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_version_management.py +0 -561
  650. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_watchers.py +0 -128
  651. package/skills/vds-skill/vds-scripts/jira_viettelmoney_orchestrator/tests/test_worklog.py +0 -265
  652. package/skills/vds-skill/vds-scripts/llms.txt +0 -159
  653. package/skills/vds-skill/vds-scripts/markdown_orchestrator/README.md +0 -72
  654. package/skills/vds-skill/vds-scripts/markdown_orchestrator/pyproject.toml +0 -39
  655. package/skills/vds-skill/vds-scripts/markdown_orchestrator/src/vds_markdown_orchestrator/__init__.py +0 -5
  656. package/skills/vds-skill/vds-scripts/markdown_orchestrator/src/vds_markdown_orchestrator/cli.py +0 -102
  657. package/skills/vds-skill/vds-scripts/mcp_server/Dockerfile +0 -63
  658. package/skills/vds-skill/vds-scripts/mcp_server/README.md +0 -140
  659. package/skills/vds-skill/vds-scripts/mcp_server/pyproject.toml +0 -41
  660. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/__init__.py +0 -3
  661. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/config.py +0 -36
  662. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/server.py +0 -111
  663. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/__init__.py +0 -15
  664. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/bitbucket_tools.py +0 -47
  665. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/confluence_tools.py +0 -53
  666. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/git_tools.py +0 -71
  667. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/jira_tools.py +0 -63
  668. package/skills/vds-skill/vds-scripts/mcp_server/src/vds_mcp_server/tools/vidp_tools.py +0 -64
  669. package/skills/vds-skill/vds-scripts/mcp_server/tests/__init__.py +0 -1
  670. package/skills/vds-skill/vds-scripts/mcp_server/tests/conftest.py +0 -31
  671. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/__init__.py +0 -1
  672. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_bitbucket_tools.py +0 -28
  673. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_confluence_tools.py +0 -28
  674. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_git_tools.py +0 -35
  675. package/skills/vds-skill/vds-scripts/mcp_server/tests/unit/test_jira_tools.py +0 -35
  676. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/__init__.py +0 -6
  677. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/conftest.py +0 -51
  678. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/test_mcp_confluence_tools.py +0 -40
  679. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/test_mcp_jira_tools.py +0 -39
  680. package/skills/vds-skill/vds-scripts/mcp_server/tests/verification/test_mcp_tool_registration.py +0 -50
  681. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.dockerignore +0 -93
  682. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.env.example +0 -40
  683. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.ruff_rules.py +0 -350
  684. package/skills/vds-skill/vds-scripts/pdf_orchestrator/.yamllint.yml +0 -43
  685. package/skills/vds-skill/vds-scripts/pdf_orchestrator/DEVELOPMENT_PLAN.md +0 -80
  686. package/skills/vds-skill/vds-scripts/pdf_orchestrator/Dockerfile +0 -87
  687. package/skills/vds-skill/vds-scripts/pdf_orchestrator/README.md +0 -608
  688. package/skills/vds-skill/vds-scripts/pdf_orchestrator/cli_verification_test/test.md +0 -6
  689. package/skills/vds-skill/vds-scripts/pdf_orchestrator/cli_verification_test/test.pdf +0 -0
  690. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/alertmanager.yml +0 -83
  691. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/prometheus.prod.yml +0 -98
  692. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/prometheus.yml +0 -40
  693. package/skills/vds-skill/vds-scripts/pdf_orchestrator/config/redis.conf +0 -78
  694. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/COMPETITIVE_ANALYSIS_REPORT.md +0 -309
  695. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/FEATURES_GUIDE.md +0 -518
  696. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/MULTI_USER_DEPLOYMENT_GUIDE.md +0 -615
  697. package/skills/vds-skill/vds-scripts/pdf_orchestrator/docs/USER_GUIDE.md +0 -829
  698. package/skills/vds-skill/vds-scripts/pdf_orchestrator/pyproject.toml +0 -87
  699. package/skills/vds-skill/vds-scripts/pdf_orchestrator/pytest.ini +0 -71
  700. package/skills/vds-skill/vds-scripts/pdf_orchestrator/ruff.toml +0 -6
  701. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/debug_security_report.py +0 -59
  702. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/demo_library_selector.py +0 -109
  703. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/generate_project_stats.py +0 -52
  704. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/generate_styled_pdf.py +0 -95
  705. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/migrate_render_pdfs.py +0 -285
  706. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/setup_team.bat +0 -283
  707. package/skills/vds-skill/vds-scripts/pdf_orchestrator/scripts/setup_team.sh +0 -324
  708. package/skills/vds-skill/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/__init__.py +0 -5
  709. package/skills/vds-skill/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/cli.py +0 -542
  710. package/skills/vds-skill/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/config.py +0 -33
  711. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/README.md +0 -650
  712. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/__init__.py +0 -0
  713. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/conftest.py +0 -520
  714. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/requirements.txt +0 -51
  715. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/run_tests.py +0 -659
  716. package/skills/vds-skill/vds-scripts/pdf_orchestrator/tests/test_config.py +0 -36
  717. package/skills/vds-skill/vds-scripts/platform_core/pyproject.toml +0 -49
  718. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/__init__.py +0 -16
  719. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/alembic/__init__.py +0 -18
  720. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/alembic/runtime.py +0 -139
  721. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/config.py +0 -88
  722. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/credentials.py +0 -40
  723. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/env.py +0 -24
  724. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/errors.py +0 -127
  725. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/__init__.py +0 -18
  726. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/auth.py +0 -32
  727. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/errors.py +0 -47
  728. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/pagination.py +0 -65
  729. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/retry.py +0 -62
  730. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/http/stack.py +0 -61
  731. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/logging.py +0 -132
  732. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/protocols.py +0 -77
  733. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/serialization.py +0 -80
  734. package/skills/vds-skill/vds-scripts/platform_core/src/vds_platform_core/severity.py +0 -175
  735. package/skills/vds-skill/vds-scripts/platform_core/tests/__init__.py +0 -0
  736. package/skills/vds-skill/vds-scripts/platform_core/tests/conftest.py +0 -1
  737. package/skills/vds-skill/vds-scripts/platform_core/tests/test_alembic_runtime.py +0 -300
  738. package/skills/vds-skill/vds-scripts/platform_core/tests/test_auth.py +0 -84
  739. package/skills/vds-skill/vds-scripts/platform_core/tests/test_config.py +0 -83
  740. package/skills/vds-skill/vds-scripts/platform_core/tests/test_credentials.py +0 -73
  741. package/skills/vds-skill/vds-scripts/platform_core/tests/test_env.py +0 -56
  742. package/skills/vds-skill/vds-scripts/platform_core/tests/test_errors.py +0 -201
  743. package/skills/vds-skill/vds-scripts/platform_core/tests/test_errors_http.py +0 -74
  744. package/skills/vds-skill/vds-scripts/platform_core/tests/test_http_settings.py +0 -116
  745. package/skills/vds-skill/vds-scripts/platform_core/tests/test_logging.py +0 -148
  746. package/skills/vds-skill/vds-scripts/platform_core/tests/test_pagination.py +0 -153
  747. package/skills/vds-skill/vds-scripts/platform_core/tests/test_protocols.py +0 -132
  748. package/skills/vds-skill/vds-scripts/platform_core/tests/test_retry.py +0 -151
  749. package/skills/vds-skill/vds-scripts/platform_core/tests/test_serialization.py +0 -92
  750. package/skills/vds-skill/vds-scripts/platform_core/tests/test_severity.py +0 -178
  751. package/skills/vds-skill/vds-scripts/platform_core/tests/test_stack.py +0 -130
  752. package/skills/vds-skill/vds-scripts/platform_core/uv.lock +0 -341
  753. package/skills/vds-skill/vds-scripts/pyproject.toml +0 -145
  754. package/skills/vds-skill/vds-scripts/pyrightconfig.json +0 -82
  755. package/skills/vds-skill/vds-scripts/repo-manifest.yaml +0 -380
  756. package/skills/vds-skill/vds-scripts/repo-manifest.yaml.example +0 -25
  757. package/skills/vds-skill/vds-scripts/ruff.toml +0 -100
  758. package/skills/vds-skill/vds-scripts/scripts/BRD-Validation-API.postman_collection.json +0 -706
  759. package/skills/vds-skill/vds-scripts/scripts/BRD-Validation-README.md +0 -308
  760. package/skills/vds-skill/vds-scripts/scripts/README.md +0 -271
  761. package/skills/vds-skill/vds-scripts/scripts/_validate_alias_phase2.py +0 -137
  762. package/skills/vds-skill/vds-scripts/scripts/audit-cli-patterns.sh +0 -135
  763. package/skills/vds-skill/vds-scripts/scripts/audit-dashboard.sh +0 -525
  764. package/skills/vds-skill/vds-scripts/scripts/backup.sh +0 -123
  765. package/skills/vds-skill/vds-scripts/scripts/bootstrap_uv.sh +0 -69
  766. package/skills/vds-skill/vds-scripts/scripts/brd-validation-environment.json +0 -51
  767. package/skills/vds-skill/vds-scripts/scripts/brd-validation-test-results.json +0 -13023
  768. package/skills/vds-skill/vds-scripts/scripts/brd_coverage_report.json +0 -276
  769. package/skills/vds-skill/vds-scripts/scripts/check-future-annotations.py +0 -22
  770. package/skills/vds-skill/vds-scripts/scripts/check-invalid-symlinks.py +0 -183
  771. package/skills/vds-skill/vds-scripts/scripts/check-no-debug-markers.py +0 -21
  772. package/skills/vds-skill/vds-scripts/scripts/check-no-unittest.py +0 -21
  773. package/skills/vds-skill/vds-scripts/scripts/ci/assert_no_openspace_commits.sh +0 -37
  774. package/skills/vds-skill/vds-scripts/scripts/ci/verify_branch_protection.sh +0 -64
  775. package/skills/vds-skill/vds-scripts/scripts/closure/phase1_check.sh +0 -483
  776. package/skills/vds-skill/vds-scripts/scripts/closure/phase2_check.sh +0 -500
  777. package/skills/vds-skill/vds-scripts/scripts/create_memory_session.py +0 -36
  778. package/skills/vds-skill/vds-scripts/scripts/deploy-bootstrap.sh +0 -201
  779. package/skills/vds-skill/vds-scripts/scripts/deployment/load_docker_images_offline.sh +0 -90
  780. package/skills/vds-skill/vds-scripts/scripts/dev/cli_smoke.sh +0 -259
  781. package/skills/vds-skill/vds-scripts/scripts/final_completion_report.md +0 -139
  782. package/skills/vds-skill/vds-scripts/scripts/folder_structure_report.json +0 -321
  783. package/skills/vds-skill/vds-scripts/scripts/generate_completion_report.py +0 -132
  784. package/skills/vds-skill/vds-scripts/scripts/generate_intellij_modules.py +0 -154
  785. package/skills/vds-skill/vds-scripts/scripts/init-pgbouncer-userlist.sh +0 -154
  786. package/skills/vds-skill/vds-scripts/scripts/link_integrity_report.json +0 -807
  787. package/skills/vds-skill/vds-scripts/scripts/move_audit_artifact_pages.py +0 -252
  788. package/skills/vds-skill/vds-scripts/scripts/move_audit_artifact_pages_rest.py +0 -165
  789. package/skills/vds-skill/vds-scripts/scripts/move_wrong_dept_pages.py +0 -235
  790. package/skills/vds-skill/vds-scripts/scripts/openspace_bootstrap.sh +0 -56
  791. package/skills/vds-skill/vds-scripts/scripts/openspace_common.sh +0 -75
  792. package/skills/vds-skill/vds-scripts/scripts/openspace_doctor.sh +0 -61
  793. package/skills/vds-skill/vds-scripts/scripts/openspace_sync_shadow.sh +0 -65
  794. package/skills/vds-skill/vds-scripts/scripts/phase7-baseline.sh +0 -77
  795. package/skills/vds-skill/vds-scripts/scripts/preflight/env_check.sh +0 -102
  796. package/skills/vds-skill/vds-scripts/scripts/repair_autopay_reports.sh +0 -173
  797. package/skills/vds-skill/vds-scripts/scripts/rollback_drill.sh +0 -659
  798. package/skills/vds-skill/vds-scripts/scripts/run-audit-in-tmux.sh +0 -286
  799. package/skills/vds-skill/vds-scripts/scripts/run-department-audit.sh +0 -495
  800. package/skills/vds-skill/vds-scripts/scripts/run-project-audit.sh +0 -267
  801. package/skills/vds-skill/vds-scripts/scripts/save_intellij_memories.py +0 -112
  802. package/skills/vds-skill/vds-scripts/scripts/save_memories_to_vds_ai.py +0 -81
  803. package/skills/vds-skill/vds-scripts/scripts/save_memories_vds_style.py +0 -133
  804. package/skills/vds-skill/vds-scripts/scripts/search_intellij_memories.py +0 -48
  805. package/skills/vds-skill/vds-scripts/scripts/setup_intellij_workspace.py +0 -71
  806. package/skills/vds-skill/vds-scripts/scripts/smoke-test-deploy.sh +0 -137
  807. package/skills/vds-skill/vds-scripts/scripts/smoke_deploy_lib.py +0 -205
  808. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/README.md +0 -89
  809. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/confluence_sync_coordinator.sh +0 -27
  810. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/coordination.sh +0 -114
  811. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/diagram_coordinator.sh +0 -25
  812. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/docs_root.sh +0 -22
  813. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/generate_diagrams.sh +0 -22
  814. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/markdown_coordinator.sh +0 -25
  815. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/progress_dashboard.sh +0 -17
  816. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/schema_coordinator.sh +0 -25
  817. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/sync_confluence.sh +0 -30
  818. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/update_dependencies.sh +0 -19
  819. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_links.sh +0 -86
  820. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_markdown.sh +0 -52
  821. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_schemas.sh +0 -26
  822. package/skills/vds-skill/vds-scripts/scripts/target-state-automation/validate_structure.sh +0 -98
  823. package/skills/vds-skill/vds-scripts/scripts/tests/__init__.py +0 -1
  824. package/skills/vds-skill/vds-scripts/scripts/tests/test_dockerfile_correctness.py +0 -815
  825. package/skills/vds-skill/vds-scripts/scripts/tests/test_makefile_loadouts.py +0 -560
  826. package/skills/vds-skill/vds-scripts/scripts/tests/test_smoke_deploy.py +0 -313
  827. package/skills/vds-skill/vds-scripts/scripts/tests/test_verify_alembic.py +0 -581
  828. package/skills/vds-skill/vds-scripts/scripts/tests/test_verify_infra_topology.py +0 -254
  829. package/skills/vds-skill/vds-scripts/scripts/update_modules_xml.py +0 -194
  830. package/skills/vds-skill/vds-scripts/scripts/uv-workspace-alignment-verification-2026-03-25.md +0 -128
  831. package/skills/vds-skill/vds-scripts/scripts/uv-workspace-alignment-verification-2026-04-18.md +0 -100
  832. package/skills/vds-skill/vds-scripts/scripts/validate-cli-standardization.sh +0 -188
  833. package/skills/vds-skill/vds-scripts/scripts/validate_brd_coverage.py +0 -197
  834. package/skills/vds-skill/vds-scripts/scripts/validate_folder_structure.py +0 -234
  835. package/skills/vds-skill/vds-scripts/scripts/validate_link_integrity.py +0 -274
  836. package/skills/vds-skill/vds-scripts/scripts/vami017-caller-compat-report.md +0 -62
  837. package/skills/vds-skill/vds-scripts/scripts/vami017-phase-b-scaffold-notes.md +0 -79
  838. package/skills/vds-skill/vds-scripts/scripts/vds_sh_helpers.sh +0 -180
  839. package/skills/vds-skill/vds-scripts/scripts/verification/phase2_portable_paths_ubuntu_docker.sh +0 -26
  840. package/skills/vds-skill/vds-scripts/scripts/verify-infra-topology.py +0 -868
  841. package/skills/vds-skill/vds-scripts/scripts/verify-memory-cli-e2e.sh +0 -598
  842. package/skills/vds-skill/vds-scripts/scripts/verify-worktree-features.sh +0 -306
  843. package/skills/vds-skill/vds-scripts/scripts/worktree-add.sh +0 -128
  844. package/skills/vds-skill/vds-scripts/scripts/worktree-remove.sh +0 -112
  845. package/skills/vds-skill/vds-scripts/scripts/worktree_compose.sh +0 -269
  846. package/skills/vds-skill/vds-scripts/scripts/worktree_uv.sh +0 -77
  847. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/IMPLEMENTATION_AUDIT.md +0 -376
  848. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/README.md +0 -507
  849. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/pyproject.toml +0 -106
  850. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/scripts/ensure_symlink.sh +0 -38
  851. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/__init__.py +0 -164
  852. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/batch.py +0 -212
  853. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/cli.py +0 -1407
  854. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/client.py +0 -608
  855. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/config.py +0 -260
  856. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/diff.py +0 -220
  857. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/errors.py +0 -34
  858. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/external_sca.py +0 -932
  859. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/portfolio.py +0 -225
  860. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/pr.py +0 -505
  861. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/reports.py +0 -342
  862. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/scanner.py +0 -351
  863. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/webhooks.py +0 -269
  864. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/__init__.py +0 -0
  865. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/conftest.py +0 -134
  866. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_batch.py +0 -419
  867. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_config.py +0 -145
  868. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_errors.py +0 -78
  869. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_external_sca.py +0 -466
  870. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_pr.py +0 -471
  871. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_reports.py +0 -511
  872. package/skills/vds-skill/vds-scripts/sonarqube_orchestrator/tests/test_webhooks.py +0 -660
  873. package/skills/vds-skill/vds-scripts/uv.lock +0 -5046
  874. package/skills/vds-skill/vds-scripts/vds_agent_core/CHANGELOG.md +0 -36
  875. package/skills/vds-skill/vds-scripts/vds_agent_core/README.md +0 -453
  876. package/skills/vds-skill/vds-scripts/vds_agent_core/docs/PHASE9A_ASSESSMENT.md +0 -50
  877. package/skills/vds-skill/vds-scripts/vds_agent_core/docs/embedding.md +0 -468
  878. package/skills/vds-skill/vds-scripts/vds_agent_core/pyproject.toml +0 -51
  879. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/__init__.py +0 -29
  880. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/__init__.py +0 -26
  881. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/hooks.py +0 -119
  882. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/loop.py +0 -864
  883. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/agents/tools.py +0 -41
  884. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/config.py +0 -252
  885. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/__init__.py +0 -55
  886. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/_cascade.py +0 -143
  887. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/budget.py +0 -353
  888. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/cache.py +0 -373
  889. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/embedding.py +0 -815
  890. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/provider.py +0 -173
  891. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/llm/schemas.py +0 -45
  892. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/__init__.py +0 -77
  893. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/decorators.py +0 -258
  894. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/jsonl_exporter.py +0 -236
  895. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/observability/tracer.py +0 -497
  896. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/profiles.py +0 -2015
  897. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/runtime/__init__.py +0 -0
  898. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/runtime/agent_id.py +0 -60
  899. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/security/__init__.py +0 -13
  900. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/security/credentials.py +0 -106
  901. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/__init__.py +0 -1
  902. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/executor.py +0 -238
  903. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/manager.py +0 -381
  904. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/skills/policy.py +0 -568
  905. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/workflows/__init__.py +0 -19
  906. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/workflows/langgraph_runner.py +0 -102
  907. package/skills/vds-skill/vds-scripts/vds_agent_core/src/vds_agent_core/workflows/protocols.py +0 -81
  908. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/__init__.py +0 -0
  909. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/conftest.py +0 -62
  910. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/__init__.py +0 -0
  911. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/test_audit_loop_hooks_integration.py +0 -135
  912. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/test_audit_observability_integration.py +0 -246
  913. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/integration/test_public_api_stability.py +0 -91
  914. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/__init__.py +0 -0
  915. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/__init__.py +0 -0
  916. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_call_site_parallelism.py +0 -30
  917. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_dimension_guardrail.py +0 -25
  918. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_drop_in_provider_extensibility.py +0 -76
  919. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding.py +0 -393
  920. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding_cache.py +0 -302
  921. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding_extra.py +0 -696
  922. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_embedding_subclass.py +0 -49
  923. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_no_provider_leakage_in_env.py +0 -34
  924. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_provider_auto_route.py +0 -48
  925. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_runtime_log_clean.py +0 -111
  926. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/llm/test_w7_logic_fixes.py +0 -219
  927. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/__init__.py +0 -0
  928. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_embedding_block_parser.py +0 -194
  929. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_env_resolver_allowlist.py +0 -141
  930. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_profile_authorization.py +0 -158
  931. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_profiles_w3_extra.py +0 -547
  932. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/profiles/test_real_audit_profile_compat.py +0 -129
  933. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/runtime/__init__.py +0 -0
  934. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/runtime/test_for_agent.py +0 -322
  935. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/runtime/test_w9_cascade_edges.py +0 -369
  936. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/security/__init__.py +0 -0
  937. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/security/test_credentials.py +0 -132
  938. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_agent_loop.py +0 -663
  939. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_agent_loop_coverage.py +0 -429
  940. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_agents_hooks_defaults.py +0 -22
  941. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_budget.py +0 -155
  942. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_budget_coverage.py +0 -264
  943. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_budget_tracking_only.py +0 -71
  944. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_cache.py +0 -251
  945. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_cache_context.py +0 -62
  946. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_config.py +0 -155
  947. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_langgraph_runner.py +0 -45
  948. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_langgraph_runner_coverage.py +0 -98
  949. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_llm_cache_deep.py +0 -113
  950. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_decorators.py +0 -697
  951. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_hooks.py +0 -217
  952. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_jsonl_exporter.py +0 -542
  953. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_jsonl_wiring.py +0 -313
  954. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_observability_tracer.py +0 -896
  955. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_profiles.py +0 -1571
  956. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_profiles_coverage.py +0 -444
  957. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_provider.py +0 -316
  958. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_schemas.py +0 -63
  959. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_executor.py +0 -297
  960. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_manager.py +0 -370
  961. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_manager_coverage.py +0 -364
  962. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_policy.py +0 -402
  963. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_skill_rubric.py +0 -47
  964. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_tools.py +0 -51
  965. package/skills/vds-skill/vds-scripts/vds_agent_core/tests/unit/test_workflow_protocols.py +0 -136
  966. package/skills/vds-skill/vds-scripts/vds_cli/README.md +0 -201
  967. package/skills/vds-skill/vds-scripts/vds_cli/VERIFICATION_REPORT.md +0 -41
  968. package/skills/vds-skill/vds-scripts/vds_cli/pyproject.toml +0 -50
  969. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/__init__.py +0 -3
  970. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/assets/git-credential-helper.py +0 -235
  971. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/cli.py +0 -1158
  972. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/commands/__init__.py +0 -1
  973. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/commands/lint_cli.py +0 -389
  974. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/confluence_sync.py +0 -846
  975. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/consumption/__init__.py +0 -7
  976. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/consumption/funnel.py +0 -105
  977. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/consumption/scanner.py +0 -211
  978. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/freshness/report.py +0 -90
  979. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs/types.py +0 -27
  980. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs_cmd.py +0 -672
  981. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs_metrics.py +0 -75
  982. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/docs_sync.py +0 -1171
  983. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/ecosystem/__init__.py +0 -39
  984. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/ecosystem/report.py +0 -439
  985. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/ecosystem_docs.py +0 -164
  986. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/env.py +0 -111
  987. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/env_git_helper.py +0 -281
  988. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/__init__.py +0 -3
  989. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/google_sheets_orchestrator/google_sheets_orchestrator.py +0 -173
  990. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/router.py +0 -232
  991. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/skills_cmd.py +0 -274
  992. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/sync_api.py +0 -613
  993. package/skills/vds-skill/vds-scripts/vds_cli/src/vds_cli/sync_service.py +0 -283
  994. package/skills/vds-skill/vds-scripts/vds_cli/tests/conftest.py +0 -62
  995. package/skills/vds-skill/vds-scripts/vds_cli/tests/test_env_git_helper_lifecycle.py +0 -261
  996. package/skills/vds-skill/vds-scripts/vds_cli/tests/test_git_credential_helper.py +0 -240
  997. package/skills/vds-skill/vds-scripts/vds_cli/tests/test_router_help_proxy.py +0 -43
  998. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_cli.py +0 -264
  999. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_cli_DOC004.py +0 -110
  1000. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_confluence_sync.py +0 -315
  1001. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_confluence_sync_wave7.py +0 -375
  1002. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_consumption_funnel.py +0 -106
  1003. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_consumption_scanner.py +0 -144
  1004. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_cmd.py +0 -89
  1005. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_cmd_wave8.py +0 -161
  1006. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_metrics.py +0 -16
  1007. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_quality_score.py +0 -61
  1008. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_docs_sync.py +0 -417
  1009. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_ecosystem_cli_dashboard.py +0 -667
  1010. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_ecosystem_cli_dashboard_rendering.py +0 -143
  1011. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_ecosystem_docs.py +0 -63
  1012. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_env.py +0 -85
  1013. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_freshness_report.py +0 -125
  1014. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_lint_cli.py +0 -224
  1015. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_router.py +0 -101
  1016. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_skills_cmd.py +0 -419
  1017. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_sync_api.py +0 -357
  1018. package/skills/vds-skill/vds-scripts/vds_cli/tests/unit/test_sync_service.py +0 -170
  1019. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/conftest.py +0 -51
  1020. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/test_bitbucket_real.py +0 -32
  1021. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/test_confluence_real.py +0 -32
  1022. package/skills/vds-skill/vds-scripts/vds_cli/tests/verification/test_jira_real.py +0 -40
  1023. package/skills/vds-skill/vds-scripts/vds_cli_common/README.md +0 -190
  1024. package/skills/vds-skill/vds-scripts/vds_cli_common/pyproject.toml +0 -96
  1025. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/__init__.py +0 -36
  1026. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/app.py +0 -55
  1027. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/completers.py +0 -139
  1028. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/context.py +0 -201
  1029. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/env.py +0 -163
  1030. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/errors.py +0 -440
  1031. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/migrate_sdlc_config.py +0 -210
  1032. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/output.py +0 -284
  1033. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/paths.py +0 -78
  1034. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/testing.py +0 -211
  1035. package/skills/vds-skill/vds-scripts/vds_cli_common/src/vds_cli_common/version.py +0 -85
  1036. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/__init__.py +0 -0
  1037. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_app.py +0 -126
  1038. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_completers.py +0 -148
  1039. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_context.py +0 -192
  1040. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_env.py +0 -235
  1041. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_errors.py +0 -275
  1042. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_migrate_sdlc_config.py +0 -257
  1043. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_output.py +0 -229
  1044. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_paths.py +0 -61
  1045. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_testing.py +0 -138
  1046. package/skills/vds-skill/vds-scripts/vds_cli_common/tests/test_version.py +0 -64
  1047. package/skills/vds-skill/vds-scripts/vidp_orchestrator/README.md +0 -31
  1048. package/skills/vds-skill/vds-scripts/vidp_orchestrator/pyproject.toml +0 -50
  1049. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/__init__.py +0 -26
  1050. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/cli.py +0 -246
  1051. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/client.py +0 -104
  1052. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/config.py +0 -82
  1053. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.json +0 -3
  1054. package/skills/vds-skill/vds-scripts/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.py +0 -130
  1055. package/skills/vds-skill/vds-scripts-skill/.openskills.json +0 -6
  1056. package/skills/vds-skill/vds-scripts-skill/QUALITY.md +0 -44
  1057. package/skills/vds-skill/vds-scripts-skill/SKILL.md +0 -132
  1058. package/skills/vds-skill/vds-scripts-skill/references/audit-commands.md +0 -171
  1059. package/skills/vds-skill/vds-scripts-skill/references/capability-index.md +0 -34
  1060. package/skills/vds-skill/vds-scripts-skill/references/development-commands.md +0 -12
  1061. package/skills/vds-skill/vds-scripts-skill/references/google-sheets.md +0 -71
  1062. package/skills/vds-skill/vds-scripts-skill/references/integration-commands.md +0 -17
  1063. package/skills/vds-skill/vds-scripts-skill/references/platform-bootstrap.md +0 -31
  1064. package/skills/vds-skill/vds-scripts-skill/references/specialist-routing.md +0 -14
  1065. package/skills/vds-skill/vds-scripts-skill/references/validation-commands.md +0 -15
@@ -1,1833 +0,0 @@
1
- """Confluence tree crawling and on-disk export helpers.
2
-
3
- This module is intentionally dependency-light (std lib + BeautifulSoup) so the output
4
- can be used as input for downstream LLM/document analysis pipelines.
5
- """
6
-
7
- from __future__ import annotations
8
-
9
- import contextlib
10
- import hashlib
11
- import json
12
- import re
13
- import time
14
- import zipfile
15
- from collections.abc import Callable
16
- from concurrent.futures import Future, ThreadPoolExecutor
17
- from dataclasses import dataclass, field
18
- from datetime import UTC, datetime, timedelta
19
- from pathlib import Path
20
- from typing import TYPE_CHECKING, Any
21
- from urllib.parse import parse_qs, unquote, urlparse
22
-
23
- from bs4 import BeautifulSoup
24
-
25
- if TYPE_CHECKING:
26
- from .http import ConfluenceClient
27
-
28
- _JIRA_KEY_RE = re.compile(r"\b[A-Z][A-Z0-9]+-\d+\b")
29
- _MIME_SUFFIX_MAP: dict[str, str] = {
30
- "application/json": ".json",
31
- "application/msword": ".doc",
32
- "application/pdf": ".pdf",
33
- "application/vnd.jgraph.mxfile": ".drawio",
34
- "application/vnd.ms-excel": ".xls",
35
- "application/vnd.ms-powerpoint": ".ppt",
36
- "application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
37
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
38
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
39
- "image/gif": ".gif",
40
- "image/jpeg": ".jpg",
41
- "image/png": ".png",
42
- "image/svg+xml": ".svg",
43
- "text/csv": ".csv",
44
- "text/plain": ".txt",
45
- }
46
-
47
-
48
- def _now_iso() -> str:
49
- return datetime.now(UTC).isoformat()
50
-
51
-
52
- def _sha256_bytes(data: bytes) -> str:
53
- return hashlib.sha256(data).hexdigest()
54
-
55
-
56
- def _sha256_text(text: str) -> str:
57
- return _sha256_bytes(text.encode("utf-8"))
58
-
59
-
60
- def _parse_iso_timestamp(value: str | None) -> datetime | None:
61
- if not value:
62
- return None
63
- cleaned = value.strip()
64
- if not cleaned:
65
- return None
66
- if cleaned.endswith("Z"):
67
- cleaned = f"{cleaned[:-1]}+00:00"
68
- try:
69
- parsed = datetime.fromisoformat(cleaned)
70
- except ValueError:
71
- return None
72
- if parsed.tzinfo is None:
73
- return parsed.replace(tzinfo=UTC)
74
- return parsed.astimezone(UTC)
75
-
76
-
77
- def _safe_filename(name: str) -> str:
78
- # Preserve unicode for VN titles, but remove path separators + control chars.
79
- cleaned = name.replace("/", "-").replace("\\", "-").replace("\0", "")
80
- cleaned = re.sub(r"[\r\n\t]+", " ", cleaned).strip()
81
- return cleaned or "untitled"
82
-
83
-
84
- def _normalise_suffix(value: str) -> str:
85
- cleaned = (value or "").strip().lower()
86
- if not cleaned:
87
- return ""
88
- return cleaned if cleaned.startswith(".") else f".{cleaned}"
89
-
90
-
91
- def _guess_attachment_suffix(attachment: dict[str, Any]) -> str | None:
92
- extensions = attachment.get("extensions") or {}
93
- metadata = attachment.get("metadata") or {}
94
-
95
- if isinstance(extensions, dict):
96
- ext = extensions.get("fileExtension") or extensions.get("file_extension")
97
- if isinstance(ext, str) and ext.strip():
98
- normalised = _normalise_suffix(ext)
99
- return normalised if normalised else None
100
-
101
- media_type = None
102
- if isinstance(extensions, dict):
103
- media_type = extensions.get("mediaType") or extensions.get("media_type")
104
- if not media_type and isinstance(metadata, dict):
105
- media_type = metadata.get("mediaType") or metadata.get("media_type")
106
-
107
- if isinstance(media_type, str) and media_type.strip():
108
- mapped = _MIME_SUFFIX_MAP.get(media_type.strip().lower())
109
- if mapped:
110
- return mapped
111
- return None
112
-
113
-
114
- def _safe_attachment_filename(attachment_id: str, title: str, *, fallback_suffix: str | None = None) -> str:
115
- safe_title = _safe_filename(title)
116
- path = Path(safe_title)
117
- stem = path.stem or "attachment"
118
- suffix = path.suffix
119
- if not suffix and fallback_suffix:
120
- suffix = _normalise_suffix(fallback_suffix)
121
-
122
- # Keep filenames under typical filesystem limits (255 bytes). We preserve the
123
- # attachment id prefix for stability and trim the human title if needed.
124
- max_stem_length = 180
125
- if len(stem) > max_stem_length:
126
- stem = stem[:max_stem_length].rstrip()
127
- safe_title = f"{stem}{suffix}"
128
- return f"{attachment_id}_{safe_title}"
129
-
130
-
131
- def _escape_cql(value: str) -> str:
132
- return value.replace("\\", "\\\\").replace('"', '\\"')
133
-
134
-
135
- def resolve_page_ref(page_ref: str, http: ConfluenceClient) -> str:
136
- """Resolve a page reference to a numeric page ID.
137
-
138
- Supported forms:
139
- - numeric ID: "74014717"
140
- - viewpage: ".../pages/viewpage.action?pageId=74014717"
141
- - display URL: ".../display/TDOV/13.02.10.+BRD"
142
- """
143
- page_ref = (page_ref or "").strip()
144
- if not page_ref:
145
- raise ValueError("page_ref is empty")
146
-
147
- if page_ref.isdigit():
148
- return page_ref
149
-
150
- parsed = urlparse(page_ref)
151
- if parsed.query:
152
- qs = parse_qs(parsed.query)
153
- page_ids = qs.get("pageId") or qs.get("pageid")
154
- if page_ids and page_ids[0].isdigit():
155
- return page_ids[0]
156
-
157
- # /display/<SPACE>/<TITLE>
158
- match = re.search(r"/display/([^/]+)/(.+)$", parsed.path or "")
159
- if match:
160
- space = unquote(match.group(1))
161
- # Confluence "display" URLs often encode spaces as '+'
162
- title = unquote(match.group(2)).replace("+", " ").strip()
163
- cql = f'space="{_escape_cql(space)}" and title="{_escape_cql(title)}" and type=page'
164
- result = http.search_cql(cql, limit=5)
165
- results = result.get("results", []) if isinstance(result, dict) else []
166
- for item in results:
167
- if not isinstance(item, dict):
168
- continue
169
- # Confluence CQL results usually wrap content under `content`.
170
- raw_id = item.get("id")
171
- if raw_id is None and isinstance(item.get("content"), dict):
172
- raw_id = item["content"].get("id")
173
- if raw_id is not None and str(raw_id).isdigit():
174
- return str(raw_id)
175
-
176
- raise ValueError(f"Unable to resolve display URL to page ID (space={space!r}, title={title!r})")
177
-
178
- raise ValueError(f"Unsupported page reference: {page_ref}")
179
-
180
-
181
- @dataclass(slots=True)
182
- class CrawlOptions:
183
- max_depth: int = 3
184
- include_attachments: bool = True
185
- emit_corpus: bool = False
186
- emit_link_graph: bool = False
187
- emit_tables: bool = False
188
- emit_mentions: bool = False
189
- body_format: str = "view"
190
- chunk_max_chars: int | None = 4000
191
- resume: bool = False
192
- max_nodes: int | None = 500
193
- bundle: bool = False
194
- page_concurrency: int = 5
195
- staged_mode: str = "off"
196
- incremental_cql: bool = True
197
- incremental_overlap_minutes: int = 5
198
- full_reconciliation_interval_days: int = 7
199
- rate_limit_budget: int = 50_000
200
- runtime_event_sink: Callable[[str, dict[str, Any]], None] | None = None
201
-
202
-
203
- def _emit_runtime_event(options: CrawlOptions, event: str, **payload: Any) -> None:
204
- if not callable(options.runtime_event_sink):
205
- return
206
- try:
207
- options.runtime_event_sink(event, payload)
208
- except Exception:
209
- return
210
-
211
-
212
- def _create_bundle_zip(output_dir: Path, root_page_id: str, manifest_path: Path) -> Path:
213
- """Create a zip bundle of all crawl artifacts for offline handoff (TSK-189)."""
214
- timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S")
215
- bundle_name = f"crawl_bundle_{root_page_id}_{timestamp}.zip"
216
- bundle_path = output_dir / bundle_name
217
-
218
- with zipfile.ZipFile(bundle_path, "w", zipfile.ZIP_DEFLATED) as zf:
219
- # Add all HTML files
220
- for html_file in output_dir.glob("*.html"):
221
- zf.write(html_file, html_file.name)
222
-
223
- # Add attachments directory
224
- attachments_dir = output_dir / "attachments"
225
- if attachments_dir.exists():
226
- for att_file in attachments_dir.iterdir():
227
- if att_file.is_file():
228
- zf.write(att_file, f"attachments/{att_file.name}")
229
-
230
- # Add artifact files
231
- artifact_files = [
232
- "corpus.jsonl",
233
- "link-graph.json",
234
- "tables.jsonl",
235
- "mentions.jsonl",
236
- "crawl_state.json",
237
- ]
238
- for artifact_name in artifact_files:
239
- artifact_path = output_dir / artifact_name
240
- if artifact_path.exists():
241
- zf.write(artifact_path, artifact_name)
242
-
243
- # Add manifest
244
- if manifest_path.exists():
245
- zf.write(manifest_path, manifest_path.name)
246
-
247
- return bundle_path
248
-
249
-
250
- @dataclass(slots=True)
251
- class CrawlState:
252
- """Persistent crawl state for resume/incremental crawling (TSK-188)."""
253
-
254
- root_page_id: str
255
- body_format: str
256
- visited_pages: dict[str, dict[str, Any]] # page_id -> {version, html_sha256, visited_at}
257
- pending_queue: list[tuple[str, str | None, int]] # [(page_id, parent_id, depth), ...]
258
- started_at: str
259
- last_updated_at: str
260
- completed: bool = False
261
- last_sync_timestamp: str | None = None
262
- last_full_reconciliation_timestamp: str | None = None
263
- run_diagnostics: dict[str, Any] = field(default_factory=dict)
264
-
265
- def to_dict(self) -> dict[str, Any]:
266
- """Serialize state to JSON-compatible dict."""
267
- return {
268
- "root_page_id": self.root_page_id,
269
- "body_format": self.body_format,
270
- "visited_pages": self.visited_pages,
271
- "pending_queue": [list(item) for item in self.pending_queue],
272
- "started_at": self.started_at,
273
- "last_updated_at": self.last_updated_at,
274
- "completed": self.completed,
275
- "last_sync_timestamp": self.last_sync_timestamp,
276
- "last_full_reconciliation_timestamp": self.last_full_reconciliation_timestamp,
277
- "run_diagnostics": self.run_diagnostics,
278
- }
279
-
280
- @classmethod
281
- def from_dict(cls, data: dict[str, Any]) -> CrawlState:
282
- """Deserialize state from JSON-compatible dict."""
283
- return cls(
284
- root_page_id=data["root_page_id"],
285
- body_format=data.get("body_format", "view"),
286
- visited_pages=data.get("visited_pages", {}),
287
- pending_queue=[tuple(item) for item in data.get("pending_queue", [])],
288
- started_at=data.get("started_at", _now_iso()),
289
- last_updated_at=data.get("last_updated_at", _now_iso()),
290
- completed=data.get("completed", False),
291
- last_sync_timestamp=data.get("last_sync_timestamp"),
292
- last_full_reconciliation_timestamp=data.get("last_full_reconciliation_timestamp"),
293
- run_diagnostics=data.get("run_diagnostics", {}),
294
- )
295
-
296
- def is_page_unchanged(self, page_id: str, version: int | None, html_sha256: str | None) -> bool:
297
- """Check if a page is unchanged since last crawl."""
298
- if page_id not in self.visited_pages:
299
- return False
300
- prev = self.visited_pages[page_id]
301
- prev_version = prev.get("version")
302
- prev_hash = prev.get("html_sha256")
303
- # If both version and hash match, page is unchanged
304
- if prev_version is not None and version is not None and prev_version == version:
305
- return True
306
- return bool(prev_hash is not None and html_sha256 is not None and prev_hash == html_sha256)
307
-
308
- def record_page(self, page_id: str, version: int | None, html_sha256: str | None) -> None:
309
- """Record a visited page."""
310
- self.visited_pages[page_id] = {
311
- "version": version,
312
- "html_sha256": html_sha256,
313
- "visited_at": _now_iso(),
314
- }
315
- self.last_updated_at = _now_iso()
316
-
317
-
318
- @dataclass(slots=True)
319
- class _FetchedPage:
320
- page_id: str
321
- parent_id: str | None
322
- depth: int
323
- status: str # fetched|unchanged|error
324
- page_payload: dict[str, Any] | None = None
325
- version_payload: dict[str, Any] | None = None
326
- children: list[tuple[str, str | None, int]] = field(default_factory=list)
327
- error: str | None = None
328
-
329
-
330
- def _load_crawl_state(state_path: Path) -> CrawlState | None:
331
- """Load crawl state from disk if it exists."""
332
- if not state_path.exists():
333
- return None
334
- try:
335
- data = json.loads(state_path.read_text(encoding="utf-8"))
336
- return CrawlState.from_dict(data)
337
- except (json.JSONDecodeError, KeyError, TypeError):
338
- return None
339
-
340
-
341
- def _save_crawl_state(state: CrawlState, state_path: Path) -> None:
342
- """Persist crawl state to disk."""
343
- state.last_updated_at = _now_iso()
344
- state_path.write_text(json.dumps(state.to_dict(), ensure_ascii=False, indent=2), encoding="utf-8")
345
-
346
-
347
- def _normalise_body_format(value: str | None) -> str:
348
- normalised = (value or "view").strip().lower().replace("-", "_")
349
- if normalised in {"view", "storage", "export_view"}:
350
- return normalised
351
- raise ValueError(f"Unsupported body format: {value!r} (expected: view|export_view|storage)")
352
-
353
-
354
- def _normalise_page_concurrency(value: int | None) -> int:
355
- if value is None:
356
- return 5
357
- return max(1, int(value))
358
-
359
-
360
- def _normalise_staged_mode(value: str | None) -> str:
361
- normalised = (value or "off").strip().lower().replace("-", "_")
362
- if normalised in {"off", "structure_first"}:
363
- return normalised
364
- raise ValueError(f"Unsupported staged mode: {value!r} (expected: off|structure_first)")
365
-
366
-
367
- def _split_text_preserving_words(text: str, max_chars: int) -> list[str]:
368
- """Split a long string into <= max_chars chunks, preferring whitespace boundaries."""
369
- stripped = (text or "").strip()
370
- if not stripped:
371
- return []
372
- if max_chars <= 0:
373
- return [stripped]
374
- if len(stripped) <= max_chars:
375
- return [stripped]
376
-
377
- words = stripped.split()
378
- parts: list[str] = []
379
- current: list[str] = []
380
- current_len = 0
381
-
382
- def flush() -> None:
383
- nonlocal current, current_len
384
- if not current:
385
- return
386
- parts.append(" ".join(current))
387
- current = []
388
- current_len = 0
389
-
390
- for word in words:
391
- if not current:
392
- current = [word]
393
- current_len = len(word)
394
- elif current_len + 1 + len(word) <= max_chars:
395
- current.append(word)
396
- current_len += 1 + len(word)
397
- else:
398
- flush()
399
- if len(word) <= max_chars:
400
- current = [word]
401
- current_len = len(word)
402
- else:
403
- # Pathological case: a single token exceeds max_chars; hard-split.
404
- for offset in range(0, len(word), max_chars):
405
- parts.append(word[offset : offset + max_chars])
406
-
407
- flush()
408
- return parts
409
-
410
-
411
- def _pack_segments(segments: list[str], max_chars: int) -> list[str]:
412
- if max_chars <= 0:
413
- joined = "\n".join([seg for seg in segments if seg.strip()]).strip()
414
- return [joined] if joined else []
415
-
416
- packed: list[str] = []
417
- current: list[str] = []
418
- current_len = 0
419
-
420
- def flush() -> None:
421
- nonlocal current, current_len
422
- if not current:
423
- return
424
- packed.append("\n".join(current).strip())
425
- current = []
426
- current_len = 0
427
-
428
- for seg in segments:
429
- seg = (seg or "").strip()
430
- if not seg:
431
- continue
432
- sep_len = 1 if current else 0 # newline
433
- if not current or current_len + sep_len + len(seg) <= max_chars:
434
- if current:
435
- current_len += 1
436
- current.append(seg)
437
- current_len += len(seg)
438
- continue
439
-
440
- flush()
441
- current = [seg]
442
- current_len = len(seg)
443
-
444
- flush()
445
- return [chunk for chunk in packed if chunk.strip()]
446
-
447
-
448
- def _extract_target_page_id(target_url: str | None) -> str | None:
449
- if not target_url:
450
- return None
451
-
452
- parsed = urlparse(target_url)
453
- if parsed.query:
454
- qs = parse_qs(parsed.query)
455
- for key, values in qs.items():
456
- if key.lower() != "pageid" or not values:
457
- continue
458
- candidate = values[0]
459
- if isinstance(candidate, str) and candidate.isdigit():
460
- return candidate
461
-
462
- match = re.search(r"/pages/(\d+)(?:/|$)", parsed.path or "")
463
- if match:
464
- return match.group(1)
465
- return None
466
-
467
-
468
- def _classify_target_type(target_url: str | None) -> str | None:
469
- if not target_url:
470
- return None
471
-
472
- url = target_url.strip()
473
- if not url:
474
- return None
475
- if url.startswith("mailto:"):
476
- return "email"
477
-
478
- parsed = urlparse(url)
479
- host = (parsed.netloc or "").lower()
480
- path = parsed.path or ""
481
-
482
- if "/display/" in path or "viewpage.action" in path or re.search(r"/pages/\d+(?:/|$)", path):
483
- return "confluence_page"
484
- if "jira" in host or "/browse/" in path:
485
- return "jira"
486
- if "bitbucket" in host or "/scm/" in path:
487
- return "bitbucket"
488
- if parsed.scheme in {"http", "https"}:
489
- return "external"
490
- return "external"
491
-
492
-
493
- def _extract_jira_key_from_url(url: str) -> str | None:
494
- parsed = urlparse(url)
495
- match = re.search(r"/browse/([A-Z][A-Z0-9]+-\d+)", parsed.path or "")
496
- if match:
497
- return match.group(1)
498
- return None
499
-
500
-
501
- def _extract_links(html: str, *, base_url: str | None = None) -> list[dict[str, Any]]:
502
- soup = BeautifulSoup(html, "html.parser")
503
- links: list[dict[str, Any]] = []
504
- for a in soup.find_all("a"):
505
- href = a.get("href")
506
- if not href:
507
- continue
508
- href = str(href).strip()
509
- if not href:
510
- continue
511
- text = a.get_text(" ", strip=True) or None
512
- links.append({"href": href, "text": text})
513
- if not base_url:
514
- return links
515
-
516
- normalized: list[dict[str, Any]] = []
517
- base = base_url.rstrip("/")
518
- for entry in links:
519
- href = entry["href"]
520
- if href.startswith("#"):
521
- continue
522
- if href.startswith(("http://", "https://")):
523
- url = href
524
- elif href.startswith("/"):
525
- url = f"{base}{href}"
526
- else:
527
- # best-effort: keep as-is (could be relative to current page)
528
- url = href
529
- # Drop fragments for canonicalization
530
- parsed = urlparse(url)
531
- url = parsed._replace(fragment="").geturl()
532
- normalized.append({"url": url, "text": entry.get("text")})
533
- return normalized
534
-
535
-
536
- def _chunk_html_by_headings(html: str, *, max_chars: int | None = None) -> list[dict[str, Any]]:
537
- """Chunk HTML into heading-scoped blocks for JSONL corpus output."""
538
- soup = BeautifulSoup(html, "html.parser")
539
-
540
- chunks: list[dict[str, Any]] = []
541
- heading_stack: list[str] = []
542
- buffer: list[str] = []
543
-
544
- def flush() -> None:
545
- nonlocal buffer
546
- lines = [line for line in buffer if line.strip()]
547
- buffer = []
548
- if not lines:
549
- return
550
-
551
- segments: list[str] = []
552
- max_limit = max_chars if isinstance(max_chars, int) and max_chars > 0 else None
553
- for line in lines:
554
- if max_limit and len(line) > max_limit:
555
- segments.extend(_split_text_preserving_words(line, max_limit))
556
- else:
557
- segments.append(line.strip())
558
-
559
- if max_limit is None:
560
- text = "\n".join([seg for seg in segments if seg.strip()]).strip()
561
- if text:
562
- chunks.append({"heading_path": list(heading_stack), "text": text, "ordinal": 0})
563
- return
564
-
565
- for ordinal, text in enumerate(_pack_segments(segments, max_limit)):
566
- chunks.append({"heading_path": list(heading_stack), "text": text, "ordinal": ordinal})
567
-
568
- for el in soup.find_all(["h1", "h2", "h3", "h4", "h5", "h6", "p", "li", "pre"]):
569
- name = el.name.lower()
570
- if name.startswith("h"):
571
- flush()
572
- level = int(name[1])
573
- title = el.get_text(" ", strip=True)
574
- if not title:
575
- continue
576
- heading_stack[:] = heading_stack[: max(0, level - 1)]
577
- heading_stack.append(title)
578
- continue
579
-
580
- text = el.get_text(" ", strip=True)
581
- if not text:
582
- continue
583
- buffer.append(text)
584
-
585
- flush()
586
- return chunks
587
-
588
-
589
- def _extract_tables(html: str) -> list[dict[str, Any]]:
590
- soup = BeautifulSoup(html, "html.parser")
591
- extracted: list[dict[str, Any]] = []
592
-
593
- for index, table in enumerate(soup.find_all("table")):
594
- headers: list[str] | None = None
595
- rows: list[list[str]] = []
596
-
597
- # Prefer explicit <thead> headers when present.
598
- thead = table.find("thead")
599
- if thead:
600
- head_row = thead.find("tr")
601
- if head_row:
602
- header_cells = head_row.find_all(["th", "td"])
603
- header_texts = [cell.get_text(" ", strip=True) for cell in header_cells]
604
- headers = [h for h in header_texts if h]
605
-
606
- # Extract all row cells.
607
- for tr in table.find_all("tr"):
608
- cells = tr.find_all(["th", "td"])
609
- if not cells:
610
- continue
611
- row = [cell.get_text(" ", strip=True) for cell in cells]
612
- row = [cell for cell in row if cell]
613
- if row:
614
- rows.append(row)
615
-
616
- # If we did not find a <thead>, treat the first row with <th> as headers.
617
- if headers is None and rows:
618
- first_tr = table.find("tr")
619
- if first_tr and first_tr.find("th"):
620
- headers = rows[0]
621
- rows = rows[1:]
622
-
623
- extracted.append(
624
- {
625
- "table_index": index,
626
- "headers": headers,
627
- "rows": rows,
628
- "row_count": len(rows),
629
- "col_count": max((len(row) for row in rows), default=0),
630
- }
631
- )
632
-
633
- return extracted
634
-
635
-
636
- def _extract_mentions(html: str, *, base_url: str | None = None) -> list[dict[str, Any]]:
637
- soup = BeautifulSoup(html, "html.parser")
638
- extracted: list[dict[str, Any]] = []
639
-
640
- # 1) Link-based mentions (already normalized by base_url when provided).
641
- for link in _extract_links(html, base_url=base_url):
642
- url = str(link.get("url") or "").strip()
643
- if not url:
644
- continue
645
-
646
- mention_type = _classify_target_type(url)
647
- if mention_type == "confluence_page":
648
- value = _extract_target_page_id(url) or url
649
- elif mention_type == "jira":
650
- value = _extract_jira_key_from_url(url) or url
651
- elif mention_type == "email":
652
- value = url.removeprefix("mailto:").strip() or url
653
- else:
654
- value = url
655
-
656
- extracted.append(
657
- {
658
- "type": mention_type or "external",
659
- "value": value,
660
- "url": url,
661
- "anchor_text": link.get("text"),
662
- "source": "link",
663
- }
664
- )
665
-
666
- # 2) Plain-text Jira keys (best-effort).
667
- plain_text = soup.get_text(" ", strip=True)
668
- for key in sorted(set(_JIRA_KEY_RE.findall(plain_text or ""))):
669
- extracted.append(
670
- {
671
- "type": "jira_key",
672
- "value": key,
673
- "url": None,
674
- "anchor_text": None,
675
- "source": "text",
676
- }
677
- )
678
-
679
- # Deduplicate mentions by stable key and keep deterministic ordering.
680
- seen: set[tuple[str, str, str | None]] = set()
681
- unique: list[dict[str, Any]] = []
682
- for entry in extracted:
683
- mention_type = str(entry.get("type") or "").strip() or "external"
684
- value = str(entry.get("value") or "").strip()
685
- url = entry.get("url")
686
- url = str(url).strip() if isinstance(url, str) else None
687
- if not value:
688
- continue
689
- key = (mention_type, value, url)
690
- if key in seen:
691
- continue
692
- seen.add(key)
693
- unique.append({**entry, "type": mention_type, "value": value, "url": url})
694
-
695
- unique.sort(key=lambda m: (m.get("type") or "", m.get("value") or "", m.get("url") or ""))
696
- return unique
697
-
698
-
699
- def crawl_tree_to_disk(
700
- *,
701
- http: ConfluenceClient,
702
- root_ref: str,
703
- output_dir: Path,
704
- options: CrawlOptions,
705
- manifest_path: Path | None = None,
706
- ) -> dict[str, Any]:
707
- """Crawl a Confluence page tree and download content/attachments to disk.
708
-
709
- Supports resume/incremental crawling (TSK-188):
710
- - resume=True: Load state from previous run, skip unchanged pages
711
- - max_nodes: Limit total pages processed (safety for large trees)
712
- """
713
- body_format = _normalise_body_format(options.body_format)
714
- page_concurrency = _normalise_page_concurrency(options.page_concurrency)
715
- staged_mode = _normalise_staged_mode(options.staged_mode)
716
- use_structure_first = staged_mode == "structure_first"
717
- chunk_max_chars = options.chunk_max_chars if isinstance(options.chunk_max_chars, int) else None
718
- resolved_root_id = resolve_page_ref(root_ref, http)
719
- output_dir = output_dir.resolve()
720
- output_dir.mkdir(parents=True, exist_ok=True)
721
- attachments_dir = output_dir / "attachments"
722
- attachments_dir.mkdir(exist_ok=True)
723
- resolved_manifest_path = manifest_path or (output_dir / "crawl_manifest.json")
724
-
725
- def _meta_from_existing_html(
726
- *,
727
- page_id: str,
728
- parent_id: str | None,
729
- depth: int,
730
- page_payload: dict[str, Any] | None,
731
- ) -> dict[str, Any]:
732
- html_candidates = sorted(output_dir.glob(f"{page_id}_*.html"))
733
- html_path = html_candidates[0] if html_candidates else None
734
- title = None
735
- page_url = None
736
- page_version = None
737
- page_updated = None
738
- space_key = None
739
- if isinstance(page_payload, dict):
740
- raw_title = page_payload.get("title")
741
- if raw_title:
742
- title = str(raw_title)
743
- links = page_payload.get("_links")
744
- if isinstance(links, dict):
745
- base_url = str(links.get("base") or "")
746
- web_ui = str(links.get("webui") or "")
747
- page_url = f"{base_url}{web_ui}" if base_url and web_ui else None
748
- version = page_payload.get("version")
749
- if isinstance(version, dict):
750
- page_version = version.get("number")
751
- page_updated = version.get("when")
752
- space = page_payload.get("space")
753
- if isinstance(space, dict):
754
- raw_space = space.get("key")
755
- if raw_space:
756
- space_key = str(raw_space)
757
- if title is None and html_path is not None:
758
- title = html_path.stem.split("_", 1)[1] if "_" in html_path.stem else html_path.stem
759
-
760
- meta: dict[str, Any] = {
761
- "page_id": page_id,
762
- "title": title,
763
- "page_url": page_url,
764
- "parent_id": parent_id,
765
- "depth": depth,
766
- "status": "downloaded" if html_path is not None else "unchanged",
767
- "html_path": str(html_path) if html_path is not None else None,
768
- "html_sha256": None,
769
- "html_size_bytes": None,
770
- "source_format": "html-view",
771
- "space_key": space_key,
772
- "page_version": page_version,
773
- "page_updated": page_updated,
774
- "ancestor_ids": [],
775
- "ancestor_titles": [],
776
- "error": None,
777
- }
778
- if html_path is not None and html_path.exists():
779
- html_bytes = html_path.read_bytes()
780
- meta["html_sha256"] = _sha256_bytes(html_bytes)
781
- meta["html_size_bytes"] = html_path.stat().st_size
782
- return meta
783
-
784
- previous_page_meta_by_id: dict[str, dict[str, Any]] = {}
785
- previous_attachments_by_page: dict[str, list[dict[str, Any]]] = {}
786
- if options.resume and resolved_manifest_path.exists():
787
- try:
788
- loaded = json.loads(resolved_manifest_path.read_text(encoding="utf-8"))
789
- if isinstance(loaded, dict):
790
- root_meta = loaded.get("page")
791
- if isinstance(root_meta, dict):
792
- root_id = root_meta.get("page_id")
793
- if root_id:
794
- previous_page_meta_by_id[str(root_id)] = root_meta
795
- raw_children = loaded.get("child_pages")
796
- if isinstance(raw_children, list):
797
- for child in raw_children:
798
- if not isinstance(child, dict):
799
- continue
800
- child_id = child.get("page_id")
801
- if child_id:
802
- previous_page_meta_by_id[str(child_id)] = child
803
- raw_attachments = loaded.get("attachments")
804
- if isinstance(raw_attachments, list):
805
- for attachment in raw_attachments:
806
- if not isinstance(attachment, dict):
807
- continue
808
- page_id = attachment.get("page_id")
809
- if page_id is None:
810
- continue
811
- previous_attachments_by_page.setdefault(str(page_id), []).append(attachment)
812
- except Exception:
813
- previous_page_meta_by_id = {}
814
- previous_attachments_by_page = {}
815
-
816
- previous_corpus_chunks_by_page: dict[str, list[dict[str, Any]]] = {}
817
- if options.resume and options.emit_corpus:
818
- previous_corpus_path = output_dir / "corpus.jsonl"
819
- if previous_corpus_path.exists():
820
- try:
821
- with previous_corpus_path.open("r", encoding="utf-8") as previous_corpus_fp:
822
- for raw_line in previous_corpus_fp:
823
- line = raw_line.strip()
824
- if not line:
825
- continue
826
- try:
827
- payload = json.loads(line)
828
- except json.JSONDecodeError:
829
- continue
830
- if not isinstance(payload, dict):
831
- continue
832
- page_id = str(payload.get("page_id") or "").strip()
833
- if not page_id:
834
- continue
835
- previous_corpus_chunks_by_page.setdefault(page_id, []).append(payload)
836
- except Exception:
837
- previous_corpus_chunks_by_page = {}
838
-
839
- # State file for resume support (TSK-188)
840
- state_path = output_dir / "crawl_state.json"
841
- crawl_state: CrawlState | None = None
842
- skipped_unchanged: int = 0
843
- skipped_already_visited: int = 0
844
- nodes_processed: int = 0
845
- pages_fetched: int = 0
846
- pages_failed: int = 0
847
- termination_reason = "queue_exhausted"
848
- unchanged_page_ids: set[str] = set()
849
-
850
- # Track previously visited pages for skip-unchanged logic (separate from current run)
851
- previous_visited: dict[str, dict[str, Any]] = {}
852
-
853
- if options.resume:
854
- crawl_state = _load_crawl_state(state_path)
855
- if crawl_state is not None:
856
- # Validate state matches current crawl parameters
857
- if crawl_state.root_page_id != resolved_root_id:
858
- # Root changed, start fresh
859
- crawl_state = None
860
- elif crawl_state.body_format != body_format:
861
- # Format changed, start fresh
862
- crawl_state = None
863
- elif crawl_state.completed:
864
- # Previous crawl completed - keep visited_pages for skip-unchanged checks
865
- # but reset queue to re-crawl from root
866
- previous_visited = dict(crawl_state.visited_pages)
867
- previous_sync_timestamp = crawl_state.last_sync_timestamp
868
- previous_full_reconciliation_timestamp = crawl_state.last_full_reconciliation_timestamp
869
- crawl_state = CrawlState(
870
- root_page_id=resolved_root_id,
871
- body_format=body_format,
872
- visited_pages=previous_visited, # Keep for version checks
873
- pending_queue=[(resolved_root_id, None, 0)],
874
- started_at=_now_iso(),
875
- last_updated_at=_now_iso(),
876
- completed=False,
877
- last_sync_timestamp=previous_sync_timestamp,
878
- last_full_reconciliation_timestamp=previous_full_reconciliation_timestamp,
879
- )
880
- else:
881
- # Incomplete crawl - restore visited pages for skip logic
882
- previous_visited = dict(crawl_state.visited_pages)
883
-
884
- # Initialize state if needed
885
- if crawl_state is None:
886
- crawl_state = CrawlState(
887
- root_page_id=resolved_root_id,
888
- body_format=body_format,
889
- visited_pages={},
890
- pending_queue=[(resolved_root_id, None, 0)],
891
- started_at=_now_iso(),
892
- last_updated_at=_now_iso(),
893
- completed=False,
894
- )
895
-
896
- # For resume mode, track pages visited in current session to avoid re-processing
897
- visited_pages: set[str] = set()
898
- downloaded_attachments: set[str] = set()
899
-
900
- queue: list[tuple[str, str | None, int]] = list(crawl_state.pending_queue)
901
- discovered_page_ids: set[str] = {resolved_root_id}
902
- for queued_page_id, _, _ in queue:
903
- discovered_page_ids.add(queued_page_id)
904
-
905
- root_meta: dict[str, Any] | None = None
906
- child_pages: list[dict[str, Any]] = []
907
- attachments: list[dict[str, Any]] = []
908
- link_edges: list[dict[str, Any]] = []
909
- corpus_chunks: list[dict[str, Any]] = []
910
- tables: list[dict[str, Any]] = []
911
- mentions: list[dict[str, Any]] = []
912
- telemetry_getter = getattr(http, "get_runtime_telemetry", None)
913
- configure_rate_limit_budget = getattr(http, "configure_rate_limit_budget", None)
914
- if callable(configure_rate_limit_budget):
915
- with contextlib.suppress(Exception):
916
- configure_rate_limit_budget(int(options.rate_limit_budget))
917
-
918
- def _children_for(page_id: str, depth: int) -> list[tuple[str, str | None, int]]:
919
- if options.max_depth >= 0 and depth >= options.max_depth:
920
- return []
921
- try:
922
- child_payload = http.get_child_pages(page_id)
923
- except Exception:
924
- return []
925
- collected: list[tuple[str, str | None, int]] = []
926
- for child in child_payload:
927
- if not isinstance(child, dict):
928
- continue
929
- child_id = child.get("id")
930
- if child_id is None:
931
- continue
932
- collected.append((str(child_id), page_id, depth + 1))
933
- return collected
934
-
935
- body_expands: list[str]
936
- if body_format == "export_view":
937
- body_expands = ["body.export_view", "body.view", "body.storage"]
938
- elif body_format == "storage":
939
- body_expands = ["body.storage", "body.view"]
940
- else:
941
- body_expands = ["body.view", "body.storage"]
942
-
943
- def _fetch_page(node: tuple[str, str | None, int]) -> _FetchedPage:
944
- page_id, parent_id, depth = node
945
- children: list[tuple[str, str | None, int]] = []
946
- children_future: Future[list[tuple[str, str | None, int]]] | None = None
947
- children_executor: ThreadPoolExecutor | None = None
948
- if not use_structure_first and (options.max_depth < 0 or depth < options.max_depth):
949
- children_executor = ThreadPoolExecutor(max_workers=1)
950
- children_future = children_executor.submit(_children_for, page_id, depth)
951
-
952
- try:
953
- if options.resume and page_id in crawl_state.visited_pages:
954
- try:
955
- version_check = http.get_page(page_id, expand=["version"])
956
- except Exception as exc:
957
- if children_future is not None:
958
- children = children_future.result()
959
- return _FetchedPage(
960
- page_id=page_id,
961
- parent_id=parent_id,
962
- depth=depth,
963
- status="error",
964
- error=str(exc),
965
- children=children,
966
- )
967
- check_version = (version_check.get("version") or {}).get("number")
968
- if crawl_state.is_page_unchanged(page_id, check_version, None):
969
- if children_future is not None:
970
- children = children_future.result()
971
- return _FetchedPage(
972
- page_id=page_id,
973
- parent_id=parent_id,
974
- depth=depth,
975
- status="unchanged",
976
- version_payload=version_check,
977
- children=children,
978
- )
979
-
980
- try:
981
- page_payload = http.get_page(page_id, expand=[*body_expands, "version", "space", "ancestors"])
982
- except Exception as exc:
983
- if children_future is not None:
984
- children = children_future.result()
985
- return _FetchedPage(
986
- page_id=page_id,
987
- parent_id=parent_id,
988
- depth=depth,
989
- status="error",
990
- error=str(exc),
991
- children=children,
992
- )
993
-
994
- if children_future is not None:
995
- children = children_future.result()
996
-
997
- return _FetchedPage(
998
- page_id=page_id,
999
- parent_id=parent_id,
1000
- depth=depth,
1001
- status="fetched",
1002
- page_payload=page_payload,
1003
- children=children,
1004
- )
1005
- finally:
1006
- if children_executor is not None:
1007
- children_executor.shutdown(wait=True)
1008
-
1009
- def _extract_page_id_from_search_item(item: Any) -> str | None:
1010
- if not isinstance(item, dict):
1011
- return None
1012
- raw_id = item.get("id")
1013
- if raw_id is None and isinstance(item.get("content"), dict):
1014
- raw_id = item["content"].get("id")
1015
- if raw_id is None:
1016
- return None
1017
- page_id = str(raw_id).strip()
1018
- return page_id if page_id.isdigit() else None
1019
-
1020
- search_by_space_and_type = getattr(http, "search_by_space_and_type", None)
1021
-
1022
- def _search_space_page_ids(
1023
- *,
1024
- space_key: str,
1025
- last_modified_after: datetime | None = None,
1026
- overlap_minutes: int = 0,
1027
- ) -> tuple[set[str], bool]:
1028
- if not callable(search_by_space_and_type):
1029
- return set(), False
1030
-
1031
- page_ids: set[str] = set()
1032
- start = 0
1033
- limit = 100
1034
- successful = False
1035
- max_pages = 500
1036
-
1037
- for _ in range(max_pages):
1038
- response = search_by_space_and_type(
1039
- space_key=space_key,
1040
- content_type="page",
1041
- limit=limit,
1042
- start=start,
1043
- expand=["version"],
1044
- last_modified_after=last_modified_after,
1045
- overlap_minutes=overlap_minutes,
1046
- )
1047
- if not isinstance(response, dict):
1048
- break
1049
- successful = True
1050
- results = response.get("results")
1051
- if not isinstance(results, list) or not results:
1052
- break
1053
- for item in results:
1054
- page_id = _extract_page_id_from_search_item(item)
1055
- if page_id:
1056
- page_ids.add(page_id)
1057
- if len(results) < limit:
1058
- break
1059
- start += limit
1060
-
1061
- return page_ids, successful
1062
-
1063
- def _resolve_known_space_key() -> str | None:
1064
- root_meta = previous_page_meta_by_id.get(resolved_root_id)
1065
- if not isinstance(root_meta, dict):
1066
- return None
1067
- raw_space_key = root_meta.get("space_key")
1068
- if not isinstance(raw_space_key, str):
1069
- return None
1070
- space_key = raw_space_key.strip()
1071
- return space_key or None
1072
-
1073
- def _discover_structure_first_tree(
1074
- initial_queue: list[tuple[str, str | None, int]],
1075
- ) -> tuple[list[tuple[str, str | None, int]], list[tuple[str, str | None, int]], set[str]]:
1076
- ordered: list[tuple[str, str | None, int]] = []
1077
- pending: list[tuple[str, str | None, int]] = []
1078
- discovered: set[str] = set()
1079
- pending_ids: set[str] = set()
1080
- seen: set[str] = set()
1081
- current_level: list[tuple[str, str | None, int]] = list(initial_queue)
1082
- for page_id, _, _ in current_level:
1083
- discovered.add(page_id)
1084
-
1085
- while current_level:
1086
- level_nodes: list[tuple[str, str | None, int]] = []
1087
- for page_id, parent_id, depth in current_level:
1088
- if page_id in seen:
1089
- continue
1090
- if options.max_nodes is not None and len(ordered) >= options.max_nodes:
1091
- if page_id not in pending_ids:
1092
- pending.append((page_id, parent_id, depth))
1093
- pending_ids.add(page_id)
1094
- continue
1095
- seen.add(page_id)
1096
- ordered.append((page_id, parent_id, depth))
1097
- level_nodes.append((page_id, parent_id, depth))
1098
-
1099
- if options.max_nodes is not None and len(ordered) >= options.max_nodes:
1100
- for page_id, parent_id, depth in current_level:
1101
- if page_id in seen or page_id in pending_ids:
1102
- continue
1103
- pending.append((page_id, parent_id, depth))
1104
- pending_ids.add(page_id)
1105
- break
1106
-
1107
- parents_for_children: list[tuple[str, int]] = []
1108
- for page_id, _, depth in level_nodes:
1109
- if options.max_depth >= 0 and depth >= options.max_depth:
1110
- continue
1111
- parents_for_children.append((page_id, depth))
1112
-
1113
- if not parents_for_children:
1114
- current_level = []
1115
- continue
1116
-
1117
- child_batches: list[list[tuple[str, str | None, int]]]
1118
- if len(parents_for_children) == 1:
1119
- parent_id, parent_depth = parents_for_children[0]
1120
- child_batches = [_children_for(parent_id, parent_depth)]
1121
- else:
1122
- max_workers = min(page_concurrency, len(parents_for_children))
1123
- with ThreadPoolExecutor(max_workers=max_workers) as executor:
1124
- futures: list[Future[list[tuple[str, str | None, int]]]] = [
1125
- executor.submit(_children_for, parent_id, parent_depth)
1126
- for parent_id, parent_depth in parents_for_children
1127
- ]
1128
- child_batches = [future.result() for future in futures]
1129
-
1130
- next_level: list[tuple[str, str | None, int]] = []
1131
- next_level_ids: set[str] = set()
1132
- for children in child_batches:
1133
- for child_id, child_parent, child_depth in children:
1134
- if child_id in seen or child_id in next_level_ids:
1135
- continue
1136
- discovered.add(child_id)
1137
- next_level_ids.add(child_id)
1138
- next_level.append((child_id, child_parent, child_depth))
1139
- current_level = next_level
1140
-
1141
- return ordered, pending, discovered
1142
-
1143
- incremental_candidate_ids: set[str] = set()
1144
- incremental_high_water_mark_ran = False
1145
- incremental_high_water_mark_skipped = False
1146
- incremental_high_water_mark_skip_reason: str | None = None
1147
- incremental_known_page_count = 0
1148
- full_reconciliation_deleted_ids: list[str] = []
1149
- full_reconciliation_ran = False
1150
- full_reconciliation_skipped = False
1151
- full_reconciliation_skip_reason: str | None = None
1152
- full_reconciliation_known_page_count = 0
1153
- space_key_for_incremental = _resolve_known_space_key()
1154
- if options.resume and options.incremental_cql and callable(search_by_space_and_type):
1155
- known_page_ids = set(crawl_state.visited_pages.keys())
1156
- incremental_known_page_count = len(known_page_ids)
1157
- last_sync_dt = _parse_iso_timestamp(crawl_state.last_sync_timestamp)
1158
- if space_key_for_incremental and last_sync_dt is not None:
1159
- if incremental_known_page_count <= 1:
1160
- incremental_high_water_mark_skipped = True
1161
- incremental_high_water_mark_skip_reason = "known_pages_lte_1"
1162
- else:
1163
- incremental_high_water_mark_ran = True
1164
- try:
1165
- incremental_ids, incremental_ok = _search_space_page_ids(
1166
- space_key=space_key_for_incremental,
1167
- last_modified_after=last_sync_dt,
1168
- overlap_minutes=max(0, int(options.incremental_overlap_minutes)),
1169
- )
1170
- except Exception:
1171
- incremental_ids, incremental_ok = set(), False
1172
- if incremental_ok:
1173
- incremental_candidate_ids = {page_id for page_id in incremental_ids if page_id in known_page_ids}
1174
- if incremental_candidate_ids:
1175
- queued_ids = {queued_page_id for queued_page_id, _, _ in queue}
1176
- for page_id in sorted(incremental_candidate_ids):
1177
- if page_id in queued_ids:
1178
- continue
1179
- previous_meta = previous_page_meta_by_id.get(page_id) or {}
1180
- parent_id = previous_meta.get("parent_id")
1181
- if parent_id is not None:
1182
- parent_id = str(parent_id)
1183
- depth = previous_meta.get("depth")
1184
- if not isinstance(depth, int) or depth < 0:
1185
- depth = 0
1186
- queue.append((page_id, parent_id, depth))
1187
- queued_ids.add(page_id)
1188
- discovered_page_ids.add(page_id)
1189
-
1190
- full_reconciliation_due = False
1191
- last_full_reconciliation_dt = _parse_iso_timestamp(crawl_state.last_full_reconciliation_timestamp)
1192
- if last_full_reconciliation_dt is None:
1193
- full_reconciliation_due = True
1194
- else:
1195
- full_reconciliation_due = datetime.now(UTC) - last_full_reconciliation_dt >= timedelta(
1196
- days=max(1, int(options.full_reconciliation_interval_days))
1197
- )
1198
-
1199
- if space_key_for_incremental and full_reconciliation_due:
1200
- known_page_ids = set(crawl_state.visited_pages.keys())
1201
- full_reconciliation_known_page_count = len(known_page_ids)
1202
- reconciliation_marker_timestamp = _now_iso()
1203
- if full_reconciliation_known_page_count <= 1:
1204
- full_reconciliation_skipped = True
1205
- full_reconciliation_skip_reason = "known_pages_lte_1"
1206
- crawl_state.last_full_reconciliation_timestamp = reconciliation_marker_timestamp
1207
- else:
1208
- try:
1209
- remote_page_ids, reconciliation_ok = _search_space_page_ids(space_key=space_key_for_incremental)
1210
- except Exception:
1211
- remote_page_ids, reconciliation_ok = set(), False
1212
- if reconciliation_ok:
1213
- full_reconciliation_ran = True
1214
- full_reconciliation_deleted_ids = sorted(known_page_ids - remote_page_ids)
1215
- if full_reconciliation_deleted_ids:
1216
- for page_id in full_reconciliation_deleted_ids:
1217
- crawl_state.visited_pages.pop(page_id, None)
1218
- previous_visited.pop(page_id, None)
1219
- previous_page_meta_by_id.pop(page_id, None)
1220
- previous_attachments_by_page.pop(page_id, None)
1221
- discovered_page_ids.discard(page_id)
1222
- _emit_runtime_event(
1223
- options,
1224
- "pages_deleted",
1225
- root_page_id=resolved_root_id,
1226
- deleted_count=len(full_reconciliation_deleted_ids),
1227
- page_ids=full_reconciliation_deleted_ids,
1228
- )
1229
- crawl_state.last_full_reconciliation_timestamp = reconciliation_marker_timestamp
1230
-
1231
- structure_first_pending_queue: list[tuple[str, str | None, int]] = []
1232
- structure_pre_discovered_nodes = 0
1233
- if use_structure_first:
1234
- queue, structure_first_pending_queue, structure_discovered_ids = _discover_structure_first_tree(queue)
1235
- structure_pre_discovered_nodes = len(queue) + len(structure_first_pending_queue)
1236
- discovered_page_ids.update(structure_discovered_ids)
1237
-
1238
- crawl_started_at = time.perf_counter()
1239
- max_inflight_workers = 0
1240
- effective_page_concurrency = page_concurrency
1241
- effective_concurrency_signal: float | None = None
1242
- throttle_pressure_score: float | None = None
1243
-
1244
- while queue:
1245
- if options.max_nodes is not None and nodes_processed >= options.max_nodes:
1246
- termination_reason = "max_nodes_reached"
1247
- break
1248
-
1249
- if options.max_nodes is None:
1250
- remaining = len(queue)
1251
- else:
1252
- remaining = min(len(queue), options.max_nodes - nodes_processed)
1253
- if remaining <= 0:
1254
- termination_reason = "max_nodes_reached"
1255
- break
1256
- runtime_page_concurrency = page_concurrency
1257
- if callable(telemetry_getter):
1258
- try:
1259
- telemetry_snapshot = telemetry_getter()
1260
- except Exception:
1261
- telemetry_snapshot = None
1262
- if isinstance(telemetry_snapshot, dict):
1263
- throttle = telemetry_snapshot.get("adaptive_throttle")
1264
- if isinstance(throttle, dict):
1265
- signal = throttle.get("effective_concurrency_signal")
1266
- if isinstance(signal, (float, int)):
1267
- effective_concurrency_signal = float(signal)
1268
- scaled = round(page_concurrency * float(signal))
1269
- runtime_page_concurrency = max(1, min(page_concurrency, scaled))
1270
- pressure_score = throttle.get("pressure_score")
1271
- if isinstance(pressure_score, (float, int)):
1272
- throttle_pressure_score = float(pressure_score)
1273
- effective_page_concurrency = runtime_page_concurrency
1274
- batch_size = min(runtime_page_concurrency, remaining)
1275
- max_inflight_workers = max(max_inflight_workers, batch_size)
1276
-
1277
- batch: list[tuple[str, str | None, int]] = []
1278
- while queue and len(batch) < batch_size:
1279
- page_id, parent_id, depth = queue.pop(0)
1280
- if page_id in visited_pages:
1281
- skipped_already_visited += 1
1282
- continue
1283
- visited_pages.add(page_id)
1284
- nodes_processed += 1
1285
- batch.append((page_id, parent_id, depth))
1286
-
1287
- crawl_state.pending_queue = list(queue)
1288
- if not batch:
1289
- continue
1290
-
1291
- fetched: list[_FetchedPage] = []
1292
- if batch_size == 1:
1293
- fetched = [_fetch_page(node) for node in batch]
1294
- else:
1295
- with ThreadPoolExecutor(max_workers=batch_size) as executor:
1296
- futures: dict[Future[_FetchedPage], int] = {
1297
- executor.submit(_fetch_page, node): idx for idx, node in enumerate(batch)
1298
- }
1299
- fetched_by_index: dict[int, _FetchedPage] = {}
1300
- for future, idx in futures.items():
1301
- fetched_by_index[idx] = future.result()
1302
- fetched = [fetched_by_index[idx] for idx in range(len(batch))]
1303
-
1304
- for result in fetched:
1305
- page_id = result.page_id
1306
- parent_id = result.parent_id
1307
- depth = result.depth
1308
-
1309
- if result.status == "unchanged":
1310
- skipped_unchanged += 1
1311
- unchanged_page_ids.add(page_id)
1312
- previous_meta = previous_page_meta_by_id.get(page_id)
1313
- if previous_meta is None:
1314
- previous_meta = _meta_from_existing_html(
1315
- page_id=page_id,
1316
- parent_id=parent_id,
1317
- depth=depth,
1318
- page_payload=result.version_payload if isinstance(result.version_payload, dict) else None,
1319
- )
1320
- if previous_meta is not None:
1321
- if depth == 0:
1322
- root_meta = previous_meta
1323
- else:
1324
- child_pages.append(previous_meta)
1325
- if options.include_attachments:
1326
- for previous_attachment in previous_attachments_by_page.get(page_id, []):
1327
- attachment_id = previous_attachment.get("attachment_id")
1328
- if attachment_id is not None:
1329
- downloaded_attachments.add(str(attachment_id))
1330
- attachments.append(previous_attachment)
1331
- for child_id, child_parent, child_depth in result.children:
1332
- if child_id in visited_pages:
1333
- continue
1334
- discovered_page_ids.add(child_id)
1335
- queue.append((child_id, child_parent, child_depth))
1336
- continue
1337
-
1338
- if result.status == "error":
1339
- pages_failed += 1
1340
- meta = {
1341
- "page_id": page_id,
1342
- "title": None,
1343
- "page_url": None,
1344
- "parent_id": parent_id,
1345
- "depth": depth,
1346
- "status": "error",
1347
- "error": result.error,
1348
- }
1349
- if depth == 0:
1350
- root_meta = meta
1351
- else:
1352
- child_pages.append(meta)
1353
- continue
1354
-
1355
- pages_fetched += 1
1356
- page = result.page_payload if isinstance(result.page_payload, dict) else {}
1357
- title = str(page.get("title") or "untitled")
1358
- safe_title = _safe_filename(title)
1359
- body_obj = page.get("body") or {}
1360
- view_html = (body_obj.get("view") or {}).get("value", "")
1361
- export_html = (body_obj.get("export_view") or {}).get("value", "")
1362
- storage_html = (body_obj.get("storage") or {}).get("value", "")
1363
- candidates = {
1364
- "view": view_html if isinstance(view_html, str) else "",
1365
- "export_view": export_html if isinstance(export_html, str) else "",
1366
- "storage": storage_html if isinstance(storage_html, str) else "",
1367
- }
1368
- chosen_html = candidates.get(body_format, "") or ""
1369
- chosen_format = body_format
1370
- if not chosen_html.strip():
1371
- fallback_order = (
1372
- ["view", "storage", "export_view"]
1373
- if body_format == "view"
1374
- else ["storage", "view", "export_view"]
1375
- if body_format == "storage"
1376
- else ["export_view", "view", "storage"]
1377
- )
1378
- for fmt in fallback_order:
1379
- candidate = candidates.get(fmt, "") or ""
1380
- if isinstance(candidate, str) and candidate.strip():
1381
- chosen_html = candidate
1382
- chosen_format = fmt
1383
- break
1384
-
1385
- html = chosen_html if isinstance(chosen_html, str) else ""
1386
- source_format = f"html-{chosen_format.replace('_', '-')}"
1387
-
1388
- links = page.get("_links", {}) if isinstance(page.get("_links"), dict) else {}
1389
- base_url = str(links.get("base") or "")
1390
- web_ui = str(links.get("webui") or "")
1391
- page_url = f"{base_url}{web_ui}" if base_url and web_ui else None
1392
-
1393
- version = page.get("version") or {}
1394
- page_version = version.get("number") if isinstance(version, dict) else None
1395
- page_updated = version.get("when") if isinstance(version, dict) else None
1396
- space_key = (page.get("space") or {}).get("key") if isinstance(page.get("space"), dict) else None
1397
-
1398
- ancestors = page.get("ancestors") or []
1399
- ancestor_ids: list[str] = []
1400
- ancestor_titles: list[str] = []
1401
- if isinstance(ancestors, list):
1402
- for entry in ancestors:
1403
- if not isinstance(entry, dict):
1404
- continue
1405
- if entry.get("id") is not None:
1406
- ancestor_ids.append(str(entry["id"]))
1407
- if entry.get("title"):
1408
- ancestor_titles.append(str(entry["title"]))
1409
-
1410
- html_path = output_dir / f"{page_id}_{safe_title}.html"
1411
- html_path.write_text(html, encoding="utf-8")
1412
- html_bytes = html.encode("utf-8")
1413
- html_sha256 = _sha256_bytes(html_bytes)
1414
- crawl_state.record_page(page_id, page_version, html_sha256)
1415
-
1416
- meta = {
1417
- "page_id": page_id,
1418
- "title": title,
1419
- "page_url": page_url,
1420
- "parent_id": parent_id,
1421
- "depth": depth,
1422
- "status": "downloaded",
1423
- "html_path": str(html_path),
1424
- "html_sha256": html_sha256,
1425
- "html_size_bytes": html_path.stat().st_size,
1426
- "source_format": source_format,
1427
- "space_key": space_key,
1428
- "page_version": page_version,
1429
- "page_updated": page_updated,
1430
- "ancestor_ids": ancestor_ids,
1431
- "ancestor_titles": ancestor_titles,
1432
- "error": None,
1433
- }
1434
- if depth == 0:
1435
- root_meta = meta
1436
- else:
1437
- child_pages.append(meta)
1438
-
1439
- if options.emit_link_graph:
1440
- for link in _extract_links(html, base_url=base_url):
1441
- target_url = link.get("url")
1442
- target_type = _classify_target_type(str(target_url)) if target_url else None
1443
- target_page_id = _extract_target_page_id(str(target_url)) if target_url else None
1444
- edge: dict[str, Any] = {
1445
- "source_page_id": page_id,
1446
- "source_page_url": page_url,
1447
- "target_url": target_url,
1448
- "anchor_text": link.get("text"),
1449
- }
1450
- if target_type:
1451
- edge["target_type"] = target_type
1452
- if target_type == "confluence_page" and target_page_id:
1453
- edge["target_page_id"] = target_page_id
1454
- link_edges.append(edge)
1455
-
1456
- if options.emit_corpus:
1457
- for chunk in _chunk_html_by_headings(html, max_chars=chunk_max_chars):
1458
- heading_path = chunk.get("heading_path") or []
1459
- ordinal = chunk.get("ordinal") if isinstance(chunk.get("ordinal"), int) else 0
1460
- base_key = f"{page_id}|{'/'.join(heading_path)}"
1461
- key = base_key if ordinal == 0 else f"{base_key}|{ordinal}"
1462
- corpus_chunks.append(
1463
- {
1464
- "chunk_id": _sha256_text(key)[:16],
1465
- "page_id": page_id,
1466
- "page_url": page_url,
1467
- "title": title,
1468
- "depth": depth,
1469
- "parent_id": parent_id,
1470
- "ancestors": ancestor_ids,
1471
- "ancestor_ids": ancestor_ids,
1472
- "space_key": space_key,
1473
- "page_version": page_version,
1474
- "page_updated": page_updated,
1475
- "ancestor_titles": ancestor_titles,
1476
- "heading_path": heading_path,
1477
- "chunk_ordinal": ordinal,
1478
- "text": chunk.get("text"),
1479
- "source_type": "confluence",
1480
- "doc_class": "canonical_doc",
1481
- "generated_flag": False,
1482
- "historical_flag": False,
1483
- "discovery": "confluence_crawl_page",
1484
- }
1485
- )
1486
-
1487
- if options.emit_tables:
1488
- for table in _extract_tables(html):
1489
- key = f"{page_id}|table|{table.get('table_index')}"
1490
- tables.append(
1491
- {
1492
- "table_id": _sha256_text(key)[:16],
1493
- "page_id": page_id,
1494
- "page_url": page_url,
1495
- "title": title,
1496
- "depth": depth,
1497
- "parent_id": parent_id,
1498
- "space_key": space_key,
1499
- "page_version": page_version,
1500
- "page_updated": page_updated,
1501
- "ancestor_titles": ancestor_titles,
1502
- "table_index": table.get("table_index"),
1503
- "headers": table.get("headers"),
1504
- "rows": table.get("rows"),
1505
- "row_count": table.get("row_count"),
1506
- "col_count": table.get("col_count"),
1507
- }
1508
- )
1509
-
1510
- if options.emit_mentions:
1511
- for index, mention in enumerate(_extract_mentions(html, base_url=base_url)):
1512
- key = f"{page_id}|mention|{mention.get('type')}|{mention.get('value')}|{mention.get('url') or ''}"
1513
- mentions.append(
1514
- {
1515
- "mention_id": _sha256_text(key)[:16],
1516
- "page_id": page_id,
1517
- "page_url": page_url,
1518
- "title": title,
1519
- "depth": depth,
1520
- "parent_id": parent_id,
1521
- "space_key": space_key,
1522
- "page_version": page_version,
1523
- "page_updated": page_updated,
1524
- "ancestor_titles": ancestor_titles,
1525
- "mention_index": index,
1526
- **mention,
1527
- }
1528
- )
1529
-
1530
- if options.include_attachments:
1531
- try:
1532
- attachment_results = http.get_attachments(page_id)
1533
- except Exception as exc:
1534
- attachments.append(
1535
- {
1536
- "attachment_id": None,
1537
- "page_id": page_id,
1538
- "title": None,
1539
- "status": "error",
1540
- "error": str(exc),
1541
- }
1542
- )
1543
- attachment_results = []
1544
-
1545
- for att in attachment_results:
1546
- if not isinstance(att, dict):
1547
- continue
1548
- attachment_id = att.get("id") or att.get("attachment_id")
1549
- if attachment_id is None:
1550
- continue
1551
- attachment_id = str(attachment_id)
1552
- if attachment_id in downloaded_attachments:
1553
- continue
1554
- downloaded_attachments.add(attachment_id)
1555
-
1556
- att_title = str(att.get("title") or att.get("name") or f"attachment_{attachment_id}")
1557
- out_path = attachments_dir / _safe_attachment_filename(
1558
- attachment_id, att_title, fallback_suffix=_guess_attachment_suffix(att)
1559
- )
1560
-
1561
- try:
1562
- content = http.get_attachment_content(attachment_id)
1563
- out_path.write_bytes(content)
1564
- file_sha256 = _sha256_bytes(content)
1565
- status = "downloaded"
1566
- error = None
1567
- except Exception as exc:
1568
- file_sha256 = None
1569
- status = "error"
1570
- error = str(exc)
1571
-
1572
- version_obj = att.get("version") or {}
1573
- attachment_version = version_obj.get("number") if isinstance(version_obj, dict) else None
1574
- extensions = att.get("extensions") or {}
1575
- attachment_size = None
1576
- if isinstance(extensions, dict):
1577
- attachment_size = extensions.get("fileSize") or extensions.get("size")
1578
-
1579
- attachments.append(
1580
- {
1581
- "attachment_id": attachment_id,
1582
- "page_id": page_id,
1583
- "title": att_title,
1584
- "status": status,
1585
- "file_path": str(out_path) if status == "downloaded" else None,
1586
- "file_sha256": file_sha256,
1587
- "file_size_bytes": out_path.stat().st_size
1588
- if status == "downloaded" and out_path.exists()
1589
- else None,
1590
- "attachment_version": attachment_version,
1591
- "attachment_size": attachment_size,
1592
- "error": error,
1593
- }
1594
- )
1595
-
1596
- for child_id, child_parent, child_depth in result.children:
1597
- if child_id in visited_pages:
1598
- continue
1599
- discovered_page_ids.add(child_id)
1600
- queue.append((child_id, child_parent, child_depth))
1601
-
1602
- _emit_runtime_event(
1603
- options,
1604
- "crawl_progress",
1605
- root_page_id=resolved_root_id,
1606
- pages_discovered=len(discovered_page_ids),
1607
- pages_fetched=pages_fetched,
1608
- pages_failed=pages_failed,
1609
- pages_skipped_unchanged=skipped_unchanged,
1610
- pages_skipped_total=skipped_unchanged + skipped_already_visited,
1611
- pending_queue_size=len(queue),
1612
- effective_page_concurrency=effective_page_concurrency,
1613
- effective_concurrency_signal=effective_concurrency_signal,
1614
- throttle_pressure_score=throttle_pressure_score,
1615
- )
1616
-
1617
- if options.emit_corpus and previous_corpus_chunks_by_page:
1618
- should_merge_unchanged_corpus = pages_fetched > 0 or bool(full_reconciliation_deleted_ids)
1619
- if should_merge_unchanged_corpus:
1620
- emitted_chunk_ids = {
1621
- str(chunk.get("chunk_id") or "").strip()
1622
- for chunk in corpus_chunks
1623
- if isinstance(chunk, dict) and str(chunk.get("chunk_id") or "").strip()
1624
- }
1625
- for page_id in sorted(unchanged_page_ids):
1626
- for previous_chunk in previous_corpus_chunks_by_page.get(page_id, []):
1627
- if not isinstance(previous_chunk, dict):
1628
- continue
1629
- chunk_id = str(previous_chunk.get("chunk_id") or "").strip()
1630
- if chunk_id and chunk_id in emitted_chunk_ids:
1631
- continue
1632
- corpus_chunks.append(dict(previous_chunk))
1633
- if chunk_id:
1634
- emitted_chunk_ids.add(chunk_id)
1635
-
1636
- if structure_first_pending_queue:
1637
- queued_page_ids = {queued_page_id for queued_page_id, _, _ in queue}
1638
- for pending_page_id, pending_parent_id, pending_depth in structure_first_pending_queue:
1639
- if pending_page_id in visited_pages or pending_page_id in queued_page_ids:
1640
- continue
1641
- queue.append((pending_page_id, pending_parent_id, pending_depth))
1642
- queued_page_ids.add(pending_page_id)
1643
- if queue:
1644
- termination_reason = "max_nodes_reached"
1645
-
1646
- # Update and save crawl state (TSK-188)
1647
- http_telemetry: dict[str, Any] | None = None
1648
- if callable(telemetry_getter):
1649
- try:
1650
- telemetry_payload = telemetry_getter()
1651
- if isinstance(telemetry_payload, dict):
1652
- http_telemetry = telemetry_payload
1653
- except Exception:
1654
- http_telemetry = None
1655
- if http_telemetry is None:
1656
- http_telemetry = {}
1657
-
1658
- elapsed_seconds = max(0.001, time.perf_counter() - crawl_started_at)
1659
- throughput_pages_per_second = round(nodes_processed / elapsed_seconds, 3)
1660
- latency_metrics = http_telemetry.get("latency_ms") if isinstance(http_telemetry, dict) else None
1661
- p95_page_latency_ms = None
1662
- if isinstance(latency_metrics, dict):
1663
- operation_latency = latency_metrics.get("operation")
1664
- if isinstance(operation_latency, dict):
1665
- p95_value = operation_latency.get("p95")
1666
- if isinstance(p95_value, (float, int)):
1667
- p95_page_latency_ms = round(float(p95_value), 3)
1668
-
1669
- retry_events_total = None
1670
- if isinstance(http_telemetry, dict):
1671
- retry_events_list = http_telemetry.get("recent_retry_events")
1672
- if isinstance(retry_events_list, list):
1673
- retry_events_total = len(retry_events_list)
1674
-
1675
- if isinstance(http_telemetry, dict):
1676
- http_telemetry["inflight_workers"] = max_inflight_workers
1677
- http_telemetry["queue_depth"] = len(queue)
1678
- http_telemetry["pages_per_second"] = throughput_pages_per_second
1679
- http_telemetry["retry_events"] = retry_events_total
1680
- http_telemetry["p95_page_latency_ms"] = p95_page_latency_ms
1681
- adaptive_throttle = http_telemetry.get("adaptive_throttle")
1682
- if isinstance(adaptive_throttle, dict):
1683
- signal_value = adaptive_throttle.get("effective_concurrency_signal")
1684
- if isinstance(signal_value, (float, int)):
1685
- effective_concurrency_signal = float(signal_value)
1686
- pressure_value = adaptive_throttle.get("pressure_score")
1687
- if isinstance(pressure_value, (float, int)):
1688
- throttle_pressure_score = float(pressure_value)
1689
-
1690
- crawl_state.last_sync_timestamp = _now_iso()
1691
- pages_skipped = skipped_unchanged + skipped_already_visited
1692
- progress_event = {
1693
- "pages_discovered": len(discovered_page_ids),
1694
- "pages_fetched": pages_fetched,
1695
- "pages_failed": pages_failed,
1696
- "pages_skipped": pages_skipped,
1697
- "pages_skipped_unchanged": skipped_unchanged,
1698
- "throttle": {
1699
- "configured_page_concurrency": page_concurrency,
1700
- "effective_page_concurrency": effective_page_concurrency,
1701
- "effective_concurrency_signal": effective_concurrency_signal,
1702
- "pressure_score": throttle_pressure_score,
1703
- },
1704
- }
1705
-
1706
- crawl_state.pending_queue = list(queue)
1707
- crawl_state.completed = len(queue) == 0
1708
- if crawl_state.completed:
1709
- termination_reason = "queue_exhausted"
1710
- crawl_state.run_diagnostics = {
1711
- "termination_reason": termination_reason,
1712
- "nodes_processed": nodes_processed,
1713
- "skipped_unchanged": skipped_unchanged,
1714
- "skipped_already_visited": skipped_already_visited,
1715
- "pages_fetched": pages_fetched,
1716
- "pages_failed": pages_failed,
1717
- "pages_discovered": len(discovered_page_ids),
1718
- "pages_skipped": pages_skipped,
1719
- "pending_queue_size": len(queue),
1720
- "page_concurrency": page_concurrency,
1721
- "staged_mode": staged_mode,
1722
- "incremental_cql": bool(options.incremental_cql),
1723
- "rate_limit_budget": int(options.rate_limit_budget),
1724
- "full_reconciliation_interval_days": max(1, int(options.full_reconciliation_interval_days)),
1725
- "last_sync_timestamp": crawl_state.last_sync_timestamp,
1726
- "last_full_reconciliation_timestamp": crawl_state.last_full_reconciliation_timestamp,
1727
- "incremental_overlap_minutes": max(0, int(options.incremental_overlap_minutes)),
1728
- "incremental_known_page_count": incremental_known_page_count,
1729
- "incremental_candidate_count": len(incremental_candidate_ids),
1730
- "incremental_high_water_mark_ran": incremental_high_water_mark_ran,
1731
- "incremental_high_water_mark_skipped": incremental_high_water_mark_skipped,
1732
- "incremental_high_water_mark_skip_reason": incremental_high_water_mark_skip_reason,
1733
- "full_reconciliation_ran": full_reconciliation_ran,
1734
- "full_reconciliation_deleted_ids": full_reconciliation_deleted_ids,
1735
- "full_reconciliation_skipped": full_reconciliation_skipped,
1736
- "full_reconciliation_skip_reason": full_reconciliation_skip_reason,
1737
- "full_reconciliation_known_page_count": full_reconciliation_known_page_count,
1738
- "structure_pre_discovered_nodes": structure_pre_discovered_nodes if use_structure_first else None,
1739
- "progress_event": progress_event,
1740
- "telemetry": http_telemetry,
1741
- "http_telemetry": http_telemetry,
1742
- }
1743
- _save_crawl_state(crawl_state, state_path)
1744
-
1745
- payload: dict[str, Any] = {
1746
- "root_ref": root_ref,
1747
- "root_page_id": resolved_root_id,
1748
- "out_dir": str(output_dir),
1749
- "generated_at": _now_iso(),
1750
- "body_format": body_format,
1751
- "chunk_max_chars": chunk_max_chars,
1752
- "crawl_mode": {
1753
- "page_concurrency": page_concurrency,
1754
- "staged_mode": staged_mode,
1755
- "incremental_cql": bool(options.incremental_cql),
1756
- "rate_limit_budget": int(options.rate_limit_budget),
1757
- "incremental_overlap_minutes": max(0, int(options.incremental_overlap_minutes)),
1758
- "full_reconciliation_interval_days": max(1, int(options.full_reconciliation_interval_days)),
1759
- },
1760
- "page": root_meta,
1761
- "child_pages": child_pages,
1762
- "attachments": attachments,
1763
- "corpus_path": None,
1764
- "link_graph_path": None,
1765
- "tables_path": None,
1766
- "mentions_path": None,
1767
- "progress_event": progress_event,
1768
- "resume_state": {
1769
- "skipped_unchanged": skipped_unchanged,
1770
- "skipped_already_visited": skipped_already_visited,
1771
- "pages_fetched": pages_fetched,
1772
- "pages_failed": pages_failed,
1773
- "pages_discovered": len(discovered_page_ids),
1774
- "pages_skipped": pages_skipped,
1775
- "pages_skipped_unchanged": skipped_unchanged,
1776
- "nodes_processed": nodes_processed,
1777
- "completed": crawl_state.completed,
1778
- "termination_reason": termination_reason,
1779
- "pending_queue_size": len(queue),
1780
- "state_path": str(state_path),
1781
- "page_concurrency": page_concurrency,
1782
- "staged_mode": staged_mode,
1783
- "last_sync_timestamp": crawl_state.last_sync_timestamp,
1784
- "last_full_reconciliation_timestamp": crawl_state.last_full_reconciliation_timestamp,
1785
- },
1786
- "telemetry": http_telemetry,
1787
- "http_telemetry": http_telemetry,
1788
- }
1789
-
1790
- if options.emit_corpus:
1791
- corpus_path = output_dir / "corpus.jsonl"
1792
- if corpus_chunks or not (options.resume and corpus_path.exists()):
1793
- with corpus_path.open("w", encoding="utf-8") as fp:
1794
- for item in corpus_chunks:
1795
- fp.write(json.dumps(item, ensure_ascii=False) + "\n")
1796
- payload["corpus_path"] = str(corpus_path)
1797
-
1798
- if options.emit_link_graph:
1799
- graph_path = output_dir / "link-graph.json"
1800
- if link_edges or not (options.resume and graph_path.exists()):
1801
- graph_payload = {
1802
- "generated_at": payload["generated_at"],
1803
- "root_page_id": resolved_root_id,
1804
- "edges": [edge for edge in link_edges if edge.get("target_url")],
1805
- }
1806
- graph_path.write_text(json.dumps(graph_payload, ensure_ascii=False, indent=2), encoding="utf-8")
1807
- payload["link_graph_path"] = str(graph_path)
1808
-
1809
- if options.emit_tables:
1810
- tables_path = output_dir / "tables.jsonl"
1811
- if tables or not (options.resume and tables_path.exists()):
1812
- with tables_path.open("w", encoding="utf-8") as fp:
1813
- for item in tables:
1814
- fp.write(json.dumps(item, ensure_ascii=False) + "\n")
1815
- payload["tables_path"] = str(tables_path)
1816
-
1817
- if options.emit_mentions:
1818
- mentions_path = output_dir / "mentions.jsonl"
1819
- if mentions or not (options.resume and mentions_path.exists()):
1820
- with mentions_path.open("w", encoding="utf-8") as fp:
1821
- for item in mentions:
1822
- fp.write(json.dumps(item, ensure_ascii=False) + "\n")
1823
- payload["mentions_path"] = str(mentions_path)
1824
-
1825
- resolved_manifest_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
1826
- payload["manifest_path"] = str(resolved_manifest_path)
1827
-
1828
- # Create bundle zip if requested (TSK-189)
1829
- if options.bundle:
1830
- bundle_path = _create_bundle_zip(output_dir, resolved_root_id, resolved_manifest_path)
1831
- payload["bundle_path"] = str(bundle_path)
1832
-
1833
- return payload