datex-studio-cli 0.4.23__tar.gz → 0.4.25__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 (225) hide show
  1. datex_studio_cli-0.4.25/.dockerignore +25 -0
  2. datex_studio_cli-0.4.25/.github/actionlint.yaml +4 -0
  3. datex_studio_cli-0.4.25/.github/workflows/build-image.yml +71 -0
  4. datex_studio_cli-0.4.25/.github/workflows/ci.yml +55 -0
  5. datex_studio_cli-0.4.25/.github/workflows/promote-prod.yml +104 -0
  6. datex_studio_cli-0.4.25/.github/workflows/release.yml +106 -0
  7. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/PKG-INFO +5 -5
  8. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/README.md +4 -4
  9. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/pyproject.toml +7 -1
  10. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/__init__.py +1 -1
  11. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/cli.py +29 -10
  12. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/auth.py +1 -1
  13. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/branch.py +6 -7
  14. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/cascade.py +1 -1
  15. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/config.py +18 -17
  16. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/configuration.py +1 -1
  17. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/crm.py +1 -1
  18. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/servicepack.py +5 -5
  19. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/source.py +36 -12
  20. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/telemetry.py +2 -2
  21. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/__init__.py +3 -0
  22. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/client.py +4 -4
  23. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/endpoints.py +27 -2
  24. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/models.py +16 -0
  25. datex_studio_cli-0.4.25/src/dxs/core/api/replacements.py +72 -0
  26. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/auth/msal_client.py +1 -1
  27. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/client.py +2 -2
  28. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/release_notes.py +71 -20
  29. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/telemetry/config.py +22 -6
  30. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/telemetry/recorder.py +8 -1
  31. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/config.py +11 -0
  32. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/errors.py +1 -1
  33. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/404/index.html +1 -1
  34. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/404.html +1 -1
  35. datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/538-b06224e65f71c9a1.js +1 -0
  36. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/app/_not-found/page-ea1be7001c230704.js → datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/app/_not-found/page-e3c660196c244183.js +1 -1
  37. datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/app/design/capture/page-c083dc9f01f32a04.js +1 -0
  38. datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/app/design/page-689cd5b9e1d9a74e.js +1 -0
  39. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/app/layout-2cc6eac09e476c91.js → datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/app/layout-cec86f90e385371d.js +1 -1
  40. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/app/page-20c358395882cdac.js → datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/app/page-f0380b0f29983264.js +1 -1
  41. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/main-app-b69998d8941231d8.js → datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/chunks/main-app-694cf3568b6c9fa9.js +1 -1
  42. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/design/capture/index.html +1 -1
  43. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/design/capture/index.txt +4 -4
  44. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/design/index.html +1 -1
  45. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/design/index.txt +4 -4
  46. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/index.html +1 -1
  47. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/index.txt +4 -4
  48. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/538-84e2e111415f1fda.js +0 -1
  49. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/app/design/capture/page-a5e129c2d223432c.js +0 -1
  50. datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/chunks/app/design/page-21ba66a3dd3b03f0.js +0 -1
  51. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/.gitignore +0 -0
  52. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/CONTEXT.md +0 -0
  53. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/.env.example +0 -0
  54. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/Dockerfile +0 -0
  55. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/README.md +0 -0
  56. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/apply-local-cache.js +0 -0
  57. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/collector-config.yaml +0 -0
  58. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/docker-compose.yml +0 -0
  59. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/local-test-settings.json +0 -0
  60. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/otel/remote-settings.json +0 -0
  61. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/report-creator.skill +0 -0
  62. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/scripts/analyze_corpus.py +0 -0
  63. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/scripts/generate_rdlx_schema.py +0 -0
  64. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/__main__.py +0 -0
  65. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/__init__.py +0 -0
  66. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/api.py +0 -0
  67. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/branch_commit_guard.py +0 -0
  68. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/crm_delivery.py +0 -0
  69. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/crm_time.py +0 -0
  70. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/datasource.py +0 -0
  71. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/devops.py +0 -0
  72. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/document.py +0 -0
  73. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/endpoint.py +0 -0
  74. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/env.py +0 -0
  75. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/explore.py +0 -0
  76. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/function.py +0 -0
  77. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/init.py +0 -0
  78. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/marketplace.py +0 -0
  79. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/__init__.py +0 -0
  80. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/_common.py +0 -0
  81. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/api.py +0 -0
  82. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/create.py +0 -0
  83. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/data.py +0 -0
  84. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/pack.py +0 -0
  85. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/ng/preview.py +0 -0
  86. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/odata.py +0 -0
  87. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/organization.py +0 -0
  88. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/proxy.py +0 -0
  89. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/reference.py +0 -0
  90. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/release_notes.py +0 -0
  91. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/repo.py +0 -0
  92. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/__init__.py +0 -0
  93. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/add_cmds.py +0 -0
  94. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/api.py +0 -0
  95. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/batch.py +0 -0
  96. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/create.py +0 -0
  97. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/data.py +0 -0
  98. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/dataset.py +0 -0
  99. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/edit.py +0 -0
  100. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/folder.py +0 -0
  101. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/preview.py +0 -0
  102. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/report/schema_cmds.py +0 -0
  103. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/reset.py +0 -0
  104. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/schema.py +0 -0
  105. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/studio.py +0 -0
  106. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/user.py +0 -0
  107. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/commands/validation_report.py +0 -0
  108. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/context.py +0 -0
  109. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/__init__.py +0 -0
  110. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/agent_browser.py +0 -0
  111. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/app_config.py +0 -0
  112. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/metadata_models.py +0 -0
  113. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/api/reference_graph.py +0 -0
  114. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/auth/__init__.py +0 -0
  115. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/auth/datex_tenant.py +0 -0
  116. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/auth/decorators.py +0 -0
  117. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/auth/tenants.py +0 -0
  118. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/auth/token_cache.py +0 -0
  119. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/cache.py +0 -0
  120. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/__init__.py +0 -0
  121. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/flow_generator.py +0 -0
  122. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/flow_models.py +0 -0
  123. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/flow_shape.py +0 -0
  124. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/generator.py +0 -0
  125. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/models.py +0 -0
  126. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/parsers.py +0 -0
  127. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/resolver.py +0 -0
  128. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/type_def_parser.py +0 -0
  129. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/datasource/validator.py +0 -0
  130. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/designer/__init__.py +0 -0
  131. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/designer/flow_models.py +0 -0
  132. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/designer/models.py +0 -0
  133. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/designer/parsers.py +0 -0
  134. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/devops/__init__.py +0 -0
  135. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/devops/client.py +0 -0
  136. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/devops/helpers.py +0 -0
  137. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/devops/models.py +0 -0
  138. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/__init__.py +0 -0
  139. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/html.py +0 -0
  140. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/metadata_cache.py +0 -0
  141. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/pagination.py +0 -0
  142. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/resolvers.py +0 -0
  143. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/dynamics/time_entry.py +0 -0
  144. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/footprint/__init__.py +0 -0
  145. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/footprint/client.py +0 -0
  146. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/footprint/edmx_parser.py +0 -0
  147. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/footprint/metadata.py +0 -0
  148. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/function/__init__.py +0 -0
  149. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/function/generator.py +0 -0
  150. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/function/models.py +0 -0
  151. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/function/validator.py +0 -0
  152. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/graph.py +0 -0
  153. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/onboarding.py +0 -0
  154. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/output/__init__.py +0 -0
  155. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/output/csv_fmt.py +0 -0
  156. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/output/formatter.py +0 -0
  157. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/output/json_fmt.py +0 -0
  158. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/output/redaction.py +0 -0
  159. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/output/yaml_fmt.py +0 -0
  160. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/responses.py +0 -0
  161. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/telemetry/__init__.py +0 -0
  162. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/telemetry/identity.py +0 -0
  163. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/telemetry/scrubber.py +0 -0
  164. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/core/telemetry/sender.py +0 -0
  165. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/models/__init__.py +0 -0
  166. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/__init__.py +0 -0
  167. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/folder.py +0 -0
  168. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/manifest.py +0 -0
  169. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/mocks.py +0 -0
  170. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/preview.py +0 -0
  171. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/scaffold.py +0 -0
  172. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/ng/serve_lock.py +0 -0
  173. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/py.typed +0 -0
  174. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/__init__.py +0 -0
  175. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/datasource_binding.py +0 -0
  176. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/engine.py +0 -0
  177. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/field_parser.py +0 -0
  178. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/folder.py +0 -0
  179. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/manifest.py +0 -0
  180. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/models.py +0 -0
  181. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/preview.py +0 -0
  182. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/preview_arjs.py +0 -0
  183. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/schema.py +0 -0
  184. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/svg_renderer.py +0 -0
  185. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/templates/__init__.py +0 -0
  186. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/templates/bill_of_lading.rdlx-json +0 -0
  187. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/templates/shipping_label.rdlx-json +0 -0
  188. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/validate_arjs.py +0 -0
  189. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/validator.py +0 -0
  190. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/report/wrapper.py +0 -0
  191. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/__init__.py +0 -0
  192. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/click_options.py +0 -0
  193. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/clipboard.py +0 -0
  194. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/filtering.py +0 -0
  195. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/image.py +0 -0
  196. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/paths.py +0 -0
  197. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/resolvers.py +0 -0
  198. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/responses.py +0 -0
  199. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/restricted.py +0 -0
  200. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/sorting.py +0 -0
  201. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/update_check.py +0 -0
  202. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/utils/versioning.py +0 -0
  203. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/__init__.py +0 -0
  204. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/app.py +0 -0
  205. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/design.py +0 -0
  206. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/proxy_app.py +0 -0
  207. {datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT → datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/BbKuTltyqzuSYoNcVtfWa}/_buildManifest.js +0 -0
  208. {datex_studio_cli-0.4.23/src/dxs/web/static/_next/static/UgyAMtPjH-Pt0RYWOHzIT → datex_studio_cli-0.4.25/src/dxs/web/static/_next/static/BbKuTltyqzuSYoNcVtfWa}/_ssgManifest.js +0 -0
  209. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/0b24cca5-c1e1c8810348f107.js +0 -0
  210. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/255-102f2e5b2e3dc2ef.js +0 -0
  211. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +0 -0
  212. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/697-0e000ab410d9f470.js +0 -0
  213. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/871-1acacdb7b4022abf.js +0 -0
  214. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/8b8f67fc-6295949a4b5485a4.js +0 -0
  215. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/909-c88abba3cf0caec3.js +0 -0
  216. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/framework-de98b93a850cfc71.js +0 -0
  217. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/main-0f18f91200dac003.js +0 -0
  218. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +0 -0
  219. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +0 -0
  220. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
  221. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/chunks/webpack-2b297ada5306c17f.js +0 -0
  222. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/_next/static/css/360c657de5e04df8.css +0 -0
  223. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/render-cli.js +0 -0
  224. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/report-preview.html +0 -0
  225. {datex_studio_cli-0.4.23 → datex_studio_cli-0.4.25}/src/dxs/web/static/report-validate.html +0 -0
@@ -0,0 +1,25 @@
1
+ # Context for quartermaster/Dockerfile (built from the repo root).
2
+ .git
3
+ .venv
4
+ **/__pycache__
5
+ .pytest_cache
6
+ .mypy_cache
7
+ .ruff_cache
8
+ .claude
9
+ .serena
10
+ node_modules
11
+ **/node_modules
12
+ src/dxs/web/frontend
13
+ tests
14
+ quartermaster/tests
15
+ quartermaster/.env
16
+ docs
17
+ documentation
18
+ exploration
19
+ examples
20
+ example-reports
21
+ exclude
22
+ skills
23
+ otel
24
+ dist
25
+ *.analysis.md
@@ -0,0 +1,4 @@
1
+ self-hosted-runner:
2
+ # Repo-scoped ARC scale set on datex-apps-eus (spec §5; CI-only, no cluster access).
3
+ labels:
4
+ - arc-dxs
@@ -0,0 +1,71 @@
1
+ # Image build + staging digest bump (spec §5, §6). CI runs in-workflow: red
2
+ # tests produce no image. The final step commits the pushed digest to
3
+ # quartermaster/deploy/staging/values.yaml with GITHUB_TOKEN — which natively
4
+ # triggers no further workflow runs, so the rebuild loop is impossible.
5
+ name: Build image
6
+
7
+ on:
8
+ push:
9
+ branches: [main]
10
+ paths-ignore:
11
+ - "docs/**"
12
+ - "**.md"
13
+ workflow_dispatch:
14
+
15
+ concurrency:
16
+ group: build-image-main
17
+ cancel-in-progress: false
18
+
19
+ permissions:
20
+ contents: write
21
+ packages: write
22
+
23
+ jobs:
24
+ ci:
25
+ uses: ./.github/workflows/ci.yml
26
+
27
+ build:
28
+ needs: ci
29
+ runs-on: arc-dxs
30
+ timeout-minutes: 30
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: docker/setup-buildx-action@v3
34
+ - uses: docker/login-action@v3
35
+ with:
36
+ registry: ghcr.io
37
+ username: ${{ github.actor }}
38
+ password: ${{ secrets.GITHUB_TOKEN }}
39
+ - id: meta
40
+ run: echo "datetag=$(date -u +%Y%m%d).${{ github.run_number }}" >> "$GITHUB_OUTPUT"
41
+ - id: build
42
+ uses: docker/build-push-action@v6
43
+ with:
44
+ context: .
45
+ file: quartermaster/Dockerfile
46
+ platforms: linux/amd64
47
+ push: true
48
+ tags: |
49
+ ghcr.io/datex/quartermaster:${{ github.sha }}
50
+ ghcr.io/datex/quartermaster:latest
51
+ ghcr.io/datex/quartermaster:${{ steps.meta.outputs.datetag }}
52
+ - name: Commit the staging digest bump
53
+ run: |
54
+ digest='${{ steps.build.outputs.digest }}'
55
+ sed -i -E "s|^ digest:.*| digest: \"${digest}\"|" quartermaster/deploy/staging/values.yaml
56
+ if git diff --quiet; then
57
+ echo "staging already runs ${digest}; nothing to commit"
58
+ exit 0
59
+ fi
60
+ git config user.name "github-actions[bot]"
61
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
62
+ git add quartermaster/deploy/staging/values.yaml
63
+ git commit -m "chore(deploy): staging → ${digest}"
64
+ for attempt in 1 2 3; do
65
+ if git push origin HEAD:main; then
66
+ exit 0
67
+ fi
68
+ git pull --rebase origin main
69
+ done
70
+ echo "digest bump push failed after 3 attempts" >&2
71
+ exit 1
@@ -0,0 +1,55 @@
1
+ # CI (spec §5): two jobs, both always run — the uv workspace couples the CLI
2
+ # and the service. Callable from build-image.yml and release.yml so a red
3
+ # suite produces no image and no release (the pipeline is the gate, not the
4
+ # merge — GitHub Free has no required checks).
5
+ name: CI
6
+
7
+ on:
8
+ pull_request:
9
+ paths-ignore:
10
+ - "docs/**"
11
+ - "**.md"
12
+ workflow_call:
13
+
14
+ concurrency:
15
+ group: ci-${{ github.head_ref || github.run_id }}
16
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
17
+
18
+ jobs:
19
+ cli:
20
+ runs-on: arc-dxs
21
+ timeout-minutes: 30
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: astral-sh/setup-uv@v5
25
+ with:
26
+ enable-cache: true
27
+ - run: uv python install 3.13
28
+ - uses: actions/setup-node@v4
29
+ with:
30
+ node-version: 22
31
+ - name: Build the report renderer bundle (snapshot tests shell out to it)
32
+ working-directory: src/dxs/web/frontend
33
+ run: |
34
+ npm ci
35
+ npm run build:render-cli
36
+ - run: uv sync --all-packages --extra dev
37
+ - run: uv run ruff check .
38
+ - name: mypy (non-blocking — 21 pre-existing errors, see #171)
39
+ run: uv run mypy src/dxs
40
+ continue-on-error: true
41
+ - run: uv run pytest -q
42
+
43
+ service:
44
+ runs-on: arc-dxs
45
+ timeout-minutes: 20
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - uses: astral-sh/setup-uv@v5
49
+ with:
50
+ enable-cache: true
51
+ - run: uv python install 3.13
52
+ - run: uv sync --all-packages --extra dev
53
+ - run: uv run ruff check quartermaster
54
+ - run: uv run --package quartermaster mypy quartermaster/src/quartermaster
55
+ - run: uv run --package quartermaster pytest quartermaster/tests -q
@@ -0,0 +1,104 @@
1
+ # Prod promotion by git commit (spec §6): dispatch-only, typed confirmation,
2
+ # moving-ref rejection, GHCR existence preflight, staging-parity assert
3
+ # (promote-what-you-tested). Rollback = re-dispatch the previous digest with
4
+ # the parity override. Actor and inputs are recorded in the run and commit.
5
+ # NOTE: no `environment:` on jobs — the pre-existing `production` environment
6
+ # carries a protected_branches policy no branch can satisfy on this plan.
7
+ name: Promote prod
8
+
9
+ on:
10
+ workflow_dispatch:
11
+ inputs:
12
+ ref:
13
+ description: "Immutable image digest (sha256:…) or the git SHA of a staging bump commit"
14
+ required: true
15
+ confirm:
16
+ description: 'Type "promote-to-prod" to confirm'
17
+ required: true
18
+ override_parity:
19
+ description: "Promote even though staging is not currently running this digest (rollbacks)"
20
+ type: boolean
21
+ default: false
22
+
23
+ concurrency:
24
+ group: promote-prod
25
+ cancel-in-progress: false
26
+
27
+ permissions:
28
+ contents: write
29
+ packages: read
30
+
31
+ jobs:
32
+ promote:
33
+ runs-on: arc-dxs
34
+ timeout-minutes: 15
35
+ steps:
36
+ - name: Typed confirmation
37
+ run: |
38
+ if [ "${{ inputs.confirm }}" != "promote-to-prod" ]; then
39
+ echo "confirmation mismatch: expected the literal string promote-to-prod" >&2
40
+ exit 1
41
+ fi
42
+ - uses: actions/checkout@v4
43
+ with:
44
+ fetch-depth: 0
45
+ - id: resolve
46
+ name: Resolve digest (moving refs rejected)
47
+ run: |
48
+ ref='${{ inputs.ref }}'
49
+ if echo "$ref" | grep -qE '^sha256:[0-9a-f]{64}$'; then
50
+ digest="$ref"
51
+ elif echo "$ref" | grep -qE '^[0-9a-f]{7,40}$'; then
52
+ digest=$(git show "${ref}:quartermaster/deploy/staging/values.yaml" | awk -F'"' '/^ digest:/ {print $2}')
53
+ if ! echo "$digest" | grep -qE '^sha256:[0-9a-f]{64}$'; then
54
+ echo "commit ${ref} carries no staging digest" >&2
55
+ exit 1
56
+ fi
57
+ else
58
+ echo "ref must be an immutable digest or a git SHA — tags like 'latest' are rejected" >&2
59
+ exit 1
60
+ fi
61
+ echo "digest=${digest}" >> "$GITHUB_OUTPUT"
62
+ - name: GHCR existence preflight
63
+ run: |
64
+ token=$(curl -sf -u "x:${{ secrets.GITHUB_TOKEN }}" \
65
+ "https://ghcr.io/token?scope=repository:datex/quartermaster:pull" | \
66
+ sed -E 's/.*"token":"([^"]+)".*/\1/')
67
+ curl -sf -o /dev/null \
68
+ -H "Authorization: Bearer ${token}" \
69
+ -H "Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json" \
70
+ "https://ghcr.io/v2/datex/quartermaster/manifests/${{ steps.resolve.outputs.digest }}" \
71
+ || { echo "digest not found in GHCR — nothing to promote" >&2; exit 1; }
72
+ - name: Staging-parity assert (promote-what-you-tested)
73
+ run: |
74
+ staging=$(awk -F'"' '/^ digest:/ {print $2}' quartermaster/deploy/staging/values.yaml)
75
+ if [ "$staging" != "${{ steps.resolve.outputs.digest }}" ]; then
76
+ if [ "${{ inputs.override_parity }}" = "true" ]; then
77
+ echo "parity override: staging runs ${staging}, promoting ${{ steps.resolve.outputs.digest }} anyway"
78
+ else
79
+ echo "staging currently runs ${staging}, not the requested digest — pass override_parity for rollbacks" >&2
80
+ exit 1
81
+ fi
82
+ fi
83
+ - name: Commit the prod digest bump
84
+ run: |
85
+ digest='${{ steps.resolve.outputs.digest }}'
86
+ sed -i -E "s|^ digest:.*| digest: \"${digest}\"|" quartermaster/deploy/prod/values.yaml
87
+ if git diff --quiet; then
88
+ echo "prod already runs ${digest}; nothing to commit"
89
+ exit 0
90
+ fi
91
+ git config user.name "github-actions[bot]"
92
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
93
+ git add quartermaster/deploy/prod/values.yaml
94
+ git commit \
95
+ -m "chore(deploy): prod → ${digest}" \
96
+ -m "Promoted by @${{ github.actor }} via promote-prod (ref input: ${{ inputs.ref }})"
97
+ for attempt in 1 2 3; do
98
+ if git push origin HEAD:main; then
99
+ exit 0
100
+ fi
101
+ git pull --rebase origin main
102
+ done
103
+ echo "prod bump push failed after 3 attempts" >&2
104
+ exit 1
@@ -0,0 +1,106 @@
1
+ # The CLI's PyPI release lane (spec §5), retiring publish.sh and ~/.pypirc.
2
+ # Two ways in, one publish path:
3
+ # - tag push vX.Y.Z — versions must already be aligned across pyproject,
4
+ # __init__, and uv.lock (the uv.lock entry is the one nothing else updates)
5
+ # - manual dispatch with an optional `version` input — the workflow bumps
6
+ # pyproject/__init__/uv.lock, commits to main, tags vX.Y.Z, then publishes.
7
+ # A blank input publishes the version already in the files (the retry lane
8
+ # for a release that failed after its bump commit landed).
9
+ # Both lanes: full CI → version-agreement assert → frontend build with a hard
10
+ # existence check (the gitignored web/static/ ships via hatch `artifacts`,
11
+ # which silently includes nothing when absent) → uv build + publish via PyPI
12
+ # trusted publishing.
13
+ # Prerequisite: a trusted publisher for this repo/workflow configured on PyPI.
14
+ name: Release to PyPI
15
+
16
+ on:
17
+ push:
18
+ tags: ["v*"]
19
+ workflow_dispatch:
20
+ inputs:
21
+ version:
22
+ description: "New version (X.Y.Z) — bumps files, commits to main, tags, publishes. Blank — publish the version already in the files."
23
+ required: false
24
+ type: string
25
+
26
+ permissions:
27
+ contents: read
28
+
29
+ concurrency:
30
+ group: release-pypi
31
+
32
+ jobs:
33
+ ci:
34
+ uses: ./.github/workflows/ci.yml
35
+
36
+ publish:
37
+ needs: ci
38
+ runs-on: arc-dxs
39
+ timeout-minutes: 30
40
+ permissions:
41
+ contents: write # the dispatch lane pushes the bump commit + tag
42
+ id-token: write # PyPI trusted publishing
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ - uses: astral-sh/setup-uv@v5
46
+ with:
47
+ enable-cache: true
48
+ - run: uv python install 3.13
49
+ - name: Bump version, commit, and tag (dispatch with a version input)
50
+ if: github.event_name == 'workflow_dispatch' && inputs.version != ''
51
+ env:
52
+ VERSION: ${{ inputs.version }}
53
+ run: |
54
+ set -euo pipefail
55
+ if [ "${GITHUB_REF}" != "refs/heads/main" ]; then
56
+ echo "version bumps may only be dispatched from main (got ${GITHUB_REF})" >&2
57
+ exit 1
58
+ fi
59
+ if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
60
+ echo "version must be X.Y.Z (got '$VERSION')" >&2
61
+ exit 1
62
+ fi
63
+ current=$(grep -m1 '^version = ' pyproject.toml | cut -d'"' -f2)
64
+ if [ "$VERSION" != "$current" ]; then
65
+ sed -i "s/^version = \".*\"/version = \"$VERSION\"/" pyproject.toml
66
+ sed -i "s/^__version__ = \".*\"/__version__ = \"$VERSION\"/" src/dxs/__init__.py
67
+ uv lock
68
+ git config user.name "github-actions[bot]"
69
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
70
+ git add pyproject.toml src/dxs/__init__.py uv.lock
71
+ git commit -m "Bump version to $VERSION"
72
+ git push origin HEAD:main
73
+ fi
74
+ # The tag push is the reuse guard: it fails if v$VERSION already exists.
75
+ git tag "v$VERSION"
76
+ git push origin "v$VERSION"
77
+ - name: Assert expected version == pyproject == __init__ == uv.lock
78
+ env:
79
+ VERSION: ${{ inputs.version }}
80
+ run: |
81
+ pyproject=$(grep -m1 '^version = ' pyproject.toml | cut -d'"' -f2)
82
+ init=$(grep -m1 '__version__' src/dxs/__init__.py | cut -d'"' -f2)
83
+ lock=$(awk '/^name = "datex-studio-cli"$/ {found=1} found && /^version = / {print; exit}' uv.lock | cut -d'"' -f2)
84
+ if [ "${GITHUB_EVENT_NAME}" = "push" ]; then
85
+ expected="${GITHUB_REF#refs/tags/v}"
86
+ else
87
+ expected="${VERSION:-$pyproject}"
88
+ fi
89
+ echo "expected=${expected} pyproject=${pyproject} __init__=${init} uv.lock=${lock}"
90
+ if [ "$expected" != "$pyproject" ] || [ "$pyproject" != "$init" ] || [ "$pyproject" != "$lock" ]; then
91
+ echo "version sources disagree — run 'uv lock' and align all three before releasing" >&2
92
+ exit 1
93
+ fi
94
+ - uses: actions/setup-node@v4
95
+ with:
96
+ node-version: 22
97
+ - name: Build the web UI (shipped via hatch artifacts)
98
+ working-directory: src/dxs/web/frontend
99
+ run: |
100
+ npm ci
101
+ npm run build
102
+ - name: Assert the frontend build actually produced the static export
103
+ run: test -f src/dxs/web/static/index.html
104
+ - run: uv build
105
+ - name: Publish via trusted publishing
106
+ run: uv publish
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: datex-studio-cli
3
- Version: 0.4.23
3
+ Version: 0.4.25
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
@@ -179,13 +179,13 @@ Configuration values are resolved in order:
179
179
 
180
180
  ```bash
181
181
  # View current configuration
182
- dxs config list
182
+ dxs settings list
183
183
 
184
184
  # Set a default
185
- dxs config set default_repo 10
185
+ dxs settings set default_repo 10
186
186
 
187
187
  # Get a specific value
188
- dxs config get default_repo
188
+ dxs settings get default_repo
189
189
  ```
190
190
 
191
191
  Configuration stored in `~/.datex/config.yaml`. Credentials stored separately in `~/.datex/credentials.yaml`.
@@ -225,7 +225,7 @@ dxs auth list
225
225
  dxs auth switch other-org
226
226
  ```
227
227
 
228
- ### Configuration (`dxs config`)
228
+ ### CLI Settings (`dxs settings`)
229
229
 
230
230
  | Command | Description |
231
231
  |---------|-------------|
@@ -126,13 +126,13 @@ Configuration values are resolved in order:
126
126
 
127
127
  ```bash
128
128
  # View current configuration
129
- dxs config list
129
+ dxs settings list
130
130
 
131
131
  # Set a default
132
- dxs config set default_repo 10
132
+ dxs settings set default_repo 10
133
133
 
134
134
  # Get a specific value
135
- dxs config get default_repo
135
+ dxs settings get default_repo
136
136
  ```
137
137
 
138
138
  Configuration stored in `~/.datex/config.yaml`. Credentials stored separately in `~/.datex/credentials.yaml`.
@@ -172,7 +172,7 @@ dxs auth list
172
172
  dxs auth switch other-org
173
173
  ```
174
174
 
175
- ### Configuration (`dxs config`)
175
+ ### CLI Settings (`dxs settings`)
176
176
 
177
177
  | Command | Description |
178
178
  |---------|-------------|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "datex-studio-cli"
7
- version = "0.4.23"
7
+ version = "0.4.25"
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"
@@ -102,8 +102,12 @@ exclude = [
102
102
  "uv.lock",
103
103
  "src/dxs/web/frontend/",
104
104
  "example-reports/",
105
+ "quartermaster/",
105
106
  ]
106
107
 
108
+ [tool.uv.workspace]
109
+ members = ["quartermaster"]
110
+
107
111
  [tool.ruff]
108
112
  target-version = "py310"
109
113
  line-length = 100
@@ -153,6 +157,8 @@ addopts = "-v --tb=short"
153
157
  markers = [
154
158
  "fidelity: cross-engine SSIM fidelity tests (require agent-browser + ARJS)",
155
159
  "internal_commands_gated: exercise the devops/crm visibility gate (no DXS_INTERNAL_COMMANDS override)",
160
+ "real_auth_state: exercise real auth state (no injected DXS_ACCESS_TOKEN; the variable is scrubbed)",
161
+ "telemetry_live: run without the suite-wide DXS_TELEMETRY=0 kill-switch",
156
162
  ]
157
163
 
158
164
  [tool.coverage.run]
@@ -1,4 +1,4 @@
1
1
  """Datex Studio CLI - Command-line interface for Datex Studio platform."""
2
2
 
3
- __version__ = "0.4.23"
3
+ __version__ = "0.4.25"
4
4
  __app_name__ = "dxs"
@@ -111,6 +111,13 @@ CONTEXT_SETTINGS = {
111
111
  }
112
112
 
113
113
 
114
+ # Alias names that resolve but stay out of --help. A command registered under two
115
+ # names shares one Command object, so per-name ``hidden`` is impossible — the
116
+ # listing filter in DxsGroup is what hides the alias. Currently: ``config`` is a
117
+ # compatibility alias for ``settings`` (canonical since the rename).
118
+ HIDDEN_COMMAND_ALIASES = frozenset({"config"})
119
+
120
+
114
121
  class DxsGroup(click.Group):
115
122
  """Custom Group that shows global options in subcommand help.
116
123
 
@@ -124,8 +131,12 @@ class DxsGroup(click.Group):
124
131
  return cmd_name in DATEX_INTERNAL_COMMANDS and not internal_commands_available()
125
132
 
126
133
  def list_commands(self, ctx: click.Context) -> list[str]:
127
- """List visible subcommands, omitting unavailable Datex-internal groups."""
128
- return [name for name in super().list_commands(ctx) if not self._is_gated(name)]
134
+ """List visible subcommands, omitting hidden aliases and gated groups."""
135
+ return [
136
+ name
137
+ for name in super().list_commands(ctx)
138
+ if name not in HIDDEN_COMMAND_ALIASES and not self._is_gated(name)
139
+ ]
129
140
 
130
141
  def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None:
131
142
  """Resolve a subcommand, refusing unavailable Datex-internal groups."""
@@ -329,7 +340,7 @@ def cli(
329
340
  dxs auth login
330
341
  dxs source log --repo 10
331
342
  dxs source history userGrid --branch 100
332
- dxs config list
343
+ dxs settings list
333
344
  dxs --tenant MGD schema entities # run one command as another identity
334
345
 
335
346
  \b
@@ -489,7 +500,7 @@ def handle_errors(f: F) -> F:
489
500
  try:
490
501
  return ctx.invoke(f, *args, **kwargs)
491
502
  except DxsError as e:
492
- _record_error_silently(e)
503
+ _record_error_silently(e, dxs_ctx)
493
504
  dxs_ctx.output_error(e)
494
505
  sys.exit(1)
495
506
  except (click.ClickException, click.Abort, click.exceptions.Exit):
@@ -498,19 +509,24 @@ def handle_errors(f: F) -> F:
498
509
  # not errors and must not be rendered as error envelopes.
499
510
  raise
500
511
  except Exception as e:
501
- _record_error_silently(e)
512
+ _record_error_silently(e, dxs_ctx)
502
513
  dxs_ctx.output_error(e)
503
514
  sys.exit(1)
504
515
 
505
516
  return cast(F, wrapper)
506
517
 
507
518
 
508
- def _record_error_silently(exc: BaseException) -> None:
509
- """Emit a telemetry error event; never raises."""
519
+ def _record_error_silently(exc: BaseException, dxs_ctx: "DxsContext | None" = None) -> None:
520
+ """Emit a telemetry error event; never raises.
521
+
522
+ ``dxs_ctx`` is available on the handle_errors path and supplies the same
523
+ ``ctx_*`` slices success events carry; errors escaping to main() arrive
524
+ after Click tears the context down and go out without them.
525
+ """
510
526
  try:
511
527
  from dxs.core.telemetry import record_error
512
528
 
513
- record_error(exc)
529
+ record_error(exc, ctx_extras=_ctx_extras(dxs_ctx))
514
530
  except Exception: # noqa: BLE001
515
531
  pass
516
532
 
@@ -546,8 +562,10 @@ def register_commands() -> None:
546
562
  cli.add_command(api.api)
547
563
  cli.add_command(auth.auth)
548
564
  cli.add_command(init.init)
549
- cli.add_command(config.config)
550
565
  cli.add_command(config.config, name="settings")
566
+ # Compatibility alias — resolves but is hidden from --help via
567
+ # HIDDEN_COMMAND_ALIASES, since both names share one Command object.
568
+ cli.add_command(config.config)
551
569
  cli.add_command(configuration.configuration)
552
570
  cli.add_command(crm.crm)
553
571
  cli.add_command(datasource.datasource)
@@ -743,7 +761,8 @@ def update_cmd(yes: bool, check_only: bool) -> None:
743
761
  try:
744
762
  from dxs.core.telemetry import record_end
745
763
 
746
- record_end(exit_code=0, ctx_extras={})
764
+ dxs_ctx = click.get_current_context().find_object(DxsContext)
765
+ record_end(exit_code=0, ctx_extras=_ctx_extras(dxs_ctx))
747
766
  except Exception: # noqa: BLE001
748
767
  pass
749
768
  try:
@@ -105,7 +105,7 @@ def _run_targeted_consent(ctx: DxsContext, resource_key: str) -> None:
105
105
  ),
106
106
  code="DXS-DYNAMICS-CONFIG-001",
107
107
  suggestions=[
108
- "Run: dxs config set dynamics_crm_url https://yourorg.crm.dynamics.com",
108
+ "Run: dxs settings set dynamics_crm_url https://yourorg.crm.dynamics.com",
109
109
  "Then re-run: dxs auth login --consent crm",
110
110
  ],
111
111
  )
@@ -22,6 +22,7 @@ from dxs.core.api import (
22
22
  BranchEndpoints,
23
23
  RepoEndpoints,
24
24
  SourceControlEndpoints,
25
+ fetch_replacements,
25
26
  fetch_settings,
26
27
  )
27
28
  from dxs.core.api.models import (
@@ -1047,7 +1048,7 @@ def search(ctx: DxsContext, query: str, repo: int | None) -> None:
1047
1048
  suggestions=[
1048
1049
  "Use --repo flag: dxs branch search 'query' --repo 10",
1049
1050
  "Set environment variable: export DXS_REPO=10",
1050
- "Set config default: dxs config set default_repo 10",
1051
+ "Set config default: dxs settings set default_repo 10",
1051
1052
  ],
1052
1053
  )
1053
1054
 
@@ -1137,7 +1138,9 @@ def replacements(ctx: DxsContext, branch_id: int) -> None:
1137
1138
  """Show configuration replacements.
1138
1139
 
1139
1140
  Lists all configuration replacements (customizations from component modules)
1140
- for a branch.
1141
+ for a branch. Each entry names the replaced config
1142
+ (``referenceName`` + ``applicationReferenceName``) and the config replacing
1143
+ it (``replacementReferenceName`` + ``replacementApplicationReferenceName``).
1141
1144
 
1142
1145
  \b
1143
1146
  Arguments:
@@ -1150,11 +1153,7 @@ def replacements(ctx: DxsContext, branch_id: int) -> None:
1150
1153
  client = ApiClient()
1151
1154
  ctx.log(f"Fetching replacements for branch {branch_id}...")
1152
1155
 
1153
- replacements_data = client.get(BranchEndpoints.replacements(branch_id))
1154
-
1155
- # Normalize to list if not already
1156
- if not isinstance(replacements_data, list):
1157
- replacements_data = [replacements_data] if replacements_data else []
1156
+ replacements_data = fetch_replacements(client, branch_id)
1158
1157
 
1159
1158
  ctx.output(
1160
1159
  list_response(items=replacements_data, semantic_key="replacements", branch_id=branch_id)
@@ -482,7 +482,7 @@ def execute_cascade_plan(
482
482
  "Check the package's published versions, then resume the remaining "
483
483
  "nodes with 'cascade run --select'.",
484
484
  "If local builds are slow, raise the publish timeout: "
485
- "dxs config set publish_timeout <seconds>.",
485
+ "dxs settings set publish_timeout <seconds>.",
486
486
  ],
487
487
  ) from e
488
488
  new_version: str | None = requested_version