datex-studio-cli 0.5.4__tar.gz → 0.5.5__tar.gz

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 (240) hide show
  1. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/PKG-INFO +1 -1
  2. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/pyproject.toml +1 -1
  3. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/__init__.py +1 -1
  4. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/cli.py +92 -2
  5. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/document.py +19 -8
  6. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/odata.py +30 -17
  7. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/release_notes.py +32 -23
  8. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/source.py +147 -237
  9. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/__init__.py +8 -0
  10. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/app_config.py +89 -1
  11. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/flow_generator.py +2 -2
  12. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/flow_shape.py +24 -16
  13. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/validator.py +5 -4
  14. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/errors.py +4 -0
  15. datex_studio_cli-0.5.5/src/dxs/utils/http_errors.py +109 -0
  16. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/404/index.html +1 -1
  17. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/404.html +1 -1
  18. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/design/capture/index.html +1 -1
  19. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/design/capture/index.txt +1 -1
  20. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/design/index.html +1 -1
  21. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/design/index.txt +1 -1
  22. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/index.html +1 -1
  23. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/index.txt +1 -1
  24. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.dockerignore +0 -0
  25. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.github/actionlint.yaml +0 -0
  26. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.github/workflows/build-image.yml +0 -0
  27. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.github/workflows/ci.yml +0 -0
  28. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.github/workflows/promote-prod.yml +0 -0
  29. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.github/workflows/release.yml +0 -0
  30. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/.gitignore +0 -0
  31. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/CONTEXT.md +0 -0
  32. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/README.md +0 -0
  33. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/.env.example +0 -0
  34. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/Dockerfile +0 -0
  35. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/README.md +0 -0
  36. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/apply-local-cache.js +0 -0
  37. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/collector-config.yaml +0 -0
  38. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/docker-compose.yml +0 -0
  39. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/local-test-settings.json +0 -0
  40. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/otel/remote-settings.json +0 -0
  41. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/report-creator.skill +0 -0
  42. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/scripts/analyze_corpus.py +0 -0
  43. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/scripts/check_wheel_completeness.py +0 -0
  44. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/scripts/datadog_errors.py +0 -0
  45. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/scripts/generate_rdlx_schema.py +0 -0
  46. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/scripts/wavelength_query.py +0 -0
  47. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/__main__.py +0 -0
  48. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/__init__.py +0 -0
  49. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/api.py +0 -0
  50. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/auth.py +0 -0
  51. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/branch.py +0 -0
  52. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/branch_commit_guard.py +0 -0
  53. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/cascade.py +0 -0
  54. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/config.py +0 -0
  55. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/configuration.py +0 -0
  56. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/crm.py +0 -0
  57. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/crm_delivery.py +0 -0
  58. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/crm_time.py +0 -0
  59. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/datasource.py +0 -0
  60. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/devops.py +0 -0
  61. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/endpoint.py +0 -0
  62. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/env.py +0 -0
  63. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/explore.py +0 -0
  64. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/function.py +0 -0
  65. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/init.py +0 -0
  66. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/marketplace.py +0 -0
  67. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/__init__.py +0 -0
  68. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/_common.py +0 -0
  69. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/api.py +0 -0
  70. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/create.py +0 -0
  71. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/data.py +0 -0
  72. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/pack.py +0 -0
  73. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/ng/preview.py +0 -0
  74. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/organization.py +0 -0
  75. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/proxy.py +0 -0
  76. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/reference.py +0 -0
  77. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/repo.py +0 -0
  78. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/__init__.py +0 -0
  79. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/add_cmds.py +0 -0
  80. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/api.py +0 -0
  81. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/batch.py +0 -0
  82. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/create.py +0 -0
  83. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/data.py +0 -0
  84. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/dataset.py +0 -0
  85. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/edit.py +0 -0
  86. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/folder.py +0 -0
  87. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/preview.py +0 -0
  88. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/report/schema_cmds.py +0 -0
  89. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/reset.py +0 -0
  90. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/schema.py +0 -0
  91. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/servicepack.py +0 -0
  92. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/skills.py +0 -0
  93. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/studio.py +0 -0
  94. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/telemetry.py +0 -0
  95. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/user.py +0 -0
  96. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/commands/validation_report.py +0 -0
  97. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/context.py +0 -0
  98. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/__init__.py +0 -0
  99. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/agent_browser.py +0 -0
  100. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/client.py +0 -0
  101. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/endpoints.py +0 -0
  102. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/metadata_models.py +0 -0
  103. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/models.py +0 -0
  104. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/reference_graph.py +0 -0
  105. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/api/replacements.py +0 -0
  106. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/__init__.py +0 -0
  107. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/browser_pages.py +0 -0
  108. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/datex_tenant.py +0 -0
  109. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/decorators.py +0 -0
  110. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/msal_client.py +0 -0
  111. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/pages/error.html +0 -0
  112. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/pages/success.html +0 -0
  113. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/tenants.py +0 -0
  114. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/auth/token_cache.py +0 -0
  115. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/cache.py +0 -0
  116. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/__init__.py +0 -0
  117. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/flow_models.py +0 -0
  118. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/generator.py +0 -0
  119. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/models.py +0 -0
  120. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/parsers.py +0 -0
  121. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/resolver.py +0 -0
  122. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/datasource/type_def_parser.py +0 -0
  123. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/designer/__init__.py +0 -0
  124. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/designer/flow_models.py +0 -0
  125. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/designer/models.py +0 -0
  126. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/designer/parsers.py +0 -0
  127. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/devops/__init__.py +0 -0
  128. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/devops/client.py +0 -0
  129. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/devops/helpers.py +0 -0
  130. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/devops/models.py +0 -0
  131. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/__init__.py +0 -0
  132. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/client.py +0 -0
  133. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/html.py +0 -0
  134. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/metadata_cache.py +0 -0
  135. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/pagination.py +0 -0
  136. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/resolvers.py +0 -0
  137. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/dynamics/time_entry.py +0 -0
  138. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/footprint/__init__.py +0 -0
  139. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/footprint/client.py +0 -0
  140. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/footprint/edmx_parser.py +0 -0
  141. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/footprint/metadata.py +0 -0
  142. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/function/__init__.py +0 -0
  143. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/function/generator.py +0 -0
  144. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/function/models.py +0 -0
  145. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/function/validator.py +0 -0
  146. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/graph.py +0 -0
  147. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/onboarding.py +0 -0
  148. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/output/__init__.py +0 -0
  149. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/output/csv_fmt.py +0 -0
  150. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/output/formatter.py +0 -0
  151. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/output/json_fmt.py +0 -0
  152. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/output/redaction.py +0 -0
  153. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/output/yaml_fmt.py +0 -0
  154. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/quartermaster/__init__.py +0 -0
  155. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/quartermaster/client.py +0 -0
  156. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/quartermaster/tenants.py +0 -0
  157. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/release_notes.py +0 -0
  158. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/responses.py +0 -0
  159. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/__init__.py +0 -0
  160. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/frontmatter.py +0 -0
  161. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/installer.py +0 -0
  162. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/layout.py +0 -0
  163. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/lock.py +0 -0
  164. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/resolver.py +0 -0
  165. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/skills/staleness.py +0 -0
  166. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/telemetry/__init__.py +0 -0
  167. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/telemetry/config.py +0 -0
  168. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/telemetry/identity.py +0 -0
  169. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/telemetry/recorder.py +0 -0
  170. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/telemetry/scrubber.py +0 -0
  171. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/core/telemetry/sender.py +0 -0
  172. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/models/__init__.py +0 -0
  173. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/__init__.py +0 -0
  174. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/folder.py +0 -0
  175. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/manifest.py +0 -0
  176. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/mocks.py +0 -0
  177. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/preview.py +0 -0
  178. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/scaffold.py +0 -0
  179. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/ng/serve_lock.py +0 -0
  180. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/py.typed +0 -0
  181. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/__init__.py +0 -0
  182. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/datasource_binding.py +0 -0
  183. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/engine.py +0 -0
  184. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/field_parser.py +0 -0
  185. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/folder.py +0 -0
  186. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/manifest.py +0 -0
  187. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/models.py +0 -0
  188. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/preview.py +0 -0
  189. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/preview_arjs.py +0 -0
  190. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/schema.py +0 -0
  191. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/svg_renderer.py +0 -0
  192. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/templates/__init__.py +0 -0
  193. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
  194. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
  195. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/validate_arjs.py +0 -0
  196. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/validator.py +0 -0
  197. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/report/wrapper.py +0 -0
  198. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/__init__.py +0 -0
  199. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/click_options.py +0 -0
  200. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/clipboard.py +0 -0
  201. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/config.py +0 -0
  202. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/filtering.py +0 -0
  203. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/image.py +0 -0
  204. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/paths.py +0 -0
  205. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/resolvers.py +0 -0
  206. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/responses.py +0 -0
  207. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/restricted.py +0 -0
  208. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/sorting.py +0 -0
  209. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/update_check.py +0 -0
  210. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/utils/versioning.py +0 -0
  211. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/__init__.py +0 -0
  212. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/app.py +0 -0
  213. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/design.py +0 -0
  214. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/proxy_app.py +0 -0
  215. {datex_studio_cli-0.5.4/src/dxs/web/static/_next/static/CAvN0dC1A3kKCmq1ZHlgY → datex_studio_cli-0.5.5/src/dxs/web/static/_next/static/5wdnX570BhEyVxkNIJZQ9}/_buildManifest.js +0 -0
  216. {datex_studio_cli-0.5.4/src/dxs/web/static/_next/static/CAvN0dC1A3kKCmq1ZHlgY → datex_studio_cli-0.5.5/src/dxs/web/static/_next/static/5wdnX570BhEyVxkNIJZQ9}/_ssgManifest.js +0 -0
  217. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
  218. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
  219. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
  220. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/538-b06224e65f71c9a1.js +0 -0
  221. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
  222. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
  223. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
  224. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
  225. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/app/_not-found/page-e3c660196c244183.js +0 -0
  226. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/app/design/capture/page-c083dc9f01f32a04.js +0 -0
  227. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/app/design/page-689cd5b9e1d9a74e.js +0 -0
  228. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/app/layout-cec86f90e385371d.js +0 -0
  229. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/app/page-f0380b0f29983264.js +0 -0
  230. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
  231. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
  232. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/main-app-694cf3568b6c9fa9.js +0 -0
  233. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
  234. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
  235. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
  236. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
  237. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
  238. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/render-cli.js +0 -0
  239. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/report-preview.html +0 -0
  240. {datex_studio_cli-0.5.4 → datex_studio_cli-0.5.5}/src/dxs/web/static/report-validate.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: datex-studio-cli
3
- Version: 0.5.4
3
+ Version: 0.5.5
4
4
  Summary: CLI for Datex Studio low-code platform, designed for LLM-based AI agents
5
5
  Project-URL: Homepage, https://github.com/datex/datex-studio-cli
6
6
  Project-URL: Documentation, https://github.com/datex/datex-studio-cli
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "datex-studio-cli"
7
- version = "0.5.4"
7
+ version = "0.5.5"
8
8
  description = "CLI for Datex Studio low-code platform, designed for LLM-based AI agents"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,4 +1,4 @@
1
1
  """Datex Studio CLI - Command-line interface for Datex Studio platform."""
2
2
 
3
- __version__ = "0.5.4"
3
+ __version__ = "0.5.5"
4
4
  __app_name__ = "dxs"
@@ -1,8 +1,10 @@
1
1
  """Main CLI entry point for Datex Studio CLI."""
2
2
 
3
+ import errno
4
+ import os
3
5
  import sys
4
6
  from collections.abc import Callable
5
- from typing import Any, TypeVar, cast
7
+ from typing import Any, NoReturn, TypeVar, cast
6
8
 
7
9
  import click
8
10
 
@@ -136,7 +138,16 @@ class DxsGroup(click.Group):
136
138
  so ``_resolve_command_path`` reads them back from ``ctx.meta``.
137
139
  """
138
140
  ctx.meta[RAW_ARGS_META_KEY] = [*getattr(ctx, "_protected_args", []), *ctx.args]
139
- return super().invoke(ctx)
141
+ try:
142
+ return super().invoke(ctx)
143
+ except (BrokenPipeError, OSError) as e:
144
+ # Handle a closed stdout here, inside Click's own invoke, rather
145
+ # than around cli(): Click catches EPIPE itself and exits 1, so by
146
+ # the time main() sees anything it is a SystemExit. Raising
147
+ # SystemExit from here passes straight through that handler.
148
+ if not _is_broken_pipe(e):
149
+ raise
150
+ _exit_broken_pipe()
140
151
 
141
152
  def _is_gated(self, cmd_name: str) -> bool:
142
153
  """Whether ``cmd_name`` is Datex-internal and unavailable to this user."""
@@ -547,6 +558,15 @@ def handle_errors(f: F) -> F:
547
558
  _record_error_silently(e, dxs_ctx)
548
559
  dxs_ctx.output_error(e)
549
560
  sys.exit(1)
561
+ except (BrokenPipeError, OSError) as e:
562
+ # A closed stdout is not a command failure: re-raise so main()
563
+ # can silence it. Rendering an error envelope here would both
564
+ # lie to the user and record a bogus command.error.
565
+ if not _is_broken_pipe(e):
566
+ _record_error_silently(e, dxs_ctx)
567
+ dxs_ctx.output_error(e)
568
+ sys.exit(1)
569
+ raise
550
570
  except (click.ClickException, click.Abort, click.exceptions.Exit):
551
571
  # Let Click handle its own exceptions and control-flow signals
552
572
  # (Abort from confirm(abort=True), Exit from ctx.exit) — these are
@@ -560,6 +580,67 @@ def handle_errors(f: F) -> F:
560
580
  return cast(F, wrapper)
561
581
 
562
582
 
583
+ #: 128 + SIGPIPE, the conventional shell status for "died because the pipe closed".
584
+ BROKEN_PIPE_EXIT_CODE = 141
585
+
586
+
587
+ def _is_broken_pipe(exc: BaseException) -> bool:
588
+ """True when ``exc`` is stdout's consumer going away rather than a failure.
589
+
590
+ POSIX raises ``BrokenPipeError`` (EPIPE). Windows has no SIGPIPE and instead
591
+ fails the underlying ``flush()`` with ``OSError [Errno 22] Invalid argument``
592
+ — so EINVAL counts only there, since on POSIX it means a hundred other
593
+ things and must not be mistaken for a closed pipe.
594
+ """
595
+ if isinstance(exc, BrokenPipeError):
596
+ return True
597
+ if not isinstance(exc, OSError):
598
+ return False
599
+ if exc.errno == errno.EPIPE:
600
+ return True
601
+ return exc.errno == errno.EINVAL and sys.platform == "win32"
602
+
603
+
604
+ def _silence_stdout() -> None:
605
+ """Point stdout at devnull so interpreter shutdown cannot re-raise.
606
+
607
+ Python flushes the standard streams on exit; against a closed pipe that
608
+ raises a second time, past any handler we control, and CPython prints
609
+ "Exception ignored in: <_io.TextIOWrapper name='<stdout>'>". Redirecting the
610
+ file descriptor is the documented way to avoid it. Best-effort: under pytest
611
+ or Click's CliRunner stdout is a StringIO with no real fileno.
612
+ """
613
+ devnull = None
614
+ try:
615
+ devnull = os.open(os.devnull, os.O_WRONLY)
616
+ os.dup2(devnull, sys.stdout.fileno())
617
+ except Exception: # noqa: BLE001 - silencing output must never itself fail
618
+ pass
619
+ finally:
620
+ if devnull is not None:
621
+ try:
622
+ os.close(devnull)
623
+ except OSError:
624
+ pass
625
+
626
+
627
+ def _exit_broken_pipe() -> NoReturn:
628
+ """Leave quietly after the consumer of stdout went away."""
629
+ _silence_stdout()
630
+ _record_broken_pipe_silently()
631
+ sys.exit(BROKEN_PIPE_EXIT_CODE)
632
+
633
+
634
+ def _record_broken_pipe_silently() -> None:
635
+ """Record a closed pipe as a completed run, never as command.error."""
636
+ try:
637
+ from dxs.core.telemetry import record_end
638
+
639
+ record_end(exit_code=BROKEN_PIPE_EXIT_CODE)
640
+ except Exception: # noqa: BLE001
641
+ pass
642
+
643
+
563
644
  def _record_error_silently(exc: BaseException, dxs_ctx: "DxsContext | None" = None) -> None:
564
645
  """Emit a telemetry error event; never raises.
565
646
 
@@ -850,6 +931,15 @@ def main() -> None:
850
931
  # SystemExit from sys.exit() inside handle_errors — telemetry already
851
932
  # recorded an error there; just propagate.
852
933
  raise
934
+ except (BrokenPipeError, OSError) as e:
935
+ if not _is_broken_pipe(e):
936
+ _record_error_silently(e)
937
+ raise
938
+ # The consumer stopped reading (`| head`, an agent that moved on).
939
+ # Say nothing, record a completed run, and exit on the SIGPIPE
940
+ # convention so `set -o pipefail` scripts can still tell truncated
941
+ # output from a clean one.
942
+ _exit_broken_pipe()
853
943
  except BaseException as e:
854
944
  # Anything else escaping cli() shouldn't take telemetry with it.
855
945
  _record_error_silently(e)
@@ -12,7 +12,14 @@ import click
12
12
  import yaml
13
13
 
14
14
  from dxs.cli import DxsContext, pass_context
15
- from dxs.core.api import ApiClient, BranchEndpoints, ConfigurationEndpoints, fetch_references
15
+ from dxs.core.api import (
16
+ ApiClient,
17
+ BranchEndpoints,
18
+ ConfigurationEndpoints,
19
+ fetch_references,
20
+ reference_branch_ids,
21
+ resolve_references,
22
+ )
16
23
  from dxs.core.auth import require_auth
17
24
  from dxs.core.cache import ConfigIndex, get_cache
18
25
  from dxs.core.graph import (
@@ -265,12 +272,16 @@ def _fetch_library_branches(
265
272
 
266
273
  try:
267
274
  refs = fetch_references(client, branch_id)
275
+ resolved = resolve_references(client, refs)
276
+ library_map = reference_branch_ids(refs, resolved)
268
277
 
269
- for ref in refs:
270
- ref_name = ref.get("referenceName", "")
271
- app_id = ref.get("applicationId")
272
- if ref_name and app_id:
273
- library_map[ref_name] = app_id
278
+ # A library we cannot place on a branch cannot be downloaded. Say so —
279
+ # silently returning fewer libraries is what made this failure invisible.
280
+ unresolved = sorted(
281
+ name for ref in refs if (name := ref.get("referenceName")) and name not in library_map
282
+ )
283
+ for name in unresolved:
284
+ _progress(f" Warning: could not resolve library '{name}' to a branch")
274
285
 
275
286
  # Fetch branch statuses for all library branches (for caching decisions)
276
287
  for lib_branch_id in set(library_map.values()):
@@ -281,8 +292,8 @@ def _fetch_library_branches(
281
292
  except Exception:
282
293
  branch_statuses[lib_branch_id] = 0 # Not cacheable if unknown
283
294
 
284
- except Exception:
285
- pass
295
+ except Exception as exc:
296
+ _progress(f" Warning: failed to discover libraries: {exc}")
286
297
 
287
298
  return library_map, branch_statuses
288
299
 
@@ -16,7 +16,7 @@ from typing import Any
16
16
  import click
17
17
  import httpx
18
18
 
19
- from dxs.cli import DxsContext, pass_context
19
+ from dxs.cli import DxsContext, handle_errors, pass_context
20
20
  from dxs.core.api import ApiClient
21
21
  from dxs.core.api.endpoints import ApiConnectionEndpoints
22
22
  from dxs.core.auth import require_auth
@@ -25,6 +25,7 @@ from dxs.core.footprint.edmx_parser import parse_edmx
25
25
  from dxs.core.footprint.metadata import MetadataCache
26
26
  from dxs.utils.config import get_settings
27
27
  from dxs.utils.errors import ApiError, AuthenticationError, ValidationError
28
+ from dxs.utils.http_errors import raise_for_transport_error
28
29
  from dxs.utils.resolvers import resolve_connection_option
29
30
  from dxs.utils.responses import list_response, single
30
31
 
@@ -88,6 +89,7 @@ def odata() -> None:
88
89
  )
89
90
  @pass_context
90
91
  @require_auth
92
+ @handle_errors
91
93
  def execute(
92
94
  ctx: DxsContext,
93
95
  connection_id: int | None,
@@ -151,6 +153,7 @@ def execute(
151
153
  token=token,
152
154
  timeout=settings.api_timeout,
153
155
  apply_oso_security=oso_security,
156
+ verify=settings.verify_ssl,
154
157
  )
155
158
 
156
159
  ctx.output(
@@ -372,6 +375,7 @@ def _execute_footprint_odata(
372
375
  token: str,
373
376
  timeout: int = 30,
374
377
  apply_oso_security: bool = False,
378
+ verify: bool = True,
375
379
  ) -> dict[str, Any]:
376
380
  """Execute an OData GET request against the Footprint API."""
377
381
  url = f"{connection_string}/{query}"
@@ -386,11 +390,14 @@ def _execute_footprint_odata(
386
390
  if _is_daemon_mode():
387
391
  headers["x-caller"] = _build_x_caller_header(token, apply_oso_security=apply_oso_security)
388
392
 
389
- with httpx.Client(timeout=timeout) as client:
390
- response = client.get(url, headers=headers)
391
- _raise_for_footprint_error(response)
392
- result: dict[str, Any] = response.json()
393
- return result
393
+ try:
394
+ with httpx.Client(timeout=timeout, verify=verify) as client:
395
+ response = client.get(url, headers=headers)
396
+ _raise_for_footprint_error(response)
397
+ result: dict[str, Any] = response.json()
398
+ return result
399
+ except httpx.TransportError as e:
400
+ raise_for_transport_error(e, url, what="the Footprint API", timeout=timeout)
394
401
 
395
402
 
396
403
  @odata.group()
@@ -449,17 +456,20 @@ def _fetch_metadata(
449
456
 
450
457
  x_caller = base64.b64encode(json.dumps({}).encode()).decode()
451
458
 
452
- with httpx.Client(timeout=settings.api_timeout) as client:
453
- response = client.get(
454
- url,
455
- headers={
456
- "Authorization": f"Bearer {token}",
457
- "x-caller": x_caller,
458
- "Accept": "application/xml",
459
- },
460
- )
461
- _raise_for_footprint_error(response)
462
- xml = response.text
459
+ try:
460
+ with httpx.Client(timeout=settings.api_timeout, verify=settings.verify_ssl) as client:
461
+ response = client.get(
462
+ url,
463
+ headers={
464
+ "Authorization": f"Bearer {token}",
465
+ "x-caller": x_caller,
466
+ "Accept": "application/xml",
467
+ },
468
+ )
469
+ _raise_for_footprint_error(response)
470
+ xml = response.text
471
+ except httpx.TransportError as e:
472
+ raise_for_transport_error(e, url, what="the Footprint API", timeout=settings.api_timeout)
463
473
 
464
474
  cache.put(resolved_id, xml, connection_name=connection_name)
465
475
  ctx.log("Metadata cached.")
@@ -510,6 +520,7 @@ def _add_connection_options(f: Any) -> Any:
510
520
  @_add_connection_options
511
521
  @pass_context
512
522
  @require_auth
523
+ @handle_errors
513
524
  def fetch(
514
525
  ctx: DxsContext,
515
526
  connection_id: int | None,
@@ -544,6 +555,7 @@ def fetch(
544
555
  @_add_connection_options
545
556
  @pass_context
546
557
  @require_auth
558
+ @handle_errors
547
559
  def entities(
548
560
  ctx: DxsContext,
549
561
  connection_id: int | None,
@@ -587,6 +599,7 @@ def entities(
587
599
  @_add_connection_options
588
600
  @pass_context
589
601
  @require_auth
602
+ @handle_errors
590
603
  def describe(
591
604
  ctx: DxsContext,
592
605
  entity_name: str,
@@ -11,7 +11,10 @@ from dxs.core.api import (
11
11
  ApiClient,
12
12
  BranchEndpoints,
13
13
  SourceControlEndpoints,
14
+ diff_references,
14
15
  fetch_references,
16
+ reference_branch_id,
17
+ resolve_references,
15
18
  )
16
19
  from dxs.core.auth import require_auth
17
20
  from dxs.core.release_notes import (
@@ -205,28 +208,26 @@ def release_notes(
205
208
  from_deps = fetch_references(client, from_branch, direct_only=True)
206
209
  to_deps = fetch_references(client, to_branch, direct_only=True)
207
210
 
208
- from_by_ref = {d.get("referenceName"): d for d in from_deps}
209
- to_by_ref = {d.get("referenceName"): d for d in to_deps}
210
-
211
- for ref, dep in to_by_ref.items():
212
- if ref not in from_by_ref:
213
- dep_changes["added"].append(dep)
214
- else:
215
- from_dep = from_by_ref[ref]
216
- from_ver = from_dep.get("marketPlaceApplicationVersionId")
217
- to_ver = dep.get("marketPlaceApplicationVersionId")
218
- if from_ver != to_ver:
219
- dep_changes["updated"].append(
220
- {
221
- "reference_name": ref,
222
- "from_branch_id": from_dep.get("applicationId"),
223
- "to_branch_id": dep.get("applicationId"),
224
- }
225
- )
226
-
227
- for ref in from_by_ref:
228
- if ref not in to_by_ref:
229
- dep_changes["removed"].append(from_by_ref[ref])
211
+ # Diff on the resolved `version`, keyed by uniqueIdentifier — the same
212
+ # helper `source compare` uses, so the two commands agree. The legacy
213
+ # marketPlaceApplicationVersionId comparison read None on both sides and
214
+ # so never reported a bump.
215
+ diff = diff_references(from_deps, to_deps)
216
+ dep_changes["added"] = diff["added"]
217
+ dep_changes["removed"] = diff["removed"]
218
+
219
+ # Classifying an update means diffing the two packages' branches, and the
220
+ # reference rows no longer carry applicationId — resolve it for both sides.
221
+ resolved = resolve_references(client, from_deps + to_deps)
222
+ for entry in diff["updated"]:
223
+ uid = entry.get("unique_identifier")
224
+ entry["from_branch_id"] = reference_branch_id(
225
+ resolved.get((uid, entry.get("from_version")))
226
+ )
227
+ entry["to_branch_id"] = reference_branch_id(
228
+ resolved.get((uid, entry.get("to_version")))
229
+ )
230
+ dep_changes["updated"] = diff["updated"]
230
231
  except Exception:
231
232
  logger.debug("Failed to fetch dependencies", exc_info=True)
232
233
 
@@ -235,7 +236,15 @@ def release_notes(
235
236
  sync_only_deps: list[dict[str, Any]] = []
236
237
  if dep_changes["updated"]:
237
238
  ctx.log(f"Classifying {len(dep_changes['updated'])} dependency updates...")
238
- meaningful_deps, sync_only_deps = classify_dependencies(client, dep_changes["updated"])
239
+ # Classification compares the two branches; an update whose branches did not
240
+ # resolve cannot be inspected. Report it as meaningful rather than dropping
241
+ # it — an unexamined bump is not evidence of a sync-only one.
242
+ classifiable = [
243
+ d for d in dep_changes["updated"] if d.get("from_branch_id") and d.get("to_branch_id")
244
+ ]
245
+ unclassifiable = [d for d in dep_changes["updated"] if d not in classifiable]
246
+ meaningful_deps, sync_only_deps = classify_dependencies(client, classifiable)
247
+ meaningful_deps.extend(unclassifiable)
239
248
 
240
249
  if include_sync:
241
250
  # Move sync-only deps into meaningful list