keboola-cli 0.96.1__tar.gz → 0.96.2__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 (607) hide show
  1. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/PKG-INFO +1 -1
  2. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/pyproject.toml +1 -1
  3. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/changelog.py +11 -0
  4. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_password.py +62 -18
  5. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_url_copy.py +5 -0
  6. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/auth.py +3 -3
  7. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/context.py +3 -3
  8. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/data_app.py +13 -2
  9. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/conftest.py +20 -0
  10. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_cli_auth.py +26 -0
  11. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_cli.py +80 -0
  12. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_password.py +141 -1
  13. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_url_copy.py +10 -0
  14. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/package-lock.json +3 -3
  15. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/package.json +1 -1
  16. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/.gitignore +0 -0
  17. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/CLAUDE.md +0 -0
  18. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/CONTRIBUTING.md +0 -0
  19. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/LICENSE +0 -0
  20. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/Makefile +0 -0
  21. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/README.md +0 -0
  22. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/examples/README.md +0 -0
  23. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/examples/storage_tui/README.md +0 -0
  24. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/formal/sync/README.md +0 -0
  25. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
  26. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/plugins/kbagent/skills/kbagent-cicd-migration/scripts/migrate_cicd.py +0 -0
  27. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py +0 -0
  28. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_command_sync.py +0 -0
  29. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_error_codes.py +0 -0
  30. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_file_size.py +0 -0
  31. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_release_scope.py +0 -0
  32. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_sentinel_guards.py +0 -0
  33. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_version_gates.py +0 -0
  34. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_wheel_ui.py +0 -0
  35. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/debug_linkedby_type.sh +0 -0
  36. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/file_size_baseline.json +0 -0
  37. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/gen_command_reference.py +0 -0
  38. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/gen_endpoint_reference.py +0 -0
  39. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/gen_release_notes.py +0 -0
  40. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/generate_changelog.py +0 -0
  41. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/generate_skill.py +0 -0
  42. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/hatch_build.py +0 -0
  43. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/lineage_deep.py +0 -0
  44. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/post-edit-quality.sh +0 -0
  45. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/pre-commit +0 -0
  46. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/sync_version.py +0 -0
  47. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/web-dev.sh +0 -0
  48. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/__init__.py +0 -0
  49. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/__main__.py +0 -0
  50. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/ai_client.py +0 -0
  51. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/__init__.py +0 -0
  52. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/auth_client.py +0 -0
  53. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/device.py +0 -0
  54. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/environment.py +0 -0
  55. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/models.py +0 -0
  56. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/pkce.py +0 -0
  57. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/sentinel.py +0 -0
  58. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/state_store.py +0 -0
  59. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/token_provider.py +0 -0
  60. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/totp.py +0 -0
  61. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auto_update.py +0 -0
  62. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/cli.py +0 -0
  63. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/__init__.py +0 -0
  64. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/_client.py +0 -0
  65. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/_core.py +0 -0
  66. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/_transfer.py +0 -0
  67. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/billing.py +0 -0
  68. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/branches.py +0 -0
  69. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/configs.py +0 -0
  70. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/editor.py +0 -0
  71. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/merge_requests.py +0 -0
  72. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/misc.py +0 -0
  73. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/notifications.py +0 -0
  74. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/query.py +0 -0
  75. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/queue.py +0 -0
  76. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/storage_files.py +0 -0
  77. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/storage_tables.py +0 -0
  78. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/stream.py +0 -0
  79. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/tokens.py +0 -0
  80. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/triggers.py +0 -0
  81. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/workspaces.py +0 -0
  82. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/__init__.py +0 -0
  83. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_auth_picker.py +0 -0
  84. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_checkbox_select.py +0 -0
  85. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_config_clone_cmd.py +0 -0
  86. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_config_oauth.py +0 -0
  87. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_config_trash_cmd.py +0 -0
  88. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
  89. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
  90. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_flow_triggers.py +0 -0
  91. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_helpers.py +0 -0
  92. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_merge_request_common.py +0 -0
  93. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_merge_request_render.py +0 -0
  94. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_merge_request_writes.py +0 -0
  95. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
  96. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_project_create.py +0 -0
  97. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_project_ref.py +0 -0
  98. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
  99. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
  100. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
  101. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_describe.py +0 -0
  102. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
  103. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_table_detail.py +0 -0
  104. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_tables_render.py +0 -0
  105. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_sync_clone_render.py +0 -0
  106. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_sync_push_render.py +0 -0
  107. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/agent.py +0 -0
  108. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/billing.py +0 -0
  109. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/branch.py +0 -0
  110. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/changelog.py +0 -0
  111. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/component.py +0 -0
  112. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/config.py +0 -0
  113. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/config_state.py +0 -0
  114. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
  115. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/docs.py +0 -0
  116. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/doctor.py +0 -0
  117. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/encrypt.py +0 -0
  118. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/feature.py +0 -0
  119. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/flow.py +0 -0
  120. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/http_client.py +0 -0
  121. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/init.py +0 -0
  122. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/job.py +0 -0
  123. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/kai.py +0 -0
  124. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/lineage.py +0 -0
  125. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/merge_request.py +0 -0
  126. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/notification.py +0 -0
  127. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/org.py +0 -0
  128. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/permissions.py +0 -0
  129. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/project.py +0 -0
  130. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/repl.py +0 -0
  131. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/schedule.py +0 -0
  132. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/search.py +0 -0
  133. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
  134. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/serve.py +0 -0
  135. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/sharing.py +0 -0
  136. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/storage.py +0 -0
  137. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/stream.py +0 -0
  138. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/sync.py +0 -0
  139. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/token.py +0 -0
  140. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/transformation.py +0 -0
  141. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/version.py +0 -0
  142. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/workspace.py +0 -0
  143. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/config_store.py +0 -0
  144. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/constants.py +0 -0
  145. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/data_science_client.py +0 -0
  146. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/dev_portal_client.py +0 -0
  147. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/effective_branch.py +0 -0
  148. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/errors.py +0 -0
  149. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/frozen_dist.py +0 -0
  150. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/http_base.py +0 -0
  151. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/json_utils.py +0 -0
  152. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/lib.py +0 -0
  153. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/manage_client.py +0 -0
  154. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/metastore_client.py +0 -0
  155. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/models.py +0 -0
  156. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/output.py +0 -0
  157. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/permissions.py +0 -0
  158. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/project_ref.py +0 -0
  159. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/py.typed +0 -0
  160. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/__init__.py +0 -0
  161. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
  162. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
  163. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
  164. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
  165. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
  166. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/result_models.py +0 -0
  167. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/scheduler_client.py +0 -0
  168. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/__init__.py +0 -0
  169. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/_serve_command_map.py +0 -0
  170. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/agent_runner.py +0 -0
  171. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/agents_store.py +0 -0
  172. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/app.py +0 -0
  173. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/auth.py +0 -0
  174. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/dependencies.py +0 -0
  175. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/pricing.py +0 -0
  176. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
  177. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/agents.py +0 -0
  178. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
  179. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/auth.py +0 -0
  180. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/billing.py +0 -0
  181. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/branches.py +0 -0
  182. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/components.py +0 -0
  183. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/configs.py +0 -0
  184. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/data_apps.py +0 -0
  185. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
  186. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/docs.py +0 -0
  187. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
  188. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/feature.py +0 -0
  189. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/flows.py +0 -0
  190. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/health.py +0 -0
  191. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
  192. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/kai.py +0 -0
  193. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
  194. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/members.py +0 -0
  195. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/merge_requests.py +0 -0
  196. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/notifications.py +0 -0
  197. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/org.py +0 -0
  198. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/projects.py +0 -0
  199. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
  200. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/search.py +0 -0
  201. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
  202. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
  203. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/storage.py +0 -0
  204. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/stream.py +0 -0
  205. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/token.py +0 -0
  206. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
  207. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
  208. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
  209. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/sse.py +0 -0
  210. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/__init__.py +0 -0
  211. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_auth_registration.py +0 -0
  212. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_column_descriptions.py +0 -0
  213. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_config_clone.py +0 -0
  214. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_config_set_guard.py +0 -0
  215. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_config_trash.py +0 -0
  216. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_data_app_bodies.py +0 -0
  217. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_data_app_password.py +0 -0
  218. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_describe_batch_input.py +0 -0
  219. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_encryption.py +0 -0
  220. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
  221. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
  222. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_fqn.py +0 -0
  223. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
  224. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
  225. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
  226. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_storage_tables.py +0 -0
  227. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_baseline.py +0 -0
  228. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
  229. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
  230. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
  231. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
  232. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_clone_warnings.py +0 -0
  233. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_data_app.py +0 -0
  234. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_models.py +0 -0
  235. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
  236. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_stale.py +0 -0
  237. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
  238. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_workspace.py +0 -0
  239. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
  240. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_table_detail.py +0 -0
  241. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_token_last_used.py +0 -0
  242. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
  243. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_workspace_load_plan.py +0 -0
  244. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/agent_service.py +0 -0
  245. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/auth_service.py +0 -0
  246. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/base.py +0 -0
  247. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/billing_service.py +0 -0
  248. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/branch_service.py +0 -0
  249. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/component_service.py +0 -0
  250. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/config_service.py +0 -0
  251. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
  252. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/data_app_service.py +0 -0
  253. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
  254. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
  255. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/docs_service.py +0 -0
  256. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/doctor_service.py +0 -0
  257. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
  258. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/feature_service.py +0 -0
  259. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/flow_service.py +0 -0
  260. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/flow_validation.py +0 -0
  261. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
  262. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
  263. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/job_service.py +0 -0
  264. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/kai_service.py +0 -0
  265. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/lineage_service.py +0 -0
  266. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/member_service.py +0 -0
  267. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/merge_request_service.py +0 -0
  268. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/notification_service.py +0 -0
  269. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/org_service.py +0 -0
  270. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/project_service.py +0 -0
  271. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
  272. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/schedule_service.py +0 -0
  273. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/search_service.py +0 -0
  274. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
  275. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/sharing_service.py +0 -0
  276. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
  277. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/storage_service.py +0 -0
  278. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/stream_service.py +0 -0
  279. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/sync_service.py +0 -0
  280. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/table_usage.py +0 -0
  281. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/token_service.py +0 -0
  282. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/transformation_service.py +0 -0
  283. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/variables_service.py +0 -0
  284. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/version_service.py +0 -0
  285. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/workspace_service.py +0 -0
  286. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/stream_client.py +0 -0
  287. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/__init__.py +0 -0
  288. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
  289. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/branch_registry.py +0 -0
  290. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/branch_scope.py +0 -0
  291. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/clone.py +0 -0
  292. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
  293. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/config_format.py +0 -0
  294. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
  295. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/git_utils.py +0 -0
  296. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/manifest.py +0 -0
  297. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/naming.py +0 -0
  298. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/secrets.py +0 -0
  299. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/sql_split.py +0 -0
  300. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/telemetry.py +0 -0
  301. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/update_runner.py +0 -0
  302. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/yaml_input.py +0 -0
  303. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/__init__.py +0 -0
  304. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/helpers.py +0 -0
  305. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_cli.py +0 -0
  306. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_prompt.py +0 -0
  307. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_prompt_helper.py +0 -0
  308. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_runner.py +0 -0
  309. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_service.py +0 -0
  310. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_tombstone.py +0 -0
  311. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agents_store_events.py +0 -0
  312. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_ai_client.py +0 -0
  313. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_api_call_counts.py +0 -0
  314. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_client.py +0 -0
  315. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_device.py +0 -0
  316. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_environment.py +0 -0
  317. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_models.py +0 -0
  318. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_picker.py +0 -0
  319. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_pkce.py +0 -0
  320. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_register_projects.py +0 -0
  321. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_sentinel.py +0 -0
  322. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_sentinel_guards.py +0 -0
  323. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_service.py +0 -0
  324. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_state_store.py +0 -0
  325. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_totp.py +0 -0
  326. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auto_update.py +0 -0
  327. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_base_service.py +0 -0
  328. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_billing_cli.py +0 -0
  329. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_billing_client.py +0 -0
  330. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_billing_service.py +0 -0
  331. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_metadata_cli.py +0 -0
  332. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_metadata_service.py +0 -0
  333. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_registry.py +0 -0
  334. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_service.py +0 -0
  335. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_build_hook.py +0 -0
  336. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_changelog_check.py +0 -0
  337. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_changelog_render.py +0 -0
  338. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_command_sync.py +0 -0
  339. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_file_size.py +0 -0
  340. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_release_scope.py +0 -0
  341. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_sentinel_guards.py +0 -0
  342. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_version_gates.py +0 -0
  343. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_checkbox_select.py +0 -0
  344. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_choice_enums.py +0 -0
  345. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_cli.py +0 -0
  346. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_client.py +0 -0
  347. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_client_device_enrollment.py +0 -0
  348. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_client_token_events.py +0 -0
  349. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_component_cli.py +0 -0
  350. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_component_service.py +0 -0
  351. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_component_sync_action.py +0 -0
  352. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_clone_cli.py +0 -0
  353. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_clone_service.py +0 -0
  354. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_create_cli.py +0 -0
  355. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_create_service.py +0 -0
  356. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_encryption.py +0 -0
  357. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_examples.py +0 -0
  358. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_metadata.py +0 -0
  359. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_rename.py +0 -0
  360. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_rename_cli.py +0 -0
  361. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_resolution.py +0 -0
  362. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_row_cli.py +0 -0
  363. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_row_service.py +0 -0
  364. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_search.py +0 -0
  365. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_search_cli.py +0 -0
  366. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_set_default_bucket.py +0 -0
  367. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_set_guard.py +0 -0
  368. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_state.py +0 -0
  369. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_store.py +0 -0
  370. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_trash.py +0 -0
  371. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_update.py +0 -0
  372. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_git_repo.py +0 -0
  373. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_plain_env_keys.py +0 -0
  374. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_secrets_cli.py +0 -0
  375. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_secrets_service.py +0 -0
  376. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_service.py +0 -0
  377. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_validate_repo_service.py +0 -0
  378. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_deep_lineage_service.py +0 -0
  379. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_dev_portal_cli.py +0 -0
  380. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_dev_portal_client.py +0 -0
  381. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_dev_portal_service.py +0 -0
  382. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_docs_cli.py +0 -0
  383. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_doctor_service.py +0 -0
  384. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e.py +0 -0
  385. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e_auth.py +0 -0
  386. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e_config_dir_mode.py +0 -0
  387. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e_lineage_deep.py +0 -0
  388. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_effective_branch.py +0 -0
  389. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_encrypt_cli.py +0 -0
  390. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_encrypt_service.py +0 -0
  391. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_encryption.py +0 -0
  392. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_errors.py +0 -0
  393. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_feature_cli.py +0 -0
  394. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_feature_service.py +0 -0
  395. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_file_locking.py +0 -0
  396. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_cli.py +0 -0
  397. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_examples.py +0 -0
  398. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_service.py +0 -0
  399. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_validation.py +0 -0
  400. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_frozen_dist.py +0 -0
  401. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_gen_command_reference.py +0 -0
  402. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_gen_endpoint_reference.py +0 -0
  403. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_gen_release_notes.py +0 -0
  404. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_generate_promotion_pipeline.py +0 -0
  405. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_helpers.py +0 -0
  406. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_base.py +0 -0
  407. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_base_auth.py +0 -0
  408. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_client_cmd.py +0 -0
  409. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_forwarder_service.py +0 -0
  410. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_integration.py +0 -0
  411. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_job_idempotency_store.py +0 -0
  412. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_job_options.py +0 -0
  413. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_json_utils.py +0 -0
  414. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_kai_cli.py +0 -0
  415. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_kai_service.py +0 -0
  416. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_lib.py +0 -0
  417. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_lib_device_enrollment.py +0 -0
  418. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_license_consistency.py +0 -0
  419. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_lineage_service.py +0 -0
  420. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_local_ai_chat.py +0 -0
  421. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_manage_client.py +0 -0
  422. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_manage_token_bulk.py +0 -0
  423. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_manage_token_cli.py +0 -0
  424. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_mcp_migration_recipe.py +0 -0
  425. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_member_cli.py +0 -0
  426. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_member_service.py +0 -0
  427. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_merge_request_cli.py +0 -0
  428. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_merge_request_client.py +0 -0
  429. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_merge_request_service.py +0 -0
  430. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_metastore_client.py +0 -0
  431. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_migrate_cicd.py +0 -0
  432. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_models.py +0 -0
  433. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_normalize_script.py +0 -0
  434. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_notification_cli.py +0 -0
  435. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_notification_client.py +0 -0
  436. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_notification_service.py +0 -0
  437. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_org_service.py +0 -0
  438. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_output.py +0 -0
  439. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_permissions.py +0 -0
  440. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_permissions_cli.py +0 -0
  441. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_pricing.py +0 -0
  442. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_create_cli.py +0 -0
  443. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_edit.py +0 -0
  444. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_edit_cli.py +0 -0
  445. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_info_cli.py +0 -0
  446. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_info_service.py +0 -0
  447. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_ref.py +0 -0
  448. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_release_kbagent_ai_kit_sync.py +0 -0
  449. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_repl.py +0 -0
  450. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_result_models.py +0 -0
  451. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_run_broadcaster.py +0 -0
  452. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_schedule_cli.py +0 -0
  453. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_schedule_service.py +0 -0
  454. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_scheduler_client.py +0 -0
  455. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_search_cli.py +0 -0
  456. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_search_service.py +0 -0
  457. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_semantic_layer_cli.py +0 -0
  458. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_semantic_layer_schema.py +0 -0
  459. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_semantic_layer_service.py +0 -0
  460. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_banner_encoding.py +0 -0
  461. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_conversation_id.py +0 -0
  462. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_telemetry.py +0 -0
  463. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_ui.py +0 -0
  464. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_auth.py +0 -0
  465. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_permissions.py +0 -0
  466. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_project_ref.py +0 -0
  467. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_router_calls.py +0 -0
  468. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
  469. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_smoke.py +0 -0
  470. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_services.py +0 -0
  471. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sharing_cli.py +0 -0
  472. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sharing_service.py +0 -0
  473. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_skill_frontmatter.py +0 -0
  474. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sql_split.py +0 -0
  475. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_clone.py +0 -0
  476. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_create_table.py +0 -0
  477. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_delete.py +0 -0
  478. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_describe_cli.py +0 -0
  479. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_describe_service.py +0 -0
  480. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_empty_definition.py +0 -0
  481. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_export_filters.py +0 -0
  482. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_files.py +0 -0
  483. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_snapshots.py +0 -0
  484. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_swap.py +0 -0
  485. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_table_definition.py +0 -0
  486. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_tables.py +0 -0
  487. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_truncate.py +0 -0
  488. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_write.py +0 -0
  489. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_stream_cli.py +0 -0
  490. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_stream_client.py +0 -0
  491. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_stream_service.py +0 -0
  492. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_baseline_stamping.py +0 -0
  493. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_branch_mapping.py +0 -0
  494. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_branch_scope.py +0 -0
  495. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_cli.py +0 -0
  496. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_cli_behavior.py +0 -0
  497. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_clone.py +0 -0
  498. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_clone_links.py +0 -0
  499. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_code_extraction.py +0 -0
  500. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_config_format.py +0 -0
  501. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_data_app_type.py +0 -0
  502. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_diff_engine.py +0 -0
  503. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_e2e.py +0 -0
  504. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_encrypt.py +0 -0
  505. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_force_pull_baseline.py +0 -0
  506. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_formal_counterexamples.py +0 -0
  507. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_manifest.py +0 -0
  508. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_naming.py +0 -0
  509. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_plaintext_audit.py +0 -0
  510. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_pull_companion_files.py +0 -0
  511. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_push_script_guard.py +0 -0
  512. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_reconcile.py +0 -0
  513. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_secrets.py +0 -0
  514. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_service.py +0 -0
  515. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_storage_jobs.py +0 -0
  516. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_version_script.py +0 -0
  517. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_workspaces.py +0 -0
  518. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_table_usage.py +0 -0
  519. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_telemetry.py +0 -0
  520. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_token_cli.py +0 -0
  521. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_token_provider.py +0 -0
  522. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_token_service.py +0 -0
  523. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_transformation_cli.py +0 -0
  524. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_transformation_ops.py +0 -0
  525. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_triggers_client.py +0 -0
  526. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_update_runner.py +0 -0
  527. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_variables_cli.py +0 -0
  528. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_variables_service.py +0 -0
  529. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_version_service.py +0 -0
  530. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_cli.py +0 -0
  531. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_gc.py +0 -0
  532. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_service.py +0 -0
  533. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_sql_helper.py +0 -0
  534. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_yaml_input.py +0 -0
  535. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/README.md +0 -0
  536. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/index.html +0 -0
  537. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/postcss.config.js +0 -0
  538. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/App.tsx +0 -0
  539. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/api/client.test.ts +0 -0
  540. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/api/client.ts +0 -0
  541. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/changelogNotes.test.ts +0 -0
  542. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/changelogNotes.ts +0 -0
  543. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/AgentRunView.tsx +0 -0
  544. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/CommandPalette.tsx +0 -0
  545. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/ConfirmModal.tsx +0 -0
  546. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/DetailTabs.tsx +0 -0
  547. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/Drawer.tsx +0 -0
  548. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/Empty.tsx +0 -0
  549. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/JsonView.tsx +0 -0
  550. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/KeyValueGrid.tsx +0 -0
  551. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
  552. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/PillList.tsx +0 -0
  553. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/RawDetail.tsx +0 -0
  554. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/SessionExpiredBanner.tsx +0 -0
  555. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/Table.tsx +0 -0
  556. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/WhatsNew.tsx +0 -0
  557. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/config/credits.test.ts +0 -0
  558. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/config/credits.ts +0 -0
  559. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/index.css +0 -0
  560. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/Shell.tsx +0 -0
  561. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/Sidebar.tsx +0 -0
  562. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/StatusBar.tsx +0 -0
  563. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/TopBar.tsx +0 -0
  564. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/lib/time.test.ts +0 -0
  565. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/lib/time.ts +0 -0
  566. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/main.tsx +0 -0
  567. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Agents.tsx +0 -0
  568. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Branches.tsx +0 -0
  569. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Changelog.tsx +0 -0
  570. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Components.tsx +0 -0
  571. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Configs.tsx +0 -0
  572. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Dashboard.tsx +0 -0
  573. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/DataApps.tsx +0 -0
  574. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Doctor.tsx +0 -0
  575. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Encrypt.tsx +0 -0
  576. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Flows.tsx +0 -0
  577. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Jobs.tsx +0 -0
  578. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/JobsAll.tsx +0 -0
  579. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Lineage.tsx +0 -0
  580. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/LocalAi.tsx +0 -0
  581. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Members.tsx +0 -0
  582. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Org.tsx +0 -0
  583. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Projects.tsx +0 -0
  584. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Schedules.tsx +0 -0
  585. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Search.tsx +0 -0
  586. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
  587. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
  588. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Sharing.tsx +0 -0
  589. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Storage.tsx +0 -0
  590. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Streams.tsx +0 -0
  591. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Tokens.tsx +0 -0
  592. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/TokensAll.tsx +0 -0
  593. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Workspaces.tsx +0 -0
  594. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/jobsShared.tsx +0 -0
  595. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/storageSel.test.ts +0 -0
  596. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/tokensShared.test.ts +0 -0
  597. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/tokensShared.tsx +0 -0
  598. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/router.test.ts +0 -0
  599. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/router.ts +0 -0
  600. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/state.tsx +0 -0
  601. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/theme.tsx +0 -0
  602. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/types.ts +0 -0
  603. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/useHashSelection.ts +0 -0
  604. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/whatsnew.ts +0 -0
  605. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/tailwind.config.ts +0 -0
  606. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/tsconfig.json +0 -0
  607. {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/vite.config.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: keboola-cli
3
- Version: 0.96.1
3
+ Version: 0.96.2
4
4
  Summary: AI-friendly CLI for managing Keboola projects
5
5
  Author-email: Keboola <dev@keboola.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "keboola-cli"
3
- version = "0.96.1"
3
+ version = "0.96.2"
4
4
  description = "AI-friendly CLI for managing Keboola projects"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -26,6 +26,17 @@ from .constants import CHANGELOG_HEADLINE_MAX_CHARS
26
26
 
27
27
  # Ordered newest-first. Each value is a list of brief one-line descriptions.
28
28
  CHANGELOG: dict[str, list[str]] = {
29
+ "0.96.2": [
30
+ "Fix (#825): the `data-app` commands now label the app link `Open the app:` and the "
31
+ "Keboola UI link `Configuration:`, so it is clear which link opens what. Before, the "
32
+ "labels were `App URL:` and `UI URL:`, or only `URL:` in `data-app detail` and "
33
+ "`data-app create`. In a terminal, `data-app password`, `create --wait` and "
34
+ "`deploy --wait` show the links in a panel that looks like the `auth login` device-code "
35
+ "panel. Outside a terminal, the output stays plain lines without a panel. The `--json` "
36
+ "output does not change.",
37
+ "Note (#819, #820, #822, #823): housekeeping with no user-facing change. Dependency "
38
+ "updates in the web UI and its backend (fast-uri, brace-expansion, fastify, dompurify).",
39
+ ],
29
40
  "0.96.1": [
30
41
  "BREAKING (#813): `kbagent data-app password` no longer prints the password unless "
31
42
  "you pass `--reveal`. When an AI agent ran the command, the password went into the model "
@@ -33,6 +33,7 @@ from typing import Annotated, Any, NoReturn
33
33
  import typer
34
34
  from rich.console import Console
35
35
  from rich.markup import escape
36
+ from rich.panel import Panel
36
37
  from rich.text import Text
37
38
 
38
39
  from ..auth import environment
@@ -51,11 +52,12 @@ DELIVERED_TO_STDOUT = "stdout"
51
52
  _BROWSER_OPEN_WAIT_SECONDS = 2.0
52
53
 
53
54
  _COPY_PROMPT_TIMEOUT_SECONDS = 120.0
55
+ _PANEL_TITLE = "Data app password"
54
56
  _COPY_PROMPT_HINT = "Press c to copy the password, Enter to finish"
55
57
  # Enter arrives as "\n" in cbreak mode on POSIX and as "\r" from msvcrt on Windows.
56
58
  _COPY_PROMPT_FINISH_KEYS = frozenset({"\n", "\r", "\x1b", "q"})
57
- # The terminal flow prints the UI URL itself, so its lines only refer to it.
58
- _UI_URL_SHOWS_IT = "The UI URL shows it under Open App after login."
59
+ # The terminal flow prints the Configuration link itself, so its lines only refer to it.
60
+ _UI_URL_SHOWS_IT = "The Configuration page shows it under Open App after login."
59
61
 
60
62
  # -- Shared options: one definition for `password`, `create` and `deploy` -------
61
63
 
@@ -206,29 +208,67 @@ def _non_interactive_message(
206
208
  )
207
209
 
208
210
 
209
- def _print_line(console: Console, *parts: str | tuple[str, str]) -> None:
211
+ def _print_line(console: Console, *parts: str | Text | tuple[str, str]) -> None:
210
212
  """One line of plain text parts: no markup parsing, no highlighting, and a
211
213
  URL in it is never folded (non-TTY consoles wrap at 80 columns)."""
212
214
  console.print(Text.assemble(*parts), highlight=False, soft_wrap=True)
213
215
 
214
216
 
215
- def _print_links(console: Console, *, app_url: str, ui_url: str | None, app_opened: bool) -> None:
216
- _print_line(console, (" App URL:", "bold"), f" {app_url or '-'}")
217
- _print_line(console, (" UI URL:", "bold"), f" {ui_url or '-'}")
217
+ def _print_password_block(
218
+ console: Console,
219
+ status: Text,
220
+ *,
221
+ app_url: str,
222
+ ui_url: str | None,
223
+ app_opened: bool,
224
+ password: str | None = None,
225
+ ) -> None:
226
+ """The status line, the two links and (``--reveal``) the password.
227
+
228
+ In a terminal they go in a panel laid out like the device-login one: a
229
+ plain label, a blank line, the link. Anywhere else (a pipe, a CI log, an
230
+ agent) they stay plain lines, so a URL is never folded and never carries
231
+ a panel border.
232
+ """
233
+ app_link = (app_url, _url_copy.LINK_STYLE) if app_url else "-"
234
+ # The app link is the one to open, so only it gets the link color.
235
+ ui_link = (ui_url, "bold") if ui_url else "-"
236
+ password_part = (password or "", "bold yellow")
237
+ if console.is_terminal:
238
+ parts: list[str | Text | tuple[str, str]] = [
239
+ status,
240
+ "\n\nOpen the app:\n\n",
241
+ app_link,
242
+ "\n\nConfiguration:\n\n",
243
+ ui_link,
244
+ ]
245
+ if app_opened:
246
+ parts.append("\n\nOpened the app in the browser.")
247
+ if password is not None:
248
+ parts += ["\n\nPassword: ", password_part]
249
+ console.print(Panel(Text.assemble(*parts), title=_PANEL_TITLE, expand=False))
250
+ return
251
+ _print_line(console, status)
252
+ _print_line(console, (" Open the app:", "bold"), " ", app_link)
253
+ _print_line(console, (" Configuration:", "bold"), " ", ui_link)
218
254
  if app_opened:
219
255
  console.print(" Opened the app in the browser.")
256
+ if password is not None:
257
+ _print_line(console, "\nPassword: ", password_part)
220
258
 
221
259
 
222
260
  def _print_result(console: Console, data: dict[str, Any]) -> None:
223
261
  label = (
224
262
  ("Success:", "bold green") if data["password_delivered_to"] else ("Warning:", "bold yellow")
225
263
  )
226
- _print_line(console, label, f" {data['message']}")
227
- _print_links(
228
- console, app_url=data["app_url"], ui_url=data["ui_url"], app_opened=data["app_opened"]
264
+ _print_password_block(
265
+ console,
266
+ Text.assemble(label, f" {data['message']}"),
267
+ app_url=data["app_url"],
268
+ ui_url=data["ui_url"],
269
+ app_opened=data["app_opened"],
270
+ password=data.get("password"),
229
271
  )
230
- if "password" in data:
231
- _print_line(console, ("\nPassword:", "bold yellow"), f" {data['password']}")
232
272
 
233
273
 
234
274
  def _copy_on_keypress(console: Console, lookup: DataAppPassword, *, app_opened: bool) -> bool:
@@ -239,15 +279,19 @@ def _copy_on_keypress(console: Console, lookup: DataAppPassword, *, app_opened:
239
279
  hint=_COPY_PROMPT_HINT,
240
280
  finish_keys=_COPY_PROMPT_FINISH_KEYS,
241
281
  )
242
- if not wait.enabled:
243
- console.print(
244
- f"[bold yellow]Warning:[/bold yellow] No clipboard tool was found, so the password "
245
- f"of data app {escape(lookup.app_id)} cannot be copied. {_UI_URL_SHOWS_IT}"
282
+ if wait.enabled:
283
+ status = Text(f"The password of data app {lookup.app_id} is ready to copy.")
284
+ else:
285
+ status = Text.assemble(
286
+ ("Warning:", "bold yellow"),
287
+ f" No clipboard tool was found, so the password of data app {lookup.app_id} "
288
+ f"cannot be copied. {_UI_URL_SHOWS_IT}",
246
289
  )
247
- _print_links(console, app_url=lookup.app_url, ui_url=lookup.ui_url, app_opened=app_opened)
290
+ _print_password_block(
291
+ console, status, app_url=lookup.app_url, ui_url=lookup.ui_url, app_opened=app_opened
292
+ )
293
+ if not wait.enabled:
248
294
  return False
249
- console.print(f"The password of data app {escape(lookup.app_id)} is ready to copy.")
250
- _print_links(console, app_url=lookup.app_url, ui_url=lookup.ui_url, app_opened=app_opened)
251
295
  wait.prompt_and_wait(lookup.password, _COPY_PROMPT_TIMEOUT_SECONDS)
252
296
  if wait.copied:
253
297
  return True
@@ -28,6 +28,11 @@ from rich.console import Console
28
28
 
29
29
  _POSIX = sys.platform != "win32"
30
30
 
31
+ # Rich style of the main link the user opens. The device-login panel
32
+ # (commands/auth.py) and the data-app app link (commands/data_app.py,
33
+ # commands/_data_app_password.py) share this one definition.
34
+ LINK_STYLE = "bold cyan"
35
+
31
36
  # A clipboard command that hangs (e.g. xclip waiting on an unreachable X
32
37
  # display) must not hang the command that called it.
33
38
  _CLIPBOARD_TIMEOUT_SECONDS = 5.0
@@ -54,7 +54,7 @@ from ._helpers import (
54
54
  map_error_to_exit_code,
55
55
  read_password_stdin,
56
56
  )
57
- from ._url_copy import CopyableUrlWait
57
+ from ._url_copy import LINK_STYLE, CopyableUrlWait
58
58
 
59
59
  auth_app = typer.Typer(
60
60
  help="Programmatic browser login (PKCE / device code) -- user-scoped sessions"
@@ -311,7 +311,7 @@ def _device_login_panel(authorization: DeviceAuthorization) -> Panel:
311
311
  lines = [
312
312
  "Open this link to finish signing in (code already filled in):",
313
313
  "",
314
- f"[bold cyan]{escape(complete)}[/bold cyan]",
314
+ f"[{LINK_STYLE}]{escape(complete)}[/{LINK_STYLE}]",
315
315
  "",
316
316
  "Or enter the code by hand at this URL:",
317
317
  "",
@@ -323,7 +323,7 @@ def _device_login_panel(authorization: DeviceAuthorization) -> Panel:
323
323
  lines = [
324
324
  "Open this URL and enter the code to finish signing in:",
325
325
  "",
326
- f"[bold cyan]{escape(authorization.verification_uri)}[/bold cyan]",
326
+ f"[{LINK_STYLE}]{escape(authorization.verification_uri)}[/{LINK_STYLE}]",
327
327
  "",
328
328
  f"Code: [bold yellow]{escape(authorization.user_code)}[/bold yellow]",
329
329
  ]
@@ -1460,9 +1460,9 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
1460
1460
  Give the user the password of a password-protected app WITHOUT printing
1461
1461
  it (0.96.1+; older versions printed it and needed a Manage API token).
1462
1462
  Project token only (static or session), no Manage token. In a terminal
1463
- (human mode, stdin + stdout a TTY, not a background job) it shows the app
1464
- URL and `ui_url`, then waits: `c` copies the password, Enter / Esc / q
1465
- finishes, 120 s timeout.
1463
+ (human mode, stdin + stdout a TTY, not a background job) it prints the
1464
+ links `Open the app:` (`app_url`) and `Configuration:` (`ui_url`), then
1465
+ waits: `c` copies the password, Enter / Esc / q finishes, 120 s timeout.
1466
1466
  Without a terminal or with --json there is no prompt: only --copy copies
1467
1467
  it (the clipboard tool gets it on stdin). Nothing copied -> exit 0 with
1468
1468
  `password_delivered_to: null`; `ui_url` is the Keboola UI page that shows
@@ -41,6 +41,7 @@ from ._helpers import (
41
41
  get_service,
42
42
  map_error_to_exit_code,
43
43
  )
44
+ from ._url_copy import LINK_STYLE
44
45
 
45
46
  # Canonical Keboola help-doc references appended to each --help epilog so
46
47
  # operators have a one-click path to the rule a flag enforces.
@@ -198,7 +199,12 @@ def data_app_detail(
198
199
  ),
199
200
  c.print(f" [bold]Size:[/bold] {d.get('size', '')}"),
200
201
  c.print(f" [bold]Auto-suspend:[/bold] {d.get('auto_suspend_after_seconds', '?')}s"),
201
- c.print(f" [bold]URL:[/bold] {d.get('url', '')}"),
202
+ c.print(
203
+ f" [bold]Open the app:[/bold] "
204
+ f"[{LINK_STYLE}]{escape(d.get('url') or '')}[/{LINK_STYLE}]",
205
+ highlight=False,
206
+ soft_wrap=True,
207
+ ),
202
208
  c.print(f" [bold]Last started:[/bold] {d.get('last_start_timestamp', '')}"),
203
209
  c.print(f" [bold]Git:[/bold] {d.get('git', {})}"),
204
210
  ),
@@ -238,7 +244,12 @@ def _print_create_result(console: Console, result: dict[str, Any]) -> None:
238
244
  "not be injected; an app that reads Storage will serve no data"
239
245
  )
240
246
  if result.get("url"):
241
- console.print(f" [bold]URL:[/bold] {result['url']}")
247
+ console.print(
248
+ f" [bold]Open the app:[/bold] "
249
+ f"[{LINK_STYLE}]{escape(result['url'])}[/{LINK_STYLE}]",
250
+ highlight=False,
251
+ soft_wrap=True,
252
+ )
242
253
  console.print(
243
254
  f" [bold]State:[/bold] {result.get('state', '?')} "
244
255
  f"(desired={result.get('desired_state', '?')})"
@@ -1,9 +1,12 @@
1
1
  """Shared test fixtures for Keboola Agent CLI tests."""
2
2
 
3
3
  from pathlib import Path
4
+ from typing import Any
4
5
 
5
6
  import pytest
7
+ from rich.console import Console
6
8
 
9
+ from keboola_agent_cli import output
7
10
  from keboola_agent_cli.config_store import ConfigStore
8
11
  from keboola_agent_cli.output import OutputFormatter
9
12
 
@@ -21,6 +24,23 @@ def _deterministic_console_width(monkeypatch: pytest.MonkeyPatch) -> None:
21
24
  monkeypatch.setenv("COLUMNS", "200")
22
25
 
23
26
 
27
+ @pytest.fixture
28
+ def force_colour(monkeypatch: pytest.MonkeyPatch) -> None:
29
+ """Make the CLI print ANSI colour codes under ``CliRunner``.
30
+
31
+ ``OutputFormatter`` turns the terminal off when stdout is not a TTY, and
32
+ ``CliRunner`` is not one, so a test that pins a Rich style would otherwise
33
+ only see plain text.
34
+ """
35
+ real_console = output.Console
36
+
37
+ def _colour_console(**kwargs: Any) -> Console:
38
+ kwargs.update(force_terminal=True, color_system="standard", no_color=False)
39
+ return real_console(**kwargs)
40
+
41
+ monkeypatch.setattr(output, "Console", _colour_console)
42
+
43
+
24
44
  @pytest.fixture(autouse=True)
25
45
  def _clear_updated_from(monkeypatch: pytest.MonkeyPatch) -> None:
26
46
  """Prevent auto-update changelog leaking between tests."""
@@ -247,6 +247,32 @@ class TestLogin:
247
247
  assert "Or enter the code by hand at this URL:" in result.output
248
248
  assert "https://connection.keboola.com/device?user_code=ABCD-EFGH" in result.output
249
249
 
250
+ def test_device_login_panel_colours(self, tmp_path: Path, force_colour) -> None:
251
+ """The link is bold cyan, the plain URL bold, the code bold yellow.
252
+
253
+ `data-app` prints its app link in the same bold cyan (`LINK_STYLE`).
254
+ """
255
+ config_dir = tmp_path / "c"
256
+ config_dir.mkdir()
257
+ svc = MagicMock()
258
+ self._fire_device_prompt(
259
+ svc,
260
+ DeviceAuthorization(
261
+ deviceCode="device-code-1",
262
+ userCode="ABCD-EFGH",
263
+ verificationUri="https://connection.keboola.com/device",
264
+ verificationUriComplete=(
265
+ "https://connection.keboola.com/device?user_code=ABCD-EFGH"
266
+ ),
267
+ ),
268
+ )
269
+ result = _invoke(config_dir, svc, ["auth", "login", "--device-code"])
270
+ assert result.exit_code == 0, result.output
271
+ link = "https://connection.keboola.com/device?user_code=ABCD-EFGH"
272
+ assert f"\x1b[1;36m{link}\x1b[0m" in result.output
273
+ assert "\x1b[1mhttps://connection.keboola.com/device\x1b[0m" in result.output
274
+ assert "\x1b[1;33mABCD-EFGH\x1b[0m" in result.output
275
+
250
276
  def test_device_login_panel_omits_one_click_link_when_absent(self, tmp_path: Path) -> None:
251
277
  config_dir = tmp_path / "c"
252
278
  config_dir.mkdir()
@@ -419,6 +419,86 @@ class TestDataAppCreateValidation:
419
419
  assert "DRY RUN" in result.output
420
420
 
421
421
 
422
+ # ---------------------------------------------------------------------------
423
+ # data-app detail / create -- the link to the running app
424
+ # ---------------------------------------------------------------------------
425
+
426
+ APP_URL = "https://x.hub.example.com"
427
+ BOLD_CYAN = "\x1b[1;36m" # the style of the `auth login --device-code` link
428
+ RESET = "\x1b[0m"
429
+
430
+
431
+ class TestDataAppLinkOutput:
432
+ def _detail(self, tmp_path: Path) -> Any:
433
+ config_dir = tmp_path / "config"
434
+ config_dir.mkdir()
435
+ store = _setup_config(config_dir, {"prod": {"token": TEST_TOKEN}})
436
+ mock = MagicMock()
437
+ mock.get_data_app.return_value = {
438
+ "project_alias": "prod",
439
+ "app_id": "42",
440
+ "name": "App",
441
+ "url": APP_URL,
442
+ }
443
+ return _invoke(
444
+ ["data-app", "detail", "--project", "prod", "--app-id", "42"],
445
+ store=store,
446
+ data_app_mock=mock,
447
+ )
448
+
449
+ def _create(self, tmp_path: Path) -> Any:
450
+ config_dir = tmp_path / "config"
451
+ config_dir.mkdir()
452
+ store = _setup_config(config_dir, {"prod": {"token": TEST_TOKEN}})
453
+ mock = MagicMock()
454
+ mock.create_data_app.return_value = {
455
+ "app_id": "42",
456
+ "config_id": "ulid",
457
+ "workspace": True,
458
+ "url": APP_URL,
459
+ "state": "created",
460
+ "desired_state": "stopped",
461
+ "message": "created",
462
+ }
463
+ return _invoke(
464
+ [
465
+ "data-app",
466
+ "create",
467
+ "--project",
468
+ "prod",
469
+ "--name",
470
+ "App",
471
+ "--slug",
472
+ "my-app",
473
+ "--git-repo",
474
+ "https://github.com/o/r",
475
+ "--git-public",
476
+ "--auth",
477
+ "public",
478
+ "--no-deploy",
479
+ ],
480
+ store=store,
481
+ data_app_mock=mock,
482
+ )
483
+
484
+ @pytest.mark.parametrize("command", ["_detail", "_create"])
485
+ def test_app_link_is_labelled_by_what_it_opens(self, tmp_path: Path, command: str) -> None:
486
+ result = getattr(self, command)(tmp_path)
487
+
488
+ assert result.exit_code == 0, result.output
489
+ assert f"Open the app: {APP_URL}" in result.output
490
+ assert " URL:" not in result.output
491
+
492
+ @pytest.mark.parametrize("command", ["_detail", "_create"])
493
+ def test_app_link_is_bold_cyan_like_the_device_login_link(
494
+ self, tmp_path: Path, force_colour, command: str
495
+ ) -> None:
496
+ result = getattr(self, command)(tmp_path)
497
+
498
+ assert result.exit_code == 0, result.output
499
+ assert f"{BOLD_CYAN}{APP_URL}{RESET}" in result.output
500
+
501
+
422
502
  # ---------------------------------------------------------------------------
423
503
  # data-app deploy
424
504
  # ---------------------------------------------------------------------------
@@ -20,6 +20,7 @@ from __future__ import annotations
20
20
  import json
21
21
  import logging
22
22
  import os
23
+ import re
23
24
  import select
24
25
  import subprocess
25
26
  import sys
@@ -67,6 +68,14 @@ CONFIG_URL = "https://connection.keboola.com/v2/storage/components/keboola.data-
67
68
  APP_URL = "https://app-42.hub.keboola.com"
68
69
  UI_URL = "https://connection.keboola.com/admin/projects/258/branch/default/data-apps/cfg-1"
69
70
 
71
+ # Rich styles of the `auth login --device-code` panel: its link, its plain
72
+ # URL, its code value and its hint.
73
+ BOLD_CYAN = "\x1b[1;36m"
74
+ BOLD = "\x1b[1m"
75
+ BOLD_YELLOW = "\x1b[1;33m"
76
+ CYAN = "\x1b[36m"
77
+ RESET = "\x1b[0m"
78
+
70
79
 
71
80
  class _Clipboard:
72
81
  """Fake copier returned by the patched ``detect_clipboard``."""
@@ -161,6 +170,14 @@ def _telemetry_payload(argv: list[str], result: Result, monkeypatch: pytest.Monk
161
170
  return repr(sent)
162
171
 
163
172
 
173
+ def _assert_labelled_links(output: str) -> None:
174
+ """The app link and the configuration page, named by what each one opens."""
175
+ assert f"Open the app: {APP_URL}" in output
176
+ assert f"Configuration: {UI_URL}" in output
177
+ assert "App URL" not in output
178
+ assert "UI URL" not in output
179
+
180
+
164
181
  def _assert_no_leak(
165
182
  argv: list[str],
166
183
  result: Result,
@@ -211,6 +228,17 @@ class TestWithoutTerminal:
211
228
  "message": data["message"],
212
229
  }
213
230
 
231
+ @pytest.mark.parametrize("flags", [(), ("--reveal",)])
232
+ def test_human_output_labels_the_two_links(
233
+ self, config_dir, httpx_mock, caplog, flags: tuple[str, ...]
234
+ ) -> None:
235
+ _mock_api(httpx_mock)
236
+
237
+ result = _run(_argv(config_dir, *flags, json_mode=False), caplog)
238
+
239
+ assert result.exit_code == 0, result.output
240
+ _assert_labelled_links(result.stdout)
241
+
214
242
  @pytest.mark.parametrize("json_mode", [True, False])
215
243
  def test_copy_puts_the_password_on_the_clipboard(
216
244
  self, config_dir, httpx_mock, caplog, monkeypatch, json_mode: bool
@@ -289,6 +317,16 @@ class TestTerminalPrompt:
289
317
  assert "not copied" not in result.stdout
290
318
  _assert_no_leak(argv, result, caplog, monkeypatch)
291
319
 
320
+ def test_prompt_labels_the_two_links(self, config_dir, httpx_mock, caplog, monkeypatch) -> None:
321
+ _mock_api(httpx_mock)
322
+ _clipboard(monkeypatch)
323
+ _terminal(monkeypatch, ["\n"])
324
+
325
+ result = _run(_argv(config_dir, json_mode=False), caplog)
326
+
327
+ assert result.exit_code == 0, result.output
328
+ _assert_labelled_links(result.stdout)
329
+
292
330
  @pytest.mark.parametrize("key", ["\n", "\r", "\x1b", "q"])
293
331
  def test_finish_key_ends_without_copying(
294
332
  self, config_dir, httpx_mock, caplog, monkeypatch, key: str
@@ -318,6 +356,7 @@ class TestTerminalPrompt:
318
356
  assert result.exit_code == 0, result.output
319
357
  assert clipboard.copied == []
320
358
  assert "No key pressed for 120 s. The password was not copied." in result.stdout
359
+ assert "The Configuration page shows it under Open App after login." in result.stdout
321
360
  _assert_no_leak(argv, result, caplog, monkeypatch)
322
361
 
323
362
  def test_failed_copy_says_so_and_points_to_the_ui(
@@ -334,6 +373,7 @@ class TestTerminalPrompt:
334
373
  assert clipboard.copied == [SENTINEL]
335
374
  assert "Copied to clipboard" not in result.stdout
336
375
  assert "The password was not copied." in result.stdout
376
+ assert "The Configuration page shows it under Open App after login." in result.stdout
337
377
  assert UI_URL in result.stdout
338
378
  _assert_no_leak(argv, result, caplog, monkeypatch)
339
379
 
@@ -349,7 +389,8 @@ class TestTerminalPrompt:
349
389
  assert result.exit_code == 0, result.output
350
390
  assert "Press c" not in result.stdout
351
391
  assert "cannot be copied" in result.stdout
352
- assert UI_URL in result.stdout
392
+ assert "The Configuration page shows it under Open App after login." in result.stdout
393
+ _assert_labelled_links(result.stdout)
353
394
  _assert_no_leak(argv, result, caplog, monkeypatch)
354
395
 
355
396
  def test_copy_flag_in_a_terminal_copies_without_the_prompt(
@@ -488,6 +529,88 @@ class TestAuthHeaders:
488
529
  assert "X-KBC-ManageApiToken" not in request.headers
489
530
 
490
531
 
532
+ # ---------------------------------------------------------------------------
533
+ # Colours: the styles of the `auth login --device-code` panel
534
+ # ---------------------------------------------------------------------------
535
+
536
+
537
+ class TestColours:
538
+ def test_only_the_app_link_is_bold_cyan_like_the_device_login_link(
539
+ self, config_dir, httpx_mock, caplog, force_colour
540
+ ) -> None:
541
+ _mock_api(httpx_mock)
542
+
543
+ result = _run(_argv(config_dir, json_mode=False), caplog)
544
+
545
+ assert result.exit_code == 0, result.output
546
+ assert f"{BOLD_CYAN}{APP_URL}{RESET}" in result.stdout
547
+ assert f"{BOLD}{UI_URL}{RESET}" in result.stdout
548
+
549
+ def test_revealed_password_is_bold_yellow_like_the_device_login_code(
550
+ self, config_dir, httpx_mock, caplog, force_colour
551
+ ) -> None:
552
+ _mock_api(httpx_mock)
553
+
554
+ result = _run(_argv(config_dir, "--reveal", json_mode=False), caplog)
555
+
556
+ assert result.exit_code == 0, result.output
557
+ assert f"Password: {BOLD_YELLOW}{SENTINEL}{RESET}" in result.stdout
558
+
559
+ def test_prompt_hint_is_cyan_like_the_device_login_hint(
560
+ self, config_dir, httpx_mock, caplog, monkeypatch, force_colour
561
+ ) -> None:
562
+ _mock_api(httpx_mock)
563
+ _clipboard(monkeypatch)
564
+ _terminal(monkeypatch, ["\n"])
565
+
566
+ result = _run(_argv(config_dir, json_mode=False), caplog)
567
+
568
+ assert result.exit_code == 0, result.output
569
+ assert f"{CYAN}Press c to copy the password, Enter to finish{RESET}" in result.stdout
570
+
571
+
572
+ # ---------------------------------------------------------------------------
573
+ # Panel: in a terminal the block is laid out like the device-login panel
574
+ # ---------------------------------------------------------------------------
575
+
576
+ _ANSI = re.compile(r"\x1b\[[0-9;]*m")
577
+
578
+
579
+ def _plain(output: str) -> str:
580
+ return _ANSI.sub("", output)
581
+
582
+
583
+ class TestPanel:
584
+ @pytest.mark.parametrize("flags", [(), ("--reveal",)])
585
+ def test_terminal_output_is_one_panel(
586
+ self, config_dir, httpx_mock, caplog, monkeypatch, force_colour, flags
587
+ ) -> None:
588
+ monkeypatch.setenv("COLUMNS", "200")
589
+ _mock_api(httpx_mock)
590
+ if not flags:
591
+ _clipboard(monkeypatch)
592
+ _terminal(monkeypatch, ["\n"])
593
+
594
+ result = _run(_argv(config_dir, *flags, json_mode=False), caplog)
595
+
596
+ assert result.exit_code == 0, result.output
597
+ lines = _plain(result.stdout).splitlines()
598
+ assert "Data app password" in lines[0]
599
+ rows = [line[1:-1].strip() for line in lines if line.startswith("│")]
600
+ # Like the device-login panel: a plain label, a blank line, the link.
601
+ assert rows[1:9] == ["", "Open the app:", "", APP_URL, "", "Configuration:", "", UI_URL]
602
+ assert rows[9:] == (["", f"Password: {SENTINEL}"] if flags else [])
603
+
604
+ def test_no_panel_outside_a_terminal(self, config_dir, httpx_mock, caplog) -> None:
605
+ _mock_api(httpx_mock)
606
+
607
+ result = _run(_argv(config_dir, json_mode=False), caplog)
608
+
609
+ assert result.exit_code == 0, result.output
610
+ assert "╭" not in result.stdout
611
+ _assert_labelled_links(result.stdout)
612
+
613
+
491
614
  # ---------------------------------------------------------------------------
492
615
  # After `deploy --wait` / `create --wait`
493
616
  # ---------------------------------------------------------------------------
@@ -659,6 +782,23 @@ class TestAfterDeploy:
659
782
  assert "Press c to copy the password, Enter to finish" in result.stdout
660
783
  _assert_no_leak(argv, result, caplog, monkeypatch)
661
784
 
785
+ @pytest.mark.parametrize("command", ["deploy", "create"])
786
+ def test_wait_with_reveal_labels_the_two_links(
787
+ self, config_dir, httpx_mock, caplog, command: str
788
+ ) -> None:
789
+ if command == "create":
790
+ _mock_create(httpx_mock)
791
+ else:
792
+ _mock_deploy_patch(httpx_mock)
793
+ _mock_deployed_app(httpx_mock)
794
+ build = _create_argv if command == "create" else _deploy_argv
795
+
796
+ result = _run(build(config_dir, "--wait", "--reveal", json_mode=False), caplog)
797
+
798
+ assert result.exit_code == 0, result.output
799
+ assert "is in this output (--reveal)." in result.stdout
800
+ _assert_labelled_links(result.stdout)
801
+
662
802
  @pytest.mark.parametrize("json_mode", [True, False])
663
803
  @pytest.mark.parametrize("command", ["deploy", "create"])
664
804
  def test_no_flag_and_no_prompt_reads_nothing(
@@ -92,6 +92,16 @@ def test_on_prompt_prints_hint_when_enabled() -> None:
92
92
  assert "Press c to copy the link" in _output(console)
93
93
 
94
94
 
95
+ def test_on_prompt_hint_is_cyan() -> None:
96
+ """The style of the `auth login --device-code` hint, also used by `data-app password`."""
97
+ console = Console(
98
+ file=io.StringIO(), force_terminal=True, color_system="standard", no_color=False, width=80
99
+ )
100
+ wait = CopyableUrlWait(console, copier=_Recorder(), interactive=True)
101
+ wait.on_prompt("https://example.com/x")
102
+ assert "\x1b[36mPress c to copy the link\x1b[0m" in _output(console)
103
+
104
+
95
105
  def test_on_prompt_silent_when_disabled(monkeypatch: pytest.MonkeyPatch) -> None:
96
106
  # Same staging as test_disabled_without_backend: no detectable backend.
97
107
  monkeypatch.setattr(_url_copy, "detect_clipboard", lambda: None)
@@ -2376,9 +2376,9 @@
2376
2376
  "license": "MIT"
2377
2377
  },
2378
2378
  "node_modules/dompurify": {
2379
- "version": "3.4.13",
2380
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz",
2381
- "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==",
2379
+ "version": "3.4.16",
2380
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.16.tgz",
2381
+ "integrity": "sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==",
2382
2382
  "license": "(MPL-2.0 OR Apache-2.0)",
2383
2383
  "optionalDependencies": {
2384
2384
  "@types/trusted-types": "^2.0.7"
@@ -32,6 +32,6 @@
32
32
  "vitest": "^4.1.11"
33
33
  },
34
34
  "overrides": {
35
- "dompurify": "^3.4.13"
35
+ "dompurify": "^3.4.16"
36
36
  }
37
37
  }
File without changes
File without changes