keboola-cli 0.95.0__tar.gz → 0.96.0__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 (610) hide show
  1. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/CLAUDE.md +66 -9
  2. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/CONTRIBUTING.md +5 -1
  3. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/PKG-INFO +2 -2
  4. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/README.md +1 -1
  5. keboola_cli-0.96.0/formal/sync/README.md +130 -0
  6. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py +11 -6
  7. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/pyproject.toml +1 -1
  8. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/file_size_baseline.json +1 -1
  9. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/environment.py +10 -2
  10. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auto_update.py +2 -0
  11. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/changelog.py +201 -4
  12. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/cli.py +9 -0
  13. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/_client.py +3 -1
  14. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/_core.py +21 -0
  15. keboola_cli-0.96.0/src/keboola_agent_cli/client/editor.py +73 -0
  16. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/queue.py +5 -2
  17. keboola_cli-0.96.0/src/keboola_agent_cli/commands/_data_app_password.py +502 -0
  18. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +5 -0
  19. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_flow_triggers.py +2 -2
  20. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_helpers.py +0 -82
  21. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_merge_request_common.py +7 -3
  22. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_merge_request_writes.py +9 -2
  23. keboola_cli-0.96.0/src/keboola_agent_cli/commands/_project_ref.py +155 -0
  24. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_storage_describe.py +6 -6
  25. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_storage_snapshots.py +4 -6
  26. keboola_cli-0.96.0/src/keboola_agent_cli/commands/_sync_clone_render.py +76 -0
  27. keboola_cli-0.96.0/src/keboola_agent_cli/commands/_sync_push_render.py +60 -0
  28. keboola_cli-0.96.0/src/keboola_agent_cli/commands/_url_copy.py +349 -0
  29. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/branch.py +5 -0
  30. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/changelog.py +35 -12
  31. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/component.py +2 -2
  32. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/config.py +16 -33
  33. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/config_state.py +4 -3
  34. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/context.py +140 -27
  35. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/data_app.py +103 -93
  36. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/flow.py +7 -8
  37. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/init.py +2 -1
  38. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/job.py +4 -3
  39. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/notification.py +3 -0
  40. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/project.py +4 -5
  41. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/schedule.py +4 -14
  42. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/storage.py +28 -30
  43. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/stream.py +5 -0
  44. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/sync.py +61 -55
  45. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/transformation.py +4 -4
  46. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/workspace.py +18 -28
  47. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/config_store.py +31 -5
  48. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/constants.py +20 -3
  49. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/data_science_client.py +57 -38
  50. keboola_cli-0.96.0/src/keboola_agent_cli/effective_branch.py +208 -0
  51. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/errors.py +3 -1
  52. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/models.py +7 -0
  53. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/output.py +55 -8
  54. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/permissions.py +6 -0
  55. keboola_cli-0.96.0/src/keboola_agent_cli/project_ref.py +108 -0
  56. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/result_models.py +28 -0
  57. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/app.py +10 -3
  58. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/dependencies.py +43 -0
  59. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/auth.py +13 -2
  60. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/data_apps.py +28 -9
  61. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/jobs.py +2 -1
  62. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/projects.py +9 -3
  63. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/workspaces.py +4 -5
  64. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_config_clone.py +13 -3
  65. keboola_cli-0.96.0/src/keboola_agent_cli/services/_data_app_password.py +136 -0
  66. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_baseline.py +46 -40
  67. keboola_cli-0.96.0/src/keboola_agent_cli/services/_sync_bindings.py +950 -0
  68. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_clone.py +60 -11
  69. keboola_cli-0.96.0/src/keboola_agent_cli/services/_sync_clone_warnings.py +434 -0
  70. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_data_app.py +62 -0
  71. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_models.py +54 -10
  72. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_push_ops.py +121 -8
  73. keboola_cli-0.96.0/src/keboola_agent_cli/services/_sync_stale.py +244 -0
  74. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_storage.py +152 -2
  75. keboola_cli-0.96.0/src/keboola_agent_cli/services/_sync_workspace.py +461 -0
  76. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/base.py +26 -12
  77. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/branch_service.py +9 -4
  78. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/config_service.py +25 -25
  79. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/data_app_service.py +37 -40
  80. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/feature_service.py +3 -7
  81. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/flow_service.py +10 -9
  82. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/job_service.py +25 -6
  83. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/member_service.py +40 -17
  84. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/merge_request_service.py +4 -0
  85. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/notification_service.py +5 -4
  86. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/project_service.py +16 -4
  87. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/schedule_service.py +4 -3
  88. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/sync_service.py +134 -148
  89. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/version_service.py +63 -5
  90. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/workspace_service.py +25 -23
  91. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/branch_scope.py +76 -0
  92. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/clone.py +20 -2
  93. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/diff_engine.py +27 -5
  94. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/manifest.py +8 -1
  95. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/update_runner.py +29 -0
  96. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/helpers.py +109 -0
  97. keboola_cli-0.96.0/tests/test_api_call_counts.py +543 -0
  98. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_environment.py +14 -0
  99. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auto_update.py +13 -2
  100. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_billing_cli.py +11 -5
  101. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_changelog_render.py +39 -7
  102. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_clone_service.py +43 -0
  103. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_metadata.py +1 -1
  104. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_cli.py +104 -37
  105. keboola_cli-0.96.0/tests/test_data_app_password.py +1179 -0
  106. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_service.py +297 -18
  107. keboola_cli-0.96.0/tests/test_effective_branch.py +444 -0
  108. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_errors.py +11 -4
  109. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_file_locking.py +11 -3
  110. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_generate_promotion_pipeline.py +17 -0
  111. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_helpers.py +0 -225
  112. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_integration.py +77 -55
  113. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_manage_token_cli.py +6 -38
  114. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_member_service.py +68 -1
  115. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_permissions_cli.py +13 -9
  116. keboola_cli-0.96.0/tests/test_project_ref.py +484 -0
  117. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_result_models.py +35 -0
  118. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_search_service.py +5 -4
  119. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_server_permissions.py +6 -2
  120. keboola_cli-0.96.0/tests/test_server_project_ref.py +117 -0
  121. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_server_router_calls.py +34 -32
  122. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_services.py +46 -4
  123. keboola_cli-0.96.0/tests/test_sync_branch_scope.py +61 -0
  124. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_cli.py +68 -1
  125. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_clone.py +359 -6
  126. keboola_cli-0.96.0/tests/test_sync_clone_links.py +1130 -0
  127. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_data_app_type.py +126 -12
  128. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_diff_engine.py +55 -0
  129. keboola_cli-0.96.0/tests/test_sync_formal_counterexamples.py +985 -0
  130. keboola_cli-0.96.0/tests/test_sync_pull_companion_files.py +208 -0
  131. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_service.py +156 -18
  132. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_storage_jobs.py +23 -0
  133. keboola_cli-0.96.0/tests/test_sync_workspaces.py +1412 -0
  134. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_update_runner.py +103 -0
  135. keboola_cli-0.96.0/tests/test_url_copy.py +396 -0
  136. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_version_service.py +147 -0
  137. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_workspace_cli.py +8 -13
  138. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_workspace_service.py +62 -0
  139. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/DataApps.tsx +1 -1
  140. keboola_cli-0.95.0/src/keboola_agent_cli/commands/_url_copy.py +0 -205
  141. keboola_cli-0.95.0/src/keboola_agent_cli/services/_sync_bindings.py +0 -502
  142. keboola_cli-0.95.0/tests/test_url_copy.py +0 -126
  143. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/.gitignore +0 -0
  144. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/LICENSE +0 -0
  145. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/Makefile +0 -0
  146. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/examples/README.md +0 -0
  147. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/examples/storage_tui/README.md +0 -0
  148. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
  149. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/plugins/kbagent/skills/kbagent-cicd-migration/scripts/migrate_cicd.py +0 -0
  150. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_command_sync.py +0 -0
  151. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_error_codes.py +0 -0
  152. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_file_size.py +0 -0
  153. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_release_scope.py +0 -0
  154. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_sentinel_guards.py +0 -0
  155. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_version_gates.py +0 -0
  156. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/check_wheel_ui.py +0 -0
  157. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/debug_linkedby_type.sh +0 -0
  158. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/gen_command_reference.py +0 -0
  159. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/gen_endpoint_reference.py +0 -0
  160. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/gen_release_notes.py +0 -0
  161. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/generate_changelog.py +0 -0
  162. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/generate_skill.py +0 -0
  163. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/hatch_build.py +0 -0
  164. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/lineage_deep.py +0 -0
  165. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/post-edit-quality.sh +0 -0
  166. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/pre-commit +0 -0
  167. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/sync_version.py +0 -0
  168. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/scripts/web-dev.sh +0 -0
  169. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/__init__.py +0 -0
  170. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/__main__.py +0 -0
  171. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/ai_client.py +0 -0
  172. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/__init__.py +0 -0
  173. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/auth_client.py +0 -0
  174. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/device.py +0 -0
  175. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/models.py +0 -0
  176. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/pkce.py +0 -0
  177. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/sentinel.py +0 -0
  178. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/state_store.py +0 -0
  179. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/token_provider.py +0 -0
  180. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/auth/totp.py +0 -0
  181. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/__init__.py +0 -0
  182. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/_transfer.py +0 -0
  183. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/billing.py +0 -0
  184. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/branches.py +0 -0
  185. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/configs.py +0 -0
  186. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/merge_requests.py +0 -0
  187. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/misc.py +0 -0
  188. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/notifications.py +0 -0
  189. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/query.py +0 -0
  190. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/storage_files.py +0 -0
  191. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/storage_tables.py +0 -0
  192. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/stream.py +0 -0
  193. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/tokens.py +0 -0
  194. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/triggers.py +0 -0
  195. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/client/workspaces.py +0 -0
  196. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
  197. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_auth_picker.py +0 -0
  198. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_checkbox_select.py +0 -0
  199. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_config_clone_cmd.py +0 -0
  200. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_config_oauth.py +0 -0
  201. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_config_trash_cmd.py +0 -0
  202. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
  203. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_merge_request_render.py +0 -0
  204. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
  205. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_project_create.py +0 -0
  206. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
  207. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
  208. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
  209. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_storage_table_detail.py +0 -0
  210. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/_storage_tables_render.py +0 -0
  211. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/agent.py +0 -0
  212. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/auth.py +0 -0
  213. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/billing.py +0 -0
  214. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
  215. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/docs.py +0 -0
  216. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
  217. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
  218. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/feature.py +0 -0
  219. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
  220. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/kai.py +0 -0
  221. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/lineage.py +0 -0
  222. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/merge_request.py +0 -0
  223. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/org.py +0 -0
  224. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/permissions.py +0 -0
  225. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/repl.py +0 -0
  226. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/search.py +0 -0
  227. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
  228. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/serve.py +0 -0
  229. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
  230. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/token.py +0 -0
  231. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/commands/version.py +0 -0
  232. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
  233. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/frozen_dist.py +0 -0
  234. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/http_base.py +0 -0
  235. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/json_utils.py +0 -0
  236. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/lib.py +0 -0
  237. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/manage_client.py +0 -0
  238. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/metastore_client.py +0 -0
  239. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/py.typed +0 -0
  240. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/resources/__init__.py +0 -0
  241. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
  242. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
  243. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
  244. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
  245. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
  246. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/scheduler_client.py +0 -0
  247. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/__init__.py +0 -0
  248. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/_serve_command_map.py +0 -0
  249. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
  250. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
  251. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/auth.py +0 -0
  252. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/pricing.py +0 -0
  253. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
  254. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
  255. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
  256. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/billing.py +0 -0
  257. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
  258. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
  259. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/configs.py +0 -0
  260. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
  261. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/docs.py +0 -0
  262. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
  263. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
  264. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
  265. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
  266. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
  267. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
  268. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
  269. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/merge_requests.py +0 -0
  270. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/notifications.py +0 -0
  271. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
  272. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
  273. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
  274. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
  275. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
  276. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/storage.py +0 -0
  277. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
  278. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/token.py +0 -0
  279. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
  280. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
  281. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/server/sse.py +0 -0
  282. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/__init__.py +0 -0
  283. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_auth_registration.py +0 -0
  284. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_column_descriptions.py +0 -0
  285. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_config_set_guard.py +0 -0
  286. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_config_trash.py +0 -0
  287. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_data_app_bodies.py +0 -0
  288. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_describe_batch_input.py +0 -0
  289. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_encryption.py +0 -0
  290. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
  291. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
  292. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_semantic_layer_fqn.py +0 -0
  293. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
  294. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
  295. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
  296. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_storage_tables.py +0 -0
  297. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
  298. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
  299. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
  300. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_table_detail.py +0 -0
  301. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_token_last_used.py +0 -0
  302. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
  303. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/_workspace_load_plan.py +0 -0
  304. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
  305. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/auth_service.py +0 -0
  306. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/billing_service.py +0 -0
  307. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/component_service.py +0 -0
  308. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
  309. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
  310. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
  311. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/docs_service.py +0 -0
  312. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
  313. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
  314. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
  315. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
  316. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
  317. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
  318. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
  319. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/org_service.py +0 -0
  320. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
  321. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/search_service.py +0 -0
  322. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
  323. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
  324. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
  325. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/storage_service.py +0 -0
  326. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
  327. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/table_usage.py +0 -0
  328. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/token_service.py +0 -0
  329. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/transformation_service.py +0 -0
  330. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
  331. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/stream_client.py +0 -0
  332. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
  333. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
  334. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/branch_registry.py +0 -0
  335. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
  336. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/config_format.py +0 -0
  337. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
  338. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/naming.py +0 -0
  339. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
  340. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
  341. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/telemetry.py +0 -0
  342. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/src/keboola_agent_cli/yaml_input.py +0 -0
  343. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/__init__.py +0 -0
  344. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/conftest.py +0 -0
  345. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agent_cli.py +0 -0
  346. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agent_prompt.py +0 -0
  347. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agent_prompt_helper.py +0 -0
  348. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agent_runner.py +0 -0
  349. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agent_service.py +0 -0
  350. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agent_tombstone.py +0 -0
  351. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_agents_store_events.py +0 -0
  352. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_ai_client.py +0 -0
  353. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_client.py +0 -0
  354. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_device.py +0 -0
  355. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_models.py +0 -0
  356. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_picker.py +0 -0
  357. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_pkce.py +0 -0
  358. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_register_projects.py +0 -0
  359. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_sentinel.py +0 -0
  360. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_sentinel_guards.py +0 -0
  361. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_service.py +0 -0
  362. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_state_store.py +0 -0
  363. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_auth_totp.py +0 -0
  364. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_base_service.py +0 -0
  365. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_billing_client.py +0 -0
  366. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_billing_service.py +0 -0
  367. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_branch_metadata_cli.py +0 -0
  368. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_branch_metadata_service.py +0 -0
  369. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_branch_registry.py +0 -0
  370. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_branch_service.py +0 -0
  371. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_build_hook.py +0 -0
  372. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_changelog_check.py +0 -0
  373. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_check_command_sync.py +0 -0
  374. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_check_file_size.py +0 -0
  375. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_check_release_scope.py +0 -0
  376. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_check_sentinel_guards.py +0 -0
  377. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_check_version_gates.py +0 -0
  378. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_checkbox_select.py +0 -0
  379. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_choice_enums.py +0 -0
  380. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_cli.py +0 -0
  381. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_cli_auth.py +0 -0
  382. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_client.py +0 -0
  383. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_client_device_enrollment.py +0 -0
  384. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_client_token_events.py +0 -0
  385. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_component_cli.py +0 -0
  386. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_component_service.py +0 -0
  387. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_component_sync_action.py +0 -0
  388. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_clone_cli.py +0 -0
  389. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_create_cli.py +0 -0
  390. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_create_service.py +0 -0
  391. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_encryption.py +0 -0
  392. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_examples.py +0 -0
  393. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_rename.py +0 -0
  394. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_rename_cli.py +0 -0
  395. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_resolution.py +0 -0
  396. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_row_cli.py +0 -0
  397. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_row_service.py +0 -0
  398. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_search.py +0 -0
  399. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_search_cli.py +0 -0
  400. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_set_default_bucket.py +0 -0
  401. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_set_guard.py +0 -0
  402. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_state.py +0 -0
  403. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_store.py +0 -0
  404. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_trash.py +0 -0
  405. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_config_update.py +0 -0
  406. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_git_repo.py +0 -0
  407. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_plain_env_keys.py +0 -0
  408. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_secrets_cli.py +0 -0
  409. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_secrets_service.py +0 -0
  410. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_data_app_validate_repo_service.py +0 -0
  411. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_deep_lineage_service.py +0 -0
  412. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_dev_portal_cli.py +0 -0
  413. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_dev_portal_client.py +0 -0
  414. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_dev_portal_service.py +0 -0
  415. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_docs_cli.py +0 -0
  416. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_doctor_service.py +0 -0
  417. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_e2e.py +0 -0
  418. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_e2e_auth.py +0 -0
  419. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_e2e_config_dir_mode.py +0 -0
  420. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_e2e_lineage_deep.py +0 -0
  421. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_encrypt_cli.py +0 -0
  422. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_encrypt_service.py +0 -0
  423. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_encryption.py +0 -0
  424. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_feature_cli.py +0 -0
  425. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_feature_service.py +0 -0
  426. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_flow_cli.py +0 -0
  427. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_flow_examples.py +0 -0
  428. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_flow_service.py +0 -0
  429. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_flow_validation.py +0 -0
  430. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_frozen_dist.py +0 -0
  431. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_gen_command_reference.py +0 -0
  432. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_gen_endpoint_reference.py +0 -0
  433. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_gen_release_notes.py +0 -0
  434. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_http_base.py +0 -0
  435. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_http_base_auth.py +0 -0
  436. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_http_client_cmd.py +0 -0
  437. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_http_forwarder_service.py +0 -0
  438. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_job_idempotency_store.py +0 -0
  439. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_job_options.py +0 -0
  440. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_json_utils.py +0 -0
  441. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_kai_cli.py +0 -0
  442. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_kai_service.py +0 -0
  443. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_lib.py +0 -0
  444. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_lib_device_enrollment.py +0 -0
  445. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_license_consistency.py +0 -0
  446. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_lineage_service.py +0 -0
  447. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_local_ai_chat.py +0 -0
  448. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_manage_client.py +0 -0
  449. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_manage_token_bulk.py +0 -0
  450. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_mcp_migration_recipe.py +0 -0
  451. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_member_cli.py +0 -0
  452. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_merge_request_cli.py +0 -0
  453. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_merge_request_client.py +0 -0
  454. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_merge_request_service.py +0 -0
  455. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_metastore_client.py +0 -0
  456. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_migrate_cicd.py +0 -0
  457. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_models.py +0 -0
  458. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_normalize_script.py +0 -0
  459. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_notification_cli.py +0 -0
  460. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_notification_client.py +0 -0
  461. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_notification_service.py +0 -0
  462. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_org_service.py +0 -0
  463. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_output.py +0 -0
  464. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_permissions.py +0 -0
  465. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_pricing.py +0 -0
  466. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_project_create_cli.py +0 -0
  467. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_project_edit.py +0 -0
  468. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_project_edit_cli.py +0 -0
  469. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_project_info_cli.py +0 -0
  470. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_project_info_service.py +0 -0
  471. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_release_kbagent_ai_kit_sync.py +0 -0
  472. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_repl.py +0 -0
  473. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_run_broadcaster.py +0 -0
  474. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_schedule_cli.py +0 -0
  475. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_schedule_service.py +0 -0
  476. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_scheduler_client.py +0 -0
  477. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_search_cli.py +0 -0
  478. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_semantic_layer_cli.py +0 -0
  479. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_semantic_layer_schema.py +0 -0
  480. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_semantic_layer_service.py +0 -0
  481. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_serve_banner_encoding.py +0 -0
  482. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_serve_conversation_id.py +0 -0
  483. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_serve_telemetry.py +0 -0
  484. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_serve_ui.py +0 -0
  485. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_server_auth.py +0 -0
  486. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
  487. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_server_smoke.py +0 -0
  488. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sharing_cli.py +0 -0
  489. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sharing_service.py +0 -0
  490. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_skill_frontmatter.py +0 -0
  491. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sql_split.py +0 -0
  492. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_clone.py +0 -0
  493. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_create_table.py +0 -0
  494. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_delete.py +0 -0
  495. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_describe_cli.py +0 -0
  496. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_describe_service.py +0 -0
  497. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_empty_definition.py +0 -0
  498. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_export_filters.py +0 -0
  499. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_files.py +0 -0
  500. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_snapshots.py +0 -0
  501. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_swap.py +0 -0
  502. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_table_definition.py +0 -0
  503. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_tables.py +0 -0
  504. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_truncate.py +0 -0
  505. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_storage_write.py +0 -0
  506. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_stream_cli.py +0 -0
  507. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_stream_client.py +0 -0
  508. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_stream_service.py +0 -0
  509. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_baseline_stamping.py +0 -0
  510. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_branch_mapping.py +0 -0
  511. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_cli_behavior.py +0 -0
  512. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_code_extraction.py +0 -0
  513. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_config_format.py +0 -0
  514. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_e2e.py +0 -0
  515. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_encrypt.py +0 -0
  516. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_force_pull_baseline.py +0 -0
  517. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_manifest.py +0 -0
  518. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_naming.py +0 -0
  519. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_plaintext_audit.py +0 -0
  520. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_push_script_guard.py +0 -0
  521. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_reconcile.py +0 -0
  522. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_secrets.py +0 -0
  523. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_sync_version_script.py +0 -0
  524. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_table_usage.py +0 -0
  525. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_telemetry.py +0 -0
  526. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_token_cli.py +0 -0
  527. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_token_provider.py +0 -0
  528. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_token_service.py +0 -0
  529. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_transformation_cli.py +0 -0
  530. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_transformation_ops.py +0 -0
  531. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_triggers_client.py +0 -0
  532. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_variables_cli.py +0 -0
  533. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_variables_service.py +0 -0
  534. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_workspace_gc.py +0 -0
  535. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_workspace_sql_helper.py +0 -0
  536. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/tests/test_yaml_input.py +0 -0
  537. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/README.md +0 -0
  538. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/index.html +0 -0
  539. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/package-lock.json +0 -0
  540. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/package.json +0 -0
  541. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/postcss.config.js +0 -0
  542. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/App.tsx +0 -0
  543. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/api/client.test.ts +0 -0
  544. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/api/client.ts +0 -0
  545. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/changelogNotes.test.ts +0 -0
  546. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/changelogNotes.ts +0 -0
  547. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
  548. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/CommandPalette.tsx +0 -0
  549. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/ConfirmModal.tsx +0 -0
  550. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/DetailTabs.tsx +0 -0
  551. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/Drawer.tsx +0 -0
  552. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/Empty.tsx +0 -0
  553. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/JsonView.tsx +0 -0
  554. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/KeyValueGrid.tsx +0 -0
  555. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
  556. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/PillList.tsx +0 -0
  557. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/RawDetail.tsx +0 -0
  558. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/SessionExpiredBanner.tsx +0 -0
  559. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/Table.tsx +0 -0
  560. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/components/WhatsNew.tsx +0 -0
  561. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/config/credits.test.ts +0 -0
  562. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/config/credits.ts +0 -0
  563. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/index.css +0 -0
  564. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/layout/Shell.tsx +0 -0
  565. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
  566. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
  567. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/layout/TopBar.tsx +0 -0
  568. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/lib/time.test.ts +0 -0
  569. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/lib/time.ts +0 -0
  570. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/main.tsx +0 -0
  571. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Agents.tsx +0 -0
  572. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Branches.tsx +0 -0
  573. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Changelog.tsx +0 -0
  574. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Components.tsx +0 -0
  575. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Configs.tsx +0 -0
  576. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
  577. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Doctor.tsx +0 -0
  578. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
  579. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Flows.tsx +0 -0
  580. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Jobs.tsx +0 -0
  581. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/JobsAll.tsx +0 -0
  582. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Lineage.tsx +0 -0
  583. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
  584. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Members.tsx +0 -0
  585. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Org.tsx +0 -0
  586. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Projects.tsx +0 -0
  587. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Schedules.tsx +0 -0
  588. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Search.tsx +0 -0
  589. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
  590. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
  591. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Sharing.tsx +0 -0
  592. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Storage.tsx +0 -0
  593. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Streams.tsx +0 -0
  594. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Tokens.tsx +0 -0
  595. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/TokensAll.tsx +0 -0
  596. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
  597. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/jobsShared.tsx +0 -0
  598. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/storageSel.test.ts +0 -0
  599. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/tokensShared.test.ts +0 -0
  600. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/pages/tokensShared.tsx +0 -0
  601. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/router.test.ts +0 -0
  602. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/router.ts +0 -0
  603. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/state.tsx +0 -0
  604. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/theme.tsx +0 -0
  605. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/types.ts +0 -0
  606. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/useHashSelection.ts +0 -0
  607. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/src/whatsnew.ts +0 -0
  608. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/tailwind.config.ts +0 -0
  609. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/tsconfig.json +0 -0
  610. {keboola_cli-0.95.0 → keboola_cli-0.96.0}/web/frontend/vite.config.ts +0 -0
@@ -68,6 +68,10 @@ src/keboola_agent_cli/
68
68
  constants.py # Shared constants + dynamic APP_NAME resolution (retry params, timeouts, defaults)
69
69
  json_utils.py # Deep-merge, set_nested_value, compute_diff utilities
70
70
  models.py # Pydantic models shared across layers
71
+ effective_branch.py # resolve_branch(): the ONLY code that applies the `branch use` active branch;
72
+ # records project + branch for the `Target:` line / `targets` key (#766)
73
+ project_ref.py # resolve_project_ref(): a project ID given where an alias is expected -> the
74
+ # alias (CLI-22); applied by commands/_project_ref.py and serve's dependency
71
75
  output.py # OutputFormatter: JSON vs Rich dual-mode output
72
76
  errors.py # KeboolaApiError, ConfigError, ErrorCode enum, mask_token()
73
77
  config_store.py # JSON persistence for config.json (0600 permissions)
@@ -80,7 +84,7 @@ src/keboola_agent_cli/
80
84
  http_base.py # BaseHttpClient - shared retry/backoff + common HTTP infra
81
85
  client/ # Storage API + Queue API package (X-StorageApi-Token);
82
86
  # split by endpoint family (storage_tables/storage_files/configs/
83
- # queue/tokens/branches/stream/query/workspaces/misc + _core/_transfer),
87
+ # queue/tokens/branches/stream/query/workspaces/editor/misc + _core/_transfer),
84
88
  # composed into one KeboolaClient via mixins (#520)
85
89
  manage_client.py # Manage API (X-KBC-ManageApiToken)
86
90
  ai_client.py # AI Service API (component schemas, Kai)
@@ -293,6 +297,28 @@ Full author checklist: see `CONTRIBUTING.md` > "Releasing a beta (pre-release) v
293
297
  `auth register-projects` disclose and every doc surface defers to. Run
294
298
  `python scripts/check_sentinel_guards.py --list` to see the inventory.
295
299
 
300
+ 19. **Only `effective_branch.resolve_branch()` applies the active branch.**
301
+ Commands and services get the branch ID from it and never read
302
+ `ProjectConfig.active_branch_id` themselves: the function records the
303
+ project and branch, and `OutputFormatter` reports them (a `Target:` line
304
+ on stderr, `targets` in the `--json` envelope, also for `--dry-run`).
305
+ `tests/test_effective_branch.py` fails on a new direct read. A read that
306
+ only shows or manages the active branch must be on its list, with a reason.
307
+
308
+ 20. **Services receive project aliases, never project IDs.** `--project`
309
+ (and `project use`, `KBAGENT_PROJECT`, serve's `{project}` / `?project=`)
310
+ also takes a project ID; the root command group
311
+ (`commands/_project_ref.py`) translates it to the alias before the command
312
+ runs. A new command gets this without extra code. A new command whose
313
+ `--project` is not a registry lookup (a NEW alias like `project add`, an
314
+ offline filter like `lineage show`) must be added to `NO_LOOKUP_COMMANDS`
315
+ there, and an option with another name that takes an existing alias (like
316
+ `config clone --target-project`) to `ALIAS_OPTIONS`.
317
+ `tests/test_project_ref.py` fails on a new option whose flag contains
318
+ `project`, `alias` or `stack` until it is in `ALIAS_OPTIONS` or in the
319
+ test's `NOT_AN_ALIAS` list; an option with any other name (like
320
+ `sync clone --target`) needs that decision by hand.
321
+
296
322
  ## Claude Code Plugin
297
323
 
298
324
  The plugin lives here in `plugins/kbagent/` and is **published through `keboola/ai-kit`**. It exposes: a CLI (`kbagent`), three skills (`kbagent`, `kbagent-cicd-migration`, `kbagent-promotion-pipeline`), three slash commands (`/kbagent:setup`, `/keboola`, `/kbagent:review`), and two specialist subagents (`keboola-expert`, `kbagent-pr-reviewer`). All are namespaced under `kbagent:`. `/kbagent:setup` is the documented one-command first-run path (install CLI -> connect project -> `doctor`); it runs in the main context and spawns no subagent.
@@ -357,6 +383,13 @@ plugins/kbagent/
357
383
  # settings.json -> env). Neither set = header omitted, as before. Version gate for this entry
358
384
  # lives in gotchas.md -- a `(since vNEXT)` tag cannot be written on these `# ` comment lines,
359
385
  # because check_version_gates.py parses them as ATX markdown headings (where a `vNEXT` is fatal).
386
+ # --project (CLI-22) takes a registered alias OR a project ID. An alias wins; an ID registered under
387
+ # several aliases is CONFIG_ERROR (exit 5) listing them, unless all are on one stack and exactly one is a
388
+ # session alias. Same for KBAGENT_PROJECT, `project use`, `config clone --target-project`,
389
+ # `sync clone --target`, the `semantic-layer promote/diff` project options, `auth * --stack`, and
390
+ # serve's {project} / ?project= / ?stack= (path and query only, not request bodies). Not for
391
+ # `project add` / `project create` (new alias) or `lineage show` (offline filter). Version gate in
392
+ # gotchas.md.
360
393
  # Headless / token-only (0.50.0+): export KBAGENT_PROJECT_FROM_ENV=1 + KBC_TOKEN + KBC_STORAGE_API_URL to synthesize an in-memory `__env__` project (no `project add`, no config.json on disk; token never persisted). Use `--project __env__`. Same env setup also powers `kbagent serve`.
361
394
 
362
395
  kbagent auth login [--stack URL|alias] [--device-code] [--register-projects]
@@ -408,7 +441,7 @@ kbagent auth register-projects [--stack URL|alias] [--all] [--project-id ID ...]
408
441
  # AUTH_BROWSER_UNAVAILABLE, AUTH_STATE_MISMATCH, SESSION_EXPIRED, SESSION_NOT_FOUND.
409
442
  # `auth register-projects` (0.80.0+): fixes the usability gap where nothing was registered unless
410
443
  # --register-projects was passed at login, and where the alias offered was a slug of the project
411
- # NAME (never the numeric id, so `--project 9840` never resolves). Lists every project the session
444
+ # NAME (never the numeric id; the id itself resolves as `--project` once registered, CLI-22). Lists every project the session
412
445
  # can access with a collision-free suggested alias, then lets the caller pick which to register.
413
446
  # --all selects every candidate; --project-id ID (repeatable) selects specific ones (unknown id ->
414
447
  # ConfigError); omitting both runs an interactive arrow-key + spacebar checkbox picker (every
@@ -760,6 +793,8 @@ kbagent permissions check OPERATION
760
793
  kbagent branch list [--project NAME]
761
794
  kbagent branch create --project ALIAS --name "..." [--description "..."]
762
795
  kbagent branch use --project ALIAS --branch ID
796
+ # branch use: every command that then picks a branch names it -- `Target:` on stderr, `targets` in
797
+ # --json (branch_source explicit|active_branch|git_mapping|manifest|merge_request|production). Version gate in gotchas.md (#766).
763
798
  kbagent branch reset --project ALIAS
764
799
  kbagent branch delete --project ALIAS --branch ID
765
800
  kbagent branch merge --project ALIAS [--branch ID]
@@ -868,7 +903,7 @@ kbagent workspace from-transformation --project ALIAS --component-id ID --config
868
903
 
869
904
  kbagent data-app list [--project NAME ...] [--branch ID]
870
905
  kbagent data-app detail --project NAME --app-id ID [--branch ID]
871
- kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL | --use-managed-git-repo) [--description STR | --description-file PATH] [--git-branch main] [--git-public/--no-git-public] [--git-username USER] [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...] [--auth password|public] [--size tiny|small|medium|large] [--auto-suspend SECONDS] [--type python-js|python|streamlit|r|...] [--workspace/--no-workspace] [--branch ID] [--no-deploy] [--wait] [--timeout SECONDS] [--keep-on-failure] [--dry-run]
906
+ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL | --use-managed-git-repo) [--description STR | --description-file PATH] [--git-branch main] [--git-public/--no-git-public] [--git-username USER] [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...] [--auth password|public] [--size tiny|small|medium|large] [--auto-suspend SECONDS] [--type python-js|python|streamlit|r|...] [--workspace/--no-workspace] [--branch ID] [--no-deploy] [--wait] [--timeout SECONDS] [--keep-on-failure] [--dry-run] [--copy] [--reveal]
872
907
  # --workspace / --no-workspace (0.87.0+): DEFAULT ON. Writes runtime.workspace.enabled=true --
873
908
  # the ONLY switch that makes the platform provision the ephemeral workspace and inject WORKSPACE_ID,
874
909
  # QUERY_SERVICE_URL and KBC_WORKSPACE_MANIFEST_PATH. Every app that reads Storage needs it. Before
@@ -891,11 +926,27 @@ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL
891
926
  # deploy pins the LATEST configVersion when a git block is present and omits it for a PURE managed
892
927
  # repo (deploys from managedGitRepoId). Use `data-app runs` to debug a deploy that reverts to
893
928
  # stopped (setup-phase failures produce no container logs).
894
- kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID]
929
+ kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--copy] [--reveal]
895
930
  kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
896
931
  kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
897
932
  kbagent data-app delete --project NAME --app-id ID [--yes]
898
- kbagent data-app password --project NAME --app-id ID
933
+ kbagent data-app password --project NAME --app-id ID [--copy] [--reveal] [--open]
934
+ # data-app password: never prints the password unless --reveal, so it does not go into an AI
935
+ # agent's context. Project token only (static or session) -- the Manage token and its prompt are
936
+ # gone. In a terminal (human mode) it waits for `c` to copy (Enter/Esc/q finishes, 120 s timeout);
937
+ # without a terminal or with --json only --copy copies. Nothing copied -> exit 0,
938
+ # password_delivered_to null, ui_url = the Keboola UI page that shows it. --reveal + --copy =
939
+ # INVALID_ARGUMENT. Refuses a non-password app (VALIDATION_ERROR) and a null password (NOT_FOUND).
940
+ # serve: GET /data-apps/{p}/{app}/password takes no X-Manage-Token; ?reveal=true adds `password`.
941
+ # create --wait / deploy --wait deliver the password the same way once the app runs (shared
942
+ # CopyOption / RevealOption + deliver_password in commands/_data_app_password.py); there
943
+ # --copy / --reveal need --wait and a deploy (else INVALID_ARGUMENT, exit 2, no API call;
944
+ # --dry-run applies the same rules and adds a `password_delivery` plan). Without a flag and
945
+ # without the terminal prompt nothing is read (output as before). With a flag, JSON adds only
946
+ # ui_url / password_delivered_to / password (--reveal); any failed read after the deploy is a
947
+ # warnings[] entry, exit 0. The serve create / deploy routes are unchanged. BREAKING: scripts
948
+ # reading `.data.password` from `data-app password` must add --reveal.
949
+ # Version gate + agent rules: gotchas.md / AGENT_CONTEXT.
899
950
  kbagent data-app logs --project NAME --app-id ID [--lines N] [--since ISO8601]
900
951
  kbagent data-app runs --project NAME --app-id ID [--limit N]
901
952
  kbagent data-app secrets-set --project ALIAS --app-id ID --secret '#KEY=VALUE' [--secret ...] [--secrets-file PATH] [--branch ID] [--allow-plaintext-on-encrypt-failure] [--dry-run] [--no-hint-next]
@@ -942,7 +993,8 @@ kbagent config new --component-id ID [--name NAME] [--project NAME] [--output-di
942
993
  # mirrors the pushed encrypted body -- placeholders would overwrite the remote on next push.
943
994
 
944
995
  # sync: GitOps -- configs as local files. init/pull/push/diff are filesystem-local (no serve REST surface).
945
- kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing]
996
+ kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing] [--with-workspaces]
997
+ # `sync init --with-workspaces` (CLI-25) sets the manifest key `syncWorkspaces`: pull/diff/push/clone then also sync shared SQL workspaces (keboola.sandboxes with no parameters.id and runtime.shared true; Python/R and legacy SQL sandboxes stay skipped), config only (services/_sync_workspace.py). A `push --force` delete removes the workspace's SQL editor sessions (Editor service, client/editor.py) before the config, `push --dry-run --force` lists them, and a plain push holds the delete back under skipped_deletions; clone warns about workspace input tables missing in the target. With --adopt-existing it turns the key on in an existing manifest. Version gate for this entry lives in gotchas.md.
946
998
  kbagent sync pull --project ALIAS [--all-projects] [--force] [--theirs] [--dry-run] [--with-samples] [--no-storage] [--no-jobs] [--job-limit N] [--branch ID]
947
999
  # `sync pull` auto-inits: if the target directory has no `.keboola/manifest.json`, pull runs `init` first, so a separate `sync init` is NOT needed for a first checkout. `sync pull --project X -d ./dir` on an empty dir writes the manifest and fetches the configs in one step.
948
1000
  # `sync pull --force` is conflict-aware (since 0.53.0): locally-modified config whose remote is UNCHANGED is preserved (delta stays pushable, never silently re-stamped); a true merge conflict (local AND remote both changed since last pull) aborts (exit 1, SYNC_CONFLICT, --json lists details.conflicts); local-untouched + remote-changed takes remote.
@@ -950,6 +1002,11 @@ kbagent sync pull --project ALIAS [--all-projects] [--force] [--theirs] [--dry-r
950
1002
  kbagent sync status [--directory DIR]
951
1003
  kbagent sync diff --project ALIAS [--all-projects] [--directory DIR] [--branch ID]
952
1004
  kbagent sync push --project ALIAS [--all-projects] [--dry-run] [--force] [--allow-plaintext-on-encrypt-failure] [--branch ID] [--no-name-drift-warnings]
1005
+ # sync push --force (#792): push deletes remote configs and rows ONLY with --force; a plain push lists them
1006
+ # under skipped_deletions (+ skipped_deletions_reason), also in --dry-run, whose summary.deleted counts only
1007
+ # what push would delete. A config/row deleted on the remote since the last pull diffs as remote_deleted and
1008
+ # is never re-created (it lands in skipped). Version gate in gotchas.md.
1009
+ # sync push workspace delete (CLI-25): in a `syncWorkspaces` tree, a `push --force` that deletes a shared SQL workspace also deletes its SQL editor sessions (every user's, push branch) and their backend workspaces, which `config restore` does not bring back; `push --dry-run --force` lists them (warnings[] workspace_sessions), a plain push lists the workspace under skipped_deletions and touches no session. `--force` is destructive-class (FLAG_ESCALATIONS `sync.push --force`), so `--deny-destructive` / a cli:destructive deny blocks it while a plain push stays write-class. Version gate for this entry lives in gotchas.md.
953
1010
  # sync push (since 0.91.0, #686): the manifest baseline `pull_config_hash` is stamped from the API
954
1011
  # response (or a read-back), never from disk -- push-deployed multi-statement SQL transformations
955
1012
  # (and anything disabled in the UI whose local YAML lacks `is_disabled`) no longer show permanent
@@ -964,8 +1021,8 @@ kbagent sync push --project ALIAS [--all-projects] [--dry-run] [--force] [--allo
964
1021
  # with SYNC_LEGACY_BOUNDARY telling you to pull first; genuine edits push normally.
965
1022
  # sync diff/push (0.89.0+, #649): local side read from exactly ONE tree (target branch subtree, else main/); entries tracked on another branch's tree are excluded from the changeset and reported under orphaned[] + summary.orphaned (reasons + reconcile hints); fix with sync pull. Adopt-by-id is branch-aware.
966
1023
  # Ignored components (since 0.91.0, #689): keboola.mcp-server-tool joins keboola.sandboxes on ALWAYS_IGNORED_COMPONENTS (the MCP server's auto-created empty mcp-workspace-<hex> configs); the manifest field ignoredComponents (.keboola/manifest.json) is now LIVE and unions with the hardcoded set, honored by pull/diff/push. pull drops manifest entries + local dirs for a newly-ignored component, reported with action "ignored" (distinct from "removed" = deleted on remote); diff filters the local side too, so a stale dir for an ignored component can never classify as DELETED -- closes the delete-dir-then-push trap that used to destroy production keboola.mcp-server-tool configs.
967
- kbagent sync clone --source DIR --target ALIAS --target-dir DIR [--bucket-map FILE] [--variable-values FILE] [--instance-rename FILE] [--dry-run] [--branch ID]
968
- # `sync clone` (0.63.0+) copies a reference synced tree into a fresh target project + parameterizes it: applies bucket_map / variable_values / instance_rename overrides (JSON/YAML files), then pushes so every config CREATEs fresh -- keboola.flow task configIds and transformation variable links are remapped reference->ULID by push Phase C/D. Idempotent: re-run with an existing --target-dir reports no_changes. Fails fast if the target already contains the reference's configs (clone needs a fresh target). Override files must be flat {id: scalar} mappings (0.89.0+): a nested mapping/list/null value is rejected with CONFIG_ERROR naming the key + actual type, instead of being silently stringified into a bogus ID. `--branch` is optional on a fresh clone. It defaults to the target's production branch, resolved from the API like `sync init`. Pass it only to target a dev branch of the target.
1024
+ kbagent sync clone --source DIR --target ALIAS --target-dir DIR [--bucket-map FILE] [--variable-values FILE] [--instance-rename FILE] [--no-create-buckets] [--dry-run] [--branch ID]
1025
+ # `sync clone` (0.63.0+) copies a reference synced tree into a fresh target project + parameterizes it: applies bucket_map / variable_values / instance_rename overrides (JSON/YAML files), then pushes so every config CREATEs fresh -- keboola.flow and keboola.orchestrator task configIds (and configRowIds), schedule targets, and transformation variable and shared-code links are remapped reference->ULID by push Phase C/D (`link_remaps` counts each kind; a link it cannot set is an `errors[]` entry, and a failed PUT is sent again by the next push). Schedules are never activated and data apps never deployed: `warnings[]` (also on --dry-run, human mode prints them) lists those, copied `KBC::` values the target cannot decrypt, and tasks that run a config not in the tree. Only the run that creates the configs reports them; a re-run returns `warnings: []`. Idempotent: re-run with an existing --target-dir reports no_changes. Fails fast if the target already contains the reference's configs (clone needs a fresh target). Override files must be flat {id: scalar} mappings (0.89.0+): a nested mapping/list/null value is rejected with CONFIG_ERROR naming the key + actual type, instead of being silently stringified into a bogus ID. `--branch` is optional on a fresh clone. It defaults to the target's production branch, resolved from the API like `sync init`. Pass it only to target a dev branch of the target. Clone recreates the reference tree's storage buckets in the target from the `storage/buckets.json` pull export BY DEFAULT -- `--no-create-buckets` skips it. Idempotent: an existing bucket is skipped, a per-bucket failure is collected in `bucket_errors`, a linked (shared) bucket is linked to the same source as in the reference (listed in `linked_buckets`; the source's sharing settings decide, a refused link lands in `bucket_errors`). Only the buckets are created, never their tables or data (the export carries no table data). Version gate in gotchas.md.
969
1026
  kbagent sync branch-link --project ALIAS (--branch-id ID | --branch-name NAME) [--directory DIR]
970
1027
  kbagent sync branch-unlink [--directory DIR]
971
1028
  kbagent sync branch-status [--directory DIR]
@@ -1232,7 +1289,7 @@ kbagent update [--beta]
1232
1289
  # completes discovery first, then does the terminal exact-version reinstall and immediately
1233
1290
  # re-executes; failures print a copy-paste recovery command.
1234
1291
  kbagent changelog [--limit N] [--full]
1235
- # Default shows a one-line summary (first sentence) per version; --full / -v expands every note.
1292
+ # Default shows first sentences: every BREAKING note of a version, plus its first other notes until at least two show; --full / -v expands every note.
1236
1293
  kbagent serve [--host HOST] [--port PORT] [--ui] [--ui-dist PATH] [--reload] [--log-level LVL] [--cors-origin ORIGIN] [--config-dir DIR] [--no-banner]
1237
1294
  # `--config-dir` on serve (since 0.91.0, #679): `serve` is the only subcommand with a --config-dir of
1238
1295
  # its own, and most specific wins -- `serve --config-dir X` beats a root `kbagent --config-dir Y`,
@@ -353,6 +353,8 @@ When adding a new command (e.g., `kbagent storage create-foo`), you must update
353
353
  - [ ] **Service method** in `services/` -- business logic, validation, orchestration
354
354
  - [ ] **Command function** in `commands/` -- Typer options, formatter, error handling
355
355
  - [ ] **Permission registration** in `permissions.py` (`OPERATION_REGISTRY` dict)
356
+ - [ ] **Branch choice** through `resolve_branch()` in `effective_branch.py` when the command takes `--branch` or uses the active branch -- never read `ProjectConfig.active_branch_id` directly. The function reports the branch (`Target:` line, `targets` in `--json`); `tests/test_effective_branch.py` fails on a new direct read.
357
+ - [ ] **`--project` naming a NEW alias** -- every `--project` option also takes a project ID, translated to the alias before the command runs (`commands/_project_ref.py`, CLI-22). A command whose `--project` is not a registry lookup (a new alias like `project add`, an offline filter like `lineage show`) must be added to `NO_LOOKUP_COMMANDS` there, and an option with another name that takes an existing alias (like `config clone --target-project`) to `ALIAS_OPTIONS`. `tests/test_project_ref.py` fails on a new option whose flag contains `project`, `alias` or `stack` until it is in `ALIAS_OPTIONS` or in the test's `NOT_AN_ALIAS` list (with a reason); an option with any other name needs this decision by hand.
356
358
  - [ ] **Service wiring** in `cli.py` if adding a new service class
357
359
  - [ ] **HTTP API endpoint** in `src/keboola_agent_cli/server/routers/<group>.py` -- `kbagent serve` exposes the CLI as a REST API so external applications (Web UI, scheduled AI agents, Slack bots, Streamlit dashboards, CI pipelines) can call the platform without forking CLI subprocesses. The current convention is **1:1**: every command in a group has a matching endpoint in that group's router (e.g. `commands/flow.py` has 8 commands, `server/routers/flows.py` has 8 routes). If you add a new command, add the corresponding route. **Skip allowed** only for genuinely terminal-only commands (interactive prompts, Rich-rendered output that has no useful JSON shape, `doctor`/`init`/`update`-style infrastructure that manages kbagent itself rather than Keboola). Document any skip in the PR description with a one-line reason so reviewers don't flag it.
358
360
 
@@ -402,6 +404,8 @@ before the PR is mergeable.
402
404
 
403
405
  > **Running locally without exporting a token:** if the target project is already registered in a kbagent `config.json`, use config-dir mode -- `make test-e2e-local CONFIG_DIR=/path/to/.kbagent ALIAS=my-proj`. The harness reads the token from `config.json` at import time and promotes it into `E2E_API_TOKEN` / `E2E_URL`; an explicit `E2E_API_TOKEN` still wins.
404
406
 
407
+ - [ ] **API call-count test for hot read paths** -- a new or changed list/detail command that users and agents run often (the `project`/`config`/`job`/`storage`/`flow` read commands and their peers) adds or updates a case in `tests/test_api_call_counts.py`. It pins the exact calls via `helpers.assert_api_calls`, which compares the method and path and, where the test pins them, the parsed query (`include_query=True`) and the token (`include_token=True`, for multi-project cases). List commands also run with 1 and 10 items and expect the same calls at both sizes: this catches a call made once per item, but not a call made once per batch or page of more than 10 items. Fixtures must look like real API payloads (several component types, a transformation with rows and storage mappings, Queue jobs with `runId`, alias and shared tables), because a per-item call that depends on a field the fixture lacks is not caught. The expected lists are a ratchet: raising one is a deliberate, reviewed change -- say why in the PR
408
+
405
409
  - [ ] **Run `make check`** before committing (lint + format + full test suite)
406
410
  - [ ] **Run `make typecheck`** -- `ty` must pass clean (0 diagnostics; the backlog was cleared in 0.45.0, so the gate is blocking, not warning-only)
407
411
  - [ ] **No new `tuple[...]` returns** -- multi-value returns use a `@dataclass` ([Code Quality Patterns](#code-quality-patterns))
@@ -631,7 +635,7 @@ silent-drift risks summarized in the
631
635
  Those merged PRs are **exactly** the scope of the release: the changelog
632
636
  entry and the release notes must cover each of them, and nothing else.
633
637
  2. **Edit `pyproject.toml`** -- bump `version = "X.Y.Z"`. Single source of truth; everything else derives from it. This is the release PR's defining change -- if you are doing this in a feature PR, stop and read the section intro above.
634
- 3. **Add a changelog entry** to `src/keboola_agent_cli/changelog.py` -- ONE entry for the new version, covering **every PR merged since the last release** (step 1), no exceptions. CI fails (`make changelog-check`) if this is missing. Author it as the file's docstring describes: **one logical change per bullet** (split the release into several list items rather than one mega-paragraph), each starting with a recognised prefix (`BREAKING:`, `New:`, `Fix:`, `Change:`, `Note:`, `Security:`, ...), carrying its `(#PR)` reference, and leading with a self-contained first sentence. `kbagent changelog` shows only that first sentence per version by default (the rest is revealed by `--full`), so a buried headline or a single wall-of-text bullet reads as an unscannable blob. The first sentence is also **capped at 160 characters**, enforced by `tests/test_changelog_render.py::TestLiveChangelogHeadlines::test_newest_release_notes_are_not_truncated` (so `make check` in step 12 catches it) -- past the cap the default view and the release page show it cut mid-clause. Write a short self-contained first sentence and put the detail in the sentences after it; 2 of 0.90.0's 13 bullets needed exactly this rewrite.
638
+ 3. **Add a changelog entry** to `src/keboola_agent_cli/changelog.py` -- ONE entry for the new version, covering **every PR merged since the last release** (step 1), no exceptions. CI fails (`make changelog-check`) if this is missing. Author it as the file's docstring describes: **one logical change per bullet** (split the release into several list items rather than one mega-paragraph), each starting with a recognised prefix (`BREAKING:`, `New:`, `Fix:`, `Change:`, `Note:`, `Security:`, ...), carrying its `(#PR)` reference, and leading with a self-contained first sentence. `kbagent changelog` shows only first sentences by default: of every `BREAKING` bullet of a version, plus of the first other bullets until at least two show (the rest is revealed by `--full`). The `What's new` notice after an update shows the first sentence of every bullet. So a buried headline or a single wall-of-text bullet reads as an unscannable blob. The first sentence is also **capped at 160 characters**, enforced by `tests/test_changelog_render.py::TestLiveChangelogHeadlines::test_newest_release_notes_are_not_truncated` (so `make check` in step 12 catches it) -- past the cap the default view and the release page show it cut mid-clause. Write a short self-contained first sentence and put the detail in the sentences after it; 2 of 0.90.0's 13 bullets needed exactly this rewrite.
635
639
  4. **Replace every `vNEXT` placeholder** left behind by the feature PRs with the version being released. Do it mechanically -- never by hand, and never with a repo-wide `sed`:
636
640
  ```bash
637
641
  make vnext-resolve VERSION=X.Y.Z
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: keboola-cli
3
- Version: 0.95.0
3
+ Version: 0.96.0
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
@@ -218,7 +218,7 @@ kbagent workspace query --project prod --workspace-id WS_ID \
218
218
  | **Agent Tasks** | Schedule AI agents inside `kbagent serve` (CRON / manual / chained). Two action flavours per task: `claude` / `codex` / `gemini` with a prompt, or a raw kbagent CLI command. Per-run cost & token timeline with authoritative Claude 4.x pricing built-in; persisted JSONL history (`0600`); live SSE replay; **Artifacts tab** auto-renders long-form markdown reports (GFM tables, Copy / Download `.md`). Subprocesses get `KBAGENT_SERVE_URL` + `KBAGENT_SERVE_TOKEN` auto-injected for self-calls via `kbagent http`. (since 0.40.0) |
219
219
  | **Workspaces** | Create Snowflake/BQ workspace, load tables, run SQL. Create from transformation config for instant debugging. Orphan detection + garbage collection. |
220
220
  | **Sharing** | Cross-project bucket sharing with org/project/user access control. Share, link, unlink. |
221
- | **Data apps** | First-class lifecycle for Streamlit / Flask / Node deployments (`keboola.data-apps`). `create / deploy / start / stop / password / delete` (since 0.27.0); `secrets-set / -list / -get / -remove` for `#`-prefixed runtime secrets with per-project KMS encryption (since 0.29.0); `validate-repo` pre-flight Golden Rule check that catches misconfigured git repos before a deploy (since 0.29.0); `logs` tails the container log buffer for triaging stuck deploys / runtime crashes (since 0.43.8). Hides the redeploy contract and per-project KMS encryption of git PATs. |
221
+ | **Data apps** | First-class lifecycle for Python/JS apps (`keboola.data-apps`; `python-js` is the default type, Streamlit via `--type streamlit`). `create / deploy / start / stop / password / delete` (since 0.27.0); `secrets-set / -list / -get / -remove` for `#`-prefixed runtime secrets with per-project KMS encryption (since 0.29.0); `validate-repo` pre-flight Golden Rule check that catches misconfigured git repos before a deploy (since 0.29.0); `logs` tails the container log buffer for triaging stuck deploys / runtime crashes (since 0.43.8). Hides the redeploy contract and per-project KMS encryption of git PATs. |
222
222
  | **Project members & invitations** | `project invite` (single or `--from-csv` bulk with parallel workers), `project member-list / member-remove / member-set-role`, `project invitation-list / invitation-cancel`. Role whitelist enforced at the CLI layer; Manage API "already invited" treated as `noop` not error (since 0.29.0). |
223
223
  | **Lineage** | Column-level dependency analysis across projects. SQL/Python parsing, AI-enhanced detection, interactive web browser, Mermaid/HTML/ER export. |
224
224
  | **Semantic layer** | Define and manage a metastore semantic model per project — datasets, metrics, relationships, constraints, glossary. Validate (incl. `--deep`), export, diff two models/files, import/promote across projects, AI-assisted `build` from tables. `kbagent semantic-layer ...` (alias `sl`). |
@@ -190,7 +190,7 @@ kbagent workspace query --project prod --workspace-id WS_ID \
190
190
  | **Agent Tasks** | Schedule AI agents inside `kbagent serve` (CRON / manual / chained). Two action flavours per task: `claude` / `codex` / `gemini` with a prompt, or a raw kbagent CLI command. Per-run cost & token timeline with authoritative Claude 4.x pricing built-in; persisted JSONL history (`0600`); live SSE replay; **Artifacts tab** auto-renders long-form markdown reports (GFM tables, Copy / Download `.md`). Subprocesses get `KBAGENT_SERVE_URL` + `KBAGENT_SERVE_TOKEN` auto-injected for self-calls via `kbagent http`. (since 0.40.0) |
191
191
  | **Workspaces** | Create Snowflake/BQ workspace, load tables, run SQL. Create from transformation config for instant debugging. Orphan detection + garbage collection. |
192
192
  | **Sharing** | Cross-project bucket sharing with org/project/user access control. Share, link, unlink. |
193
- | **Data apps** | First-class lifecycle for Streamlit / Flask / Node deployments (`keboola.data-apps`). `create / deploy / start / stop / password / delete` (since 0.27.0); `secrets-set / -list / -get / -remove` for `#`-prefixed runtime secrets with per-project KMS encryption (since 0.29.0); `validate-repo` pre-flight Golden Rule check that catches misconfigured git repos before a deploy (since 0.29.0); `logs` tails the container log buffer for triaging stuck deploys / runtime crashes (since 0.43.8). Hides the redeploy contract and per-project KMS encryption of git PATs. |
193
+ | **Data apps** | First-class lifecycle for Python/JS apps (`keboola.data-apps`; `python-js` is the default type, Streamlit via `--type streamlit`). `create / deploy / start / stop / password / delete` (since 0.27.0); `secrets-set / -list / -get / -remove` for `#`-prefixed runtime secrets with per-project KMS encryption (since 0.29.0); `validate-repo` pre-flight Golden Rule check that catches misconfigured git repos before a deploy (since 0.29.0); `logs` tails the container log buffer for triaging stuck deploys / runtime crashes (since 0.43.8). Hides the redeploy contract and per-project KMS encryption of git PATs. |
194
194
  | **Project members & invitations** | `project invite` (single or `--from-csv` bulk with parallel workers), `project member-list / member-remove / member-set-role`, `project invitation-list / invitation-cancel`. Role whitelist enforced at the CLI layer; Manage API "already invited" treated as `noop` not error (since 0.29.0). |
195
195
  | **Lineage** | Column-level dependency analysis across projects. SQL/Python parsing, AI-enhanced detection, interactive web browser, Mermaid/HTML/ER export. |
196
196
  | **Semantic layer** | Define and manage a metastore semantic model per project — datasets, metrics, relationships, constraints, glossary. Validate (incl. `--deep`), export, diff two models/files, import/promote across projects, AI-assisted `build` from tables. `kbagent semantic-layer ...` (alias `sl`). |
@@ -0,0 +1,130 @@
1
+ # Formal models of the `kbagent sync` engine (issue #792)
2
+
3
+ Pilot: can a small model checker find real bugs in `sync pull | diff | push`?
4
+ `tla/` holds a TLA+ model checked with TLC. `lean/` is a separate Lean
5
+ effort, not covered here.
6
+
7
+ ## What the TLA+ model covers
8
+
9
+ `tla/SyncEngine.tla` is a small finite model of the engine. Every operator
10
+ names the Python function and line range it mirrors.
11
+
12
+ - **Remote**: 2 branches (`prod`, plus `dev` as a copy of prod). There are
13
+ 2 initial config ids, and 2 more ids for configs created during the run.
14
+ Content versions are 0..2. One component (`mcp`) can become ignored.
15
+ - **Local**: 2 trees (`main/`, `devt/`) and 5 directory paths. Each
16
+ `_config.yml` is a record with fields for the component, the id, the name
17
+ and the content. It also carries two abstract bits:
18
+ - `cosm`: a byte-only edit. It changes the RAW sha256 (`pull_hash`) but
19
+ not `config_hash`.
20
+ - `drift`: the local form of the content hashes differently from the
21
+ API's view of the same content (#686).
22
+ - **Manifest**: one entry per id: `branchId`, `path`, `componentId`,
23
+ `pull_hash` (the RAW hash) and `pull_config_hash` (the normalized base).
24
+ - **Actors**:
25
+ - **User**: edit content, cosmetic edit, `rm -rf` a directory,
26
+ `config new` scaffold, `config new --push --output-dir`, mark a
27
+ component ignored.
28
+ - **Remote**: edit, delete (trash looks the same to sync), create a
29
+ config, optionally reusing an existing config's name.
30
+ - **Sync**: `sync pull` (plain / `--force` / `--theirs`), `sync push`, and
31
+ `sync push` aborted by `ENCRYPTION_FAILED` after some of its changes
32
+ were already applied. Any of these can use `--branch` for either
33
+ branch, which also covers `branch use`.
34
+ - `diff` is a pure function that every invariant can call.
35
+ - **Ghost fields**, used only by invariants:
36
+ - lineage (which config a file or remote config descends from);
37
+ - `ed`: the file holds work that is on no remote;
38
+ - `sv`: the remote version the file was last synced with;
39
+ - the user-deleted directories;
40
+ - flags for the last operation.
41
+
42
+ **Abstracted away**:
43
+ - rows, so I10 is not checked;
44
+ - renames and the name-collision suffix (a pull where two configs land on
45
+ one path is disabled);
46
+ - `config_hash_version` / legacy-shape migration;
47
+ - companion code files;
48
+ - dry-run;
49
+ - baseline read-back failures;
50
+ - variable and flow-task backfill.
51
+
52
+ The id pool is bounded: a push that needs more new ids than are free is
53
+ disabled. `PushAbort` applies an arbitrary strict prefix of the changes in
54
+ path/id order. That over-approximates the diff order the code uses.
55
+
56
+ ## How to run
57
+
58
+ The model needs Java 17 and `tla2tools.jar`.
59
+
60
+ ```sh
61
+ cd formal/sync/tla
62
+ java -XX:+UseParallelGC -cp ~/tools/tla/tla2tools.jar tlc2.TLC -workers auto \
63
+ -config SyncEngine.cfg SyncEngine.tla # clean run: invariants that hold
64
+ ./run_all.sh # every invariant, one TLC run each (~15 min)
65
+ ./trace.py out/<NAME>.json # compact counterexample
66
+ ```
67
+
68
+ The depth is bounded by `MaxSteps` (a state constraint). `MaxSteps = 4`
69
+ explores traces of up to 5 actions. BFS returns the shortest counterexample.
70
+
71
+ ## Results (MaxSteps = 4; up to 153k distinct states per run)
72
+
73
+ | Invariant | Result |
74
+ |---|---|
75
+ | I3 ignored component never planned | **holds** (153,077 states; 196,569 at depth 5 on prod only) |
76
+ | I4 diff/push act only on the source tree | **holds** (153,077 states) |
77
+ | I7 never-fetched entry never deleted | **holds** (104,809 states, never-fetched initial entry) |
78
+ | I1 no double create | violated: a promote push re-creates configs on every run; a resurrect followed by an `ENCRYPTION_FAILED` abort also creates a copy |
79
+ | I2 push deletes only user-removed dirs | violated: **pull's stale-entry sweep deletes a directory the same pull just wrote, and the next push deletes the live remote config** |
80
+ | I2b delete requires `--force` | violated: `push()` never reads `force` (S1). Fixed in the code (G); the model is unchanged |
81
+ | I5 pull keeps local work | violated: a remote delete plus a local edit ends with plain or `--force` pull deleting the edited directory silently |
82
+ | I6 push then diff is clean | violated on `--branch` promote (finding D, since fixed in the engine; the TLA model is unchanged). Holds on production only (30,334 states) |
83
+ | I8 manifest matches disk | violated: the stale sweep, and a promote write-back that records a `devt/` entry for a file in `main/` |
84
+ | I9 an aborted push is atomic | violated (strong reading): the changes before the failing one reached the API and the manifest was never saved |
85
+ | I11 no lost remote update | violated: an adopted file with a config id is diffed 2-way, so push reverts a UI edit |
86
+ | I11b no silent resurrect | violated: a remote delete followed by any push re-creates the config, even with no local edit (S2). Fixed in the code (H); the model is unchanged |
87
+ | I12 a pull resolves REMOTE MODIFIED | violated: after a cosmetic edit, plain pull skips the file forever and `--force` raises a conflict (S3) |
88
+
89
+ Each violation was checked against the code. The main ones were replayed
90
+ against the real `SyncService` with a stateful fake API (the scratch harness
91
+ from the #792 pilot). Details are in the pilot report.
92
+
93
+ ## Consolidated findings (A..K)
94
+
95
+ The spec's suspicious spots (S1..S5), the Lean refutations (F1..F8) and the
96
+ TLA+ counterexamples (I1..I12) overlap heavily -- several independently
97
+ rediscover the same code path. This table is the deduplicated result, with
98
+ the regression test for each in `tests/test_sync_formal_counterexamples.py`.
99
+
100
+ | ID | Finding | Sources | Severity | Test |
101
+ |----|---------|---------|----------|------|
102
+ | A | Remote delete + recreate under the same name: pull writes the new config into the old directory, the stale sweep then deletes that directory; the next push DELETEs the live new config | Lean F8, TLA I2 | HIGH -- **fixed** (#792 A/C PR) | `test_a_recreate_under_same_name_does_not_delete_new_config` |
103
+ | B | Pull compares only `_config.yml`: local edits in `transform.sql`/`code.py`/`_description.md` are silently overwritten when the remote changed, no SYNC_CONFLICT | Lean F6 | HIGH -- **FIXED** (pull's local-modification check now covers every `pull_extra_hashes` companion file) | `test_b_pull_never_overwrites_local_sql_edit` (unmarked regression guard) + `tests/test_sync_pull_companion_files.py` |
104
+ | C | Remote delete + local edit: pull (plain/`--force`) deletes the locally-edited directory with no conflict | Lean F7, TLA I5 | HIGH -- **fixed** (#792 A/C PR) | `test_c_pull_never_deletes_locally_edited_dir_on_remote_delete` |
105
+ | D | `sync push --branch dev` (promote) creates another dev copy of a prod-only config on every push. **Fixed** (fix/792-dev-promote-duplicates): on the promote path the target-branch entry shadows the production entry for the same `main/` dir (`sync/branch_scope.py::_promoted_paths`) | TLA I6/I1 | HIGH | `test_d_promote_push_is_idempotent`, `test_d_promote_push_diff_is_clean_and_edits_update_the_dev_copy` (regression guards) |
106
+ | E | An untracked file carrying a config id (`config new --push --output-dir` scaffold / adopted orphan) is diffed 2-way: push overwrites a UI edit made after the scaffold was written | TLA I11 | MED | `test_e_adopted_scaffold_push_does_not_overwrite_remote_edit` |
107
+ | F | A push aborted by `ENCRYPTION_FAILED` leaves the manifest unsaved; the retry duplicates the change(s) the aborted push already applied | TLA I1b (model trace only; replayed live for this pilot) | MED | `test_f_aborted_push_does_not_duplicate_already_created_config` |
108
+ | G | `sync push` deletes remote configs with no `--force`; the CLI help text says `--force` gates deletion (soft delete to trash since 0.89.0, restorable) | Spec S1, Lean F1, TLA I2b | MED -- **fixed** (push deletes only with `--force`) | `test_g_push_without_force_does_not_delete_remote_config` |
109
+ | H | A config deleted remotely by another actor is silently re-created by the next push, no warning | Spec S2, Lean F2, TLA I11b | MED -- **fixed** (diff reports `remote_deleted`, push skips it) | `test_h_push_does_not_silently_resurrect_deleted_config` |
110
+ | I | Moving a config's directory by hand (`mv`/`git mv`) is seen as remote DELETE + CREATE under a new id | Lean F3 | LOW-MED | `test_i_moving_config_dir_is_not_delete_plus_create` |
111
+ | J | `sync pull --branch dev` reports untouched production configs as "removed" | Spec S4 | LOW | `test_j_branch_scoped_pull_does_not_report_other_branch_configs_removed` |
112
+ | K | A cosmetic local edit (raw vs normalized hash) blocks pull from ever applying a real remote change; `--force` raises a conflict | Spec S3, TLA I12 | LOW (documented, conservative behavior) | `test_k_cosmetic_edit_is_conservative_not_unsafe` (unmarked regression guard, not xfail) |
113
+
114
+ **A and C are fixed**: a new config never lands on a stale entry's directory
115
+ (it gets a suffixed path), the sweep never deletes a path an entry of the same
116
+ pull owns, and a locally edited directory whose remote vanished is kept and
117
+ reported as `skipped` by plain pull, raises `SYNC_CONFLICT` under `--force`,
118
+ and is deleted only by `--theirs`. That is what the I2 (sweep half), I5 and I8
119
+ (sweep half) counterexamples needed; the models themselves are unchanged, so a
120
+ TLC/Lean rerun still reports them until the model's `Pull` is updated to match.
121
+ Their tests are ordinary regression guards now.
122
+
123
+ E, F and I reproduce on current code and are `xfail(strict=True)` (D, G and H
124
+ are fixed) -- flipping to a hard failure the moment a fix lands is the point:
125
+ delete the `xfail` marker to adopt the fix. F's test now reaches the aborted
126
+ create through a promote push, because push no longer re-creates the
127
+ remote-deleted config its first version used. J reproduces and
128
+ is `xfail`. K is deliberate, documented behavior, so it is an ordinary
129
+ (unmarked) regression guard instead. B is fixed: its marker was removed
130
+ and the test is now an ordinary regression guard.
@@ -10,12 +10,15 @@ directory between a SOURCE Keboola project (e.g. dev) and a DESTINATION project
10
10
  Pulls every pipeline's directory from its SOURCE project and opens/updates
11
11
  one PR against the main branch with the combined diff.
12
12
  2. kbagent-promote-validate.yml (pull_request against main)
13
- For every pipeline, runs `sync push --dry-run` against the DESTINATION
14
- project -- this is the cross-project diff: "if this PR merges, here is
15
- exactly what changes in the destination project."
13
+ For every pipeline, runs `sync push --dry-run --force` against the
14
+ DESTINATION project -- this is the cross-project diff: "if this PR merges,
15
+ here is exactly what changes in the destination project."
16
16
  3. kbagent-promote-push.yml (push to main, environment-gated)
17
17
  Pushes every pipeline's directory to its DESTINATION project once the PR
18
- has merged.
18
+ has merged, with `--force`: a config deleted in the SOURCE is deleted in
19
+ the DESTINATION too. Without `--force`, `sync push` deletes nothing
20
+ (since 0.96.0, #792), and the validate dry-run passes it for the same
21
+ reason, so it shows what the push does.
19
22
 
20
23
  Each pipeline needs two Storage API token secrets (`KBC_TOKEN_<NAME>_SOURCE` /
21
24
  `KBC_TOKEN_<NAME>_DEST`) and uses kbagent's `KBAGENT_PROJECT_FROM_ENV=1` /
@@ -364,7 +367,7 @@ def gen_validate(pipelines: list[Pipeline]) -> str:
364
367
  _pipeline_step(
365
368
  p,
366
369
  "Destination dry-run",
367
- "push --dry-run",
370
+ "push --dry-run --force",
368
371
  p.dest_token_secret,
369
372
  p.dest_stack_url,
370
373
  json_output=True,
@@ -414,7 +417,9 @@ def _push_job(p: Pipeline) -> str:
414
417
  f"{_INSTALL_TOKEN}"
415
418
  " # `sync push` encrypts #-secrets fail-closed by default. Do NOT add\n"
416
419
  " # --allow-plaintext-on-encrypt-failure in CI.\n"
417
- f"{_pipeline_step(p, 'Push', 'push', p.dest_token_secret, p.dest_stack_url)}"
420
+ " # --force: a config deleted in the source is deleted here too;\n"
421
+ " # without it, `sync push` deletes nothing.\n"
422
+ f"{_pipeline_step(p, 'Push', 'push --force', p.dest_token_secret, p.dest_stack_url)}"
418
423
  )
419
424
 
420
425
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "keboola-cli"
3
- version = "0.95.0"
3
+ version = "0.96.0"
4
4
  description = "AI-friendly CLI for managing Keboola projects"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -4,7 +4,7 @@
4
4
  "commands/config.py": 2007,
5
5
  "commands/lineage.py": 1271,
6
6
  "commands/storage.py": 2221,
7
- "services/data_app_service.py": 1641,
7
+ "services/data_app_service.py": 1633,
8
8
  "services/storage_service.py": 1684,
9
9
  "services/sync_service.py": 1655
10
10
  }
@@ -168,7 +168,7 @@ def detect_browser_environment() -> BrowserEnvironment:
168
168
  return BrowserEnvironment(loopback_browser_usable=True, reason="", opener=opener)
169
169
 
170
170
 
171
- def open_browser(url: str) -> bool:
171
+ def open_browser(url: str, *, wait_seconds: float = 0.0) -> bool:
172
172
  """Best-effort `webbrowser.open` on a daemon thread.
173
173
 
174
174
  Never raises and never logs ``url`` -- it carries the PKCE code
@@ -177,13 +177,21 @@ def open_browser(url: str) -> bool:
177
177
  before spawning the thread) and True once the open has been dispatched;
178
178
  a True return does not guarantee a browser window actually appeared, only
179
179
  that a handler accepted the request.
180
+
181
+ ``wait_seconds`` joins the thread for up to that long. A caller that exits
182
+ right after the call (``data-app password --open``) passes it, because a
183
+ daemon thread dies with the process -- possibly before the opener starts.
184
+ The login flow keeps polling afterwards, so it leaves the default 0.
180
185
  """
181
186
  try:
182
187
  webbrowser.get()
183
188
  except webbrowser.Error:
184
189
  return False
185
190
 
186
- threading.Thread(target=_open_silently, args=(url,), daemon=True).start()
191
+ thread = threading.Thread(target=_open_silently, args=(url,), daemon=True)
192
+ thread.start()
193
+ if wait_seconds > 0:
194
+ thread.join(timeout=wait_seconds)
187
195
  return True
188
196
 
189
197
 
@@ -34,6 +34,7 @@ from .services.version_service import (
34
34
  KbagentUpdatePlan,
35
35
  _fetch_kbagent_latest_version,
36
36
  _is_up_to_date,
37
+ build_hardlink_retry_command,
37
38
  build_kbagent_upgrade_command,
38
39
  get_update_timeout,
39
40
  prepare_kbagent_update_plan,
@@ -414,6 +415,7 @@ def _schedule_deferred_update(plan: KbagentUpdatePlan) -> None:
414
415
  target_version=target,
415
416
  install_command=plan.command,
416
417
  recovery_command=plan.recovery_command,
418
+ hardlink_retry_command=build_hardlink_retry_command(plan.command),
417
419
  )
418
420
  if request_deferred_update(request):
419
421
  sys.stderr.write(