keboola-cli 0.98.0__tar.gz → 0.99.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 (626) hide show
  1. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/CLAUDE.md +70 -11
  2. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/PKG-INFO +32 -6
  3. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/README.md +31 -5
  4. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/formal/sync/README.md +8 -8
  5. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/pyproject.toml +1 -1
  6. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/file_size_baseline.json +1 -1
  7. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/auth_client.py +3 -3
  8. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/environment.py +39 -6
  9. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auto_update.py +54 -17
  10. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/changelog.py +50 -0
  11. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/storage_tables.py +101 -37
  12. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_config_oauth.py +60 -7
  13. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_helpers.py +277 -9
  14. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/config.py +10 -2
  15. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/context.py +107 -27
  16. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/data_app.py +10 -1
  17. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/lineage.py +6 -3
  18. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/permissions.py +21 -6
  19. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/project.py +58 -43
  20. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/storage.py +37 -1
  21. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/token.py +1 -1
  22. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/workspace.py +19 -8
  23. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/config_store.py +1 -1
  24. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/constants.py +24 -0
  25. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/data_science_client.py +4 -7
  26. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/errors.py +21 -2
  27. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/metastore_client.py +1 -1
  28. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/permissions.py +37 -5
  29. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/_serve_command_map.py +1 -0
  30. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/app.py +44 -1
  31. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/dependencies.py +16 -0
  32. keboola_cli-0.99.0/src/keboola_agent_cli/server/route_permissions.py +532 -0
  33. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/data_apps.py +2 -0
  34. keboola_cli-0.99.0/src/keboola_agent_cli/server/routers/permissions.py +63 -0
  35. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +96 -7
  36. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/storage.py +8 -0
  37. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/workspaces.py +2 -1
  38. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_data_app_bodies.py +270 -5
  39. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_encryption.py +15 -0
  40. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_storage_jobs.py +58 -12
  41. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_baseline.py +44 -1
  42. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_push_ops.py +113 -1
  43. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_writeback.py +5 -1
  44. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/auth_service.py +22 -2
  45. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/component_service.py +27 -6
  46. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/config_service.py +1 -1
  47. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/data_app_service.py +28 -79
  48. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/deep_lineage_service.py +2 -1
  49. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/storage_service.py +33 -4
  50. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/sync_service.py +22 -41
  51. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/token_service.py +1 -1
  52. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/version_service.py +12 -2
  53. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/workspace_service.py +180 -55
  54. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/branch_registry.py +26 -0
  55. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/config_format.py +7 -0
  56. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/diff_engine.py +18 -1
  57. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_environment.py +133 -0
  58. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_sentinel_guards.py +1 -1
  59. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_service.py +82 -0
  60. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auto_update.py +170 -16
  61. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_registry.py +79 -0
  62. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_cli.py +129 -3
  63. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_cli_auth.py +74 -4
  64. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_component_service.py +40 -0
  65. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_create_cli.py +24 -0
  66. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_row_cli.py +219 -0
  67. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_cli.py +45 -0
  68. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_service.py +323 -6
  69. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_deep_lineage_service.py +37 -0
  70. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e.py +16 -3
  71. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_effective_branch.py +20 -0
  72. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_helpers.py +324 -2
  73. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_permissions_cli.py +33 -0
  74. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_edit_cli.py +209 -2
  75. keboola_cli-0.99.0/tests/test_project_token_stdin_no_leak.py +289 -0
  76. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_telemetry.py +11 -1
  77. keboola_cli-0.99.0/tests/test_server_route_permissions.py +828 -0
  78. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_router_calls.py +126 -4
  79. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_smoke.py +2 -1
  80. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_create_table.py +62 -0
  81. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_import_jobs.py +21 -1
  82. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_swap.py +315 -1
  83. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_write.py +200 -0
  84. keboola_cli-0.99.0/tests/test_sync_adopted_files.py +275 -0
  85. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_diff_engine.py +51 -0
  86. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_formal_counterexamples.py +23 -44
  87. keboola_cli-0.99.0/tests/test_sync_push_encrypt_first.py +261 -0
  88. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_reconcile.py +18 -12
  89. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_service.py +10 -9
  90. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_version_service.py +18 -0
  91. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_cli.py +51 -3
  92. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_service.py +422 -10
  93. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/package-lock.json +6 -6
  94. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/package.json +2 -1
  95. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/.gitignore +0 -0
  96. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/CONTRIBUTING.md +0 -0
  97. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/LICENSE +0 -0
  98. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/Makefile +0 -0
  99. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/examples/README.md +0 -0
  100. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/examples/storage_tui/README.md +0 -0
  101. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
  102. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/plugins/kbagent/skills/kbagent-cicd-migration/scripts/migrate_cicd.py +0 -0
  103. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py +0 -0
  104. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_command_sync.py +0 -0
  105. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_error_codes.py +0 -0
  106. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_file_size.py +0 -0
  107. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_release_scope.py +0 -0
  108. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_sentinel_guards.py +0 -0
  109. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_version_gates.py +0 -0
  110. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_wheel_ui.py +0 -0
  111. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/debug_linkedby_type.sh +0 -0
  112. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/gen_command_reference.py +0 -0
  113. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/gen_endpoint_reference.py +0 -0
  114. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/gen_release_notes.py +0 -0
  115. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/generate_changelog.py +0 -0
  116. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/generate_skill.py +0 -0
  117. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/hatch_build.py +0 -0
  118. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/lineage_deep.py +0 -0
  119. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/post-edit-quality.sh +0 -0
  120. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/pre-commit +0 -0
  121. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/sync_version.py +0 -0
  122. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/web-dev.sh +0 -0
  123. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/__init__.py +0 -0
  124. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/__main__.py +0 -0
  125. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/ai_client.py +0 -0
  126. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/__init__.py +0 -0
  127. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/device.py +0 -0
  128. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/models.py +0 -0
  129. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/pkce.py +0 -0
  130. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/sentinel.py +0 -0
  131. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/state_store.py +0 -0
  132. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/token_provider.py +0 -0
  133. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/totp.py +0 -0
  134. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/cli.py +0 -0
  135. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/__init__.py +0 -0
  136. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_client.py +0 -0
  137. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_core.py +0 -0
  138. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_s3_multipart.py +0 -0
  139. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_transfer.py +0 -0
  140. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/billing.py +0 -0
  141. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/branches.py +0 -0
  142. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/configs.py +0 -0
  143. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/editor.py +0 -0
  144. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/merge_requests.py +0 -0
  145. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/misc.py +0 -0
  146. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/notifications.py +0 -0
  147. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/query.py +0 -0
  148. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/queue.py +0 -0
  149. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/storage_files.py +0 -0
  150. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/stream.py +0 -0
  151. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/tokens.py +0 -0
  152. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/triggers.py +0 -0
  153. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/workspaces.py +0 -0
  154. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
  155. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_auth_picker.py +0 -0
  156. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_checkbox_select.py +0 -0
  157. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_config_clone_cmd.py +0 -0
  158. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_config_trash_cmd.py +0 -0
  159. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
  160. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_data_app_password.py +0 -0
  161. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
  162. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_flow_triggers.py +0 -0
  163. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_merge_request_common.py +0 -0
  164. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_merge_request_render.py +0 -0
  165. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_merge_request_writes.py +0 -0
  166. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
  167. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_progress.py +0 -0
  168. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_project_create.py +0 -0
  169. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_project_ref.py +0 -0
  170. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
  171. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
  172. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
  173. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_scope.py +0 -0
  174. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_describe.py +0 -0
  175. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_jobs.py +0 -0
  176. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
  177. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_table_detail.py +0 -0
  178. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_tables_render.py +0 -0
  179. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_sync_clone_render.py +0 -0
  180. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_sync_push_render.py +0 -0
  181. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_url_copy.py +0 -0
  182. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/agent.py +0 -0
  183. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/auth.py +0 -0
  184. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/billing.py +0 -0
  185. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/branch.py +0 -0
  186. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/changelog.py +0 -0
  187. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/component.py +0 -0
  188. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/config_state.py +0 -0
  189. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
  190. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/docs.py +0 -0
  191. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
  192. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
  193. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/feature.py +0 -0
  194. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/flow.py +0 -0
  195. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
  196. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/init.py +0 -0
  197. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/job.py +0 -0
  198. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/kai.py +0 -0
  199. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/merge_request.py +0 -0
  200. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/notification.py +0 -0
  201. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/org.py +0 -0
  202. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/repl.py +0 -0
  203. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/schedule.py +0 -0
  204. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/search.py +0 -0
  205. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
  206. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/serve.py +0 -0
  207. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
  208. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/stream.py +0 -0
  209. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/sync.py +0 -0
  210. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/transformation.py +0 -0
  211. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/version.py +0 -0
  212. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
  213. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/effective_branch.py +0 -0
  214. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/frozen_dist.py +0 -0
  215. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/http_base.py +0 -0
  216. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/json_utils.py +0 -0
  217. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/lib.py +0 -0
  218. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/manage_client.py +0 -0
  219. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/models.py +0 -0
  220. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/output.py +0 -0
  221. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/project_ref.py +0 -0
  222. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/py.typed +0 -0
  223. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/__init__.py +0 -0
  224. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
  225. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
  226. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
  227. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
  228. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
  229. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/result_models.py +0 -0
  230. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/scheduler_client.py +0 -0
  231. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/__init__.py +0 -0
  232. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
  233. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
  234. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/auth.py +0 -0
  235. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/pricing.py +0 -0
  236. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
  237. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
  238. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
  239. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/auth.py +0 -0
  240. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/billing.py +0 -0
  241. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
  242. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
  243. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/configs.py +0 -0
  244. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
  245. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/docs.py +0 -0
  246. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
  247. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
  248. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
  249. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
  250. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
  251. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
  252. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
  253. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
  254. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/merge_requests.py +0 -0
  255. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/notifications.py +0 -0
  256. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
  257. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/projects.py +0 -0
  258. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
  259. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
  260. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
  261. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
  262. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/token.py +0 -0
  263. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
  264. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
  265. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/sse.py +0 -0
  266. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/__init__.py +0 -0
  267. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_auth_registration.py +0 -0
  268. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_column_descriptions.py +0 -0
  269. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_config_clone.py +0 -0
  270. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_config_set_guard.py +0 -0
  271. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_config_trash.py +0 -0
  272. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_data_app_password.py +0 -0
  273. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_describe_batch_input.py +0 -0
  274. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
  275. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
  276. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_fqn.py +0 -0
  277. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
  278. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
  279. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
  280. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_scope.py +0 -0
  281. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_storage_downloads.py +0 -0
  282. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_storage_tables.py +0 -0
  283. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
  284. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
  285. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
  286. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
  287. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_clone_warnings.py +0 -0
  288. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_data_app.py +0 -0
  289. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_models.py +0 -0
  290. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_stale.py +0 -0
  291. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
  292. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_workspace.py +0 -0
  293. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_table_detail.py +0 -0
  294. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_token_last_used.py +0 -0
  295. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
  296. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_workspace_load_plan.py +0 -0
  297. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
  298. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/base.py +0 -0
  299. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/billing_service.py +0 -0
  300. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/branch_service.py +0 -0
  301. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
  302. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
  303. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/docs_service.py +0 -0
  304. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
  305. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
  306. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/feature_service.py +0 -0
  307. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/flow_service.py +0 -0
  308. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
  309. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
  310. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
  311. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/job_service.py +0 -0
  312. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
  313. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
  314. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/member_service.py +0 -0
  315. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/merge_request_service.py +0 -0
  316. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/notification_service.py +0 -0
  317. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/org_service.py +0 -0
  318. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/project_service.py +0 -0
  319. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
  320. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/schedule_service.py +0 -0
  321. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/search_service.py +0 -0
  322. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
  323. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
  324. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
  325. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
  326. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/table_usage.py +0 -0
  327. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/transformation_service.py +0 -0
  328. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
  329. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/stream_client.py +0 -0
  330. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
  331. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
  332. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/branch_scope.py +0 -0
  333. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/clone.py +0 -0
  334. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
  335. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
  336. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/manifest.py +0 -0
  337. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/naming.py +0 -0
  338. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
  339. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
  340. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/telemetry.py +0 -0
  341. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/update_runner.py +0 -0
  342. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/yaml_input.py +0 -0
  343. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/__init__.py +0 -0
  344. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/conftest.py +0 -0
  345. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/helpers.py +0 -0
  346. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_cli.py +0 -0
  347. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_prompt.py +0 -0
  348. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_prompt_helper.py +0 -0
  349. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_runner.py +0 -0
  350. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_service.py +0 -0
  351. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_tombstone.py +0 -0
  352. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agents_store_events.py +0 -0
  353. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_ai_client.py +0 -0
  354. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_api_call_counts.py +0 -0
  355. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_client.py +0 -0
  356. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_device.py +0 -0
  357. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_models.py +0 -0
  358. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_picker.py +0 -0
  359. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_pkce.py +0 -0
  360. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_register_projects.py +0 -0
  361. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_sentinel.py +0 -0
  362. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_state_store.py +0 -0
  363. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_totp.py +0 -0
  364. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_base_service.py +0 -0
  365. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_billing_cli.py +0 -0
  366. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_billing_client.py +0 -0
  367. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_billing_service.py +0 -0
  368. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_metadata_cli.py +0 -0
  369. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_metadata_service.py +0 -0
  370. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_service.py +0 -0
  371. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_build_hook.py +0 -0
  372. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_changelog_check.py +0 -0
  373. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_changelog_render.py +0 -0
  374. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_command_sync.py +0 -0
  375. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_file_size.py +0 -0
  376. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_release_scope.py +0 -0
  377. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_sentinel_guards.py +0 -0
  378. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_version_gates.py +0 -0
  379. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_checkbox_select.py +0 -0
  380. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_choice_enums.py +0 -0
  381. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_client.py +0 -0
  382. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_client_device_enrollment.py +0 -0
  383. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_client_token_events.py +0 -0
  384. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_component_cli.py +0 -0
  385. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_component_sync_action.py +0 -0
  386. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_clone_cli.py +0 -0
  387. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_clone_service.py +0 -0
  388. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_create_service.py +0 -0
  389. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_encryption.py +0 -0
  390. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_examples.py +0 -0
  391. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_metadata.py +0 -0
  392. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_rename.py +0 -0
  393. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_rename_cli.py +0 -0
  394. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_resolution.py +0 -0
  395. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_row_service.py +0 -0
  396. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_search.py +0 -0
  397. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_search_cli.py +0 -0
  398. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_set_default_bucket.py +0 -0
  399. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_set_guard.py +0 -0
  400. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_state.py +0 -0
  401. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_store.py +0 -0
  402. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_trash.py +0 -0
  403. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_update.py +0 -0
  404. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_git_repo.py +0 -0
  405. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_password.py +0 -0
  406. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_plain_env_keys.py +0 -0
  407. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_secrets_cli.py +0 -0
  408. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_secrets_service.py +0 -0
  409. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_validate_repo_service.py +0 -0
  410. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_dev_portal_cli.py +0 -0
  411. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_dev_portal_client.py +0 -0
  412. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_dev_portal_service.py +0 -0
  413. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_docs_cli.py +0 -0
  414. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_doctor_service.py +0 -0
  415. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e_auth.py +0 -0
  416. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e_config_dir_mode.py +0 -0
  417. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e_lineage_deep.py +0 -0
  418. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_encrypt_cli.py +0 -0
  419. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_encrypt_service.py +0 -0
  420. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_encryption.py +0 -0
  421. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_errors.py +0 -0
  422. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_feature_cli.py +0 -0
  423. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_feature_service.py +0 -0
  424. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_file_locking.py +0 -0
  425. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_cli.py +0 -0
  426. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_examples.py +0 -0
  427. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_service.py +0 -0
  428. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_validation.py +0 -0
  429. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_frozen_dist.py +0 -0
  430. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_gen_command_reference.py +0 -0
  431. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_gen_endpoint_reference.py +0 -0
  432. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_gen_release_notes.py +0 -0
  433. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_generate_promotion_pipeline.py +0 -0
  434. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_base.py +0 -0
  435. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_base_auth.py +0 -0
  436. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_client_cmd.py +0 -0
  437. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_forwarder_service.py +0 -0
  438. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_integration.py +0 -0
  439. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_job_idempotency_store.py +0 -0
  440. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_job_options.py +0 -0
  441. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_json_utils.py +0 -0
  442. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_kai_cli.py +0 -0
  443. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_kai_service.py +0 -0
  444. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_lib.py +0 -0
  445. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_lib_device_enrollment.py +0 -0
  446. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_license_consistency.py +0 -0
  447. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_lineage_service.py +0 -0
  448. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_local_ai_chat.py +0 -0
  449. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_manage_client.py +0 -0
  450. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_manage_token_bulk.py +0 -0
  451. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_manage_token_cli.py +0 -0
  452. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_mcp_migration_recipe.py +0 -0
  453. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_member_cli.py +0 -0
  454. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_member_service.py +0 -0
  455. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_merge_request_cli.py +0 -0
  456. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_merge_request_client.py +0 -0
  457. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_merge_request_service.py +0 -0
  458. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_metastore_client.py +0 -0
  459. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_migrate_cicd.py +0 -0
  460. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_models.py +0 -0
  461. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_normalize_script.py +0 -0
  462. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_notification_cli.py +0 -0
  463. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_notification_client.py +0 -0
  464. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_notification_service.py +0 -0
  465. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_org_service.py +0 -0
  466. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_output.py +0 -0
  467. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_partial_failure_exit_code.py +0 -0
  468. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_permissions.py +0 -0
  469. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_pricing.py +0 -0
  470. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_create_cli.py +0 -0
  471. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_edit.py +0 -0
  472. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_info_cli.py +0 -0
  473. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_info_service.py +0 -0
  474. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_ref.py +0 -0
  475. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_release_kbagent_ai_kit_sync.py +0 -0
  476. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_repl.py +0 -0
  477. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_result_models.py +0 -0
  478. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_run_broadcaster.py +0 -0
  479. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_s3_multipart.py +0 -0
  480. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_schedule_cli.py +0 -0
  481. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_schedule_service.py +0 -0
  482. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_scheduler_client.py +0 -0
  483. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_search_cli.py +0 -0
  484. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_search_service.py +0 -0
  485. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_cli.py +0 -0
  486. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_schema.py +0 -0
  487. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_scope.py +0 -0
  488. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_scope_cli.py +0 -0
  489. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_service.py +0 -0
  490. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_banner_encoding.py +0 -0
  491. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_conversation_id.py +0 -0
  492. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_ui.py +0 -0
  493. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_auth.py +0 -0
  494. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_permissions.py +0 -0
  495. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_project_ref.py +0 -0
  496. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
  497. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_services.py +0 -0
  498. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sharing_cli.py +0 -0
  499. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sharing_service.py +0 -0
  500. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_skill_frontmatter.py +0 -0
  501. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sql_split.py +0 -0
  502. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_clone.py +0 -0
  503. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_delete.py +0 -0
  504. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_describe_cli.py +0 -0
  505. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_describe_service.py +0 -0
  506. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_empty_definition.py +0 -0
  507. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_export_filters.py +0 -0
  508. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_files.py +0 -0
  509. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_snapshots.py +0 -0
  510. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_table_definition.py +0 -0
  511. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_tables.py +0 -0
  512. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_truncate.py +0 -0
  513. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_stream_cli.py +0 -0
  514. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_stream_client.py +0 -0
  515. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_stream_service.py +0 -0
  516. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_baseline_stamping.py +0 -0
  517. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_branch_mapping.py +0 -0
  518. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_branch_scope.py +0 -0
  519. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_cli.py +0 -0
  520. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_cli_behavior.py +0 -0
  521. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_clone.py +0 -0
  522. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_clone_links.py +0 -0
  523. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_code_extraction.py +0 -0
  524. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_config_format.py +0 -0
  525. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_data_app_type.py +0 -0
  526. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_e2e.py +0 -0
  527. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_encrypt.py +0 -0
  528. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_force_pull_baseline.py +0 -0
  529. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_manifest.py +0 -0
  530. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_naming.py +0 -0
  531. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_plaintext_audit.py +0 -0
  532. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_pull_companion_files.py +0 -0
  533. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_push_script_guard.py +0 -0
  534. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_secrets.py +0 -0
  535. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_storage_jobs.py +0 -0
  536. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_version_script.py +0 -0
  537. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_workspaces.py +0 -0
  538. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_table_usage.py +0 -0
  539. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_telemetry.py +0 -0
  540. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_token_cli.py +0 -0
  541. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_token_provider.py +0 -0
  542. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_token_service.py +0 -0
  543. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_transfer_progress.py +0 -0
  544. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_transformation_cli.py +0 -0
  545. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_transformation_ops.py +0 -0
  546. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_triggers_client.py +0 -0
  547. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_update_runner.py +0 -0
  548. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_url_copy.py +0 -0
  549. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_variables_cli.py +0 -0
  550. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_variables_service.py +0 -0
  551. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_gc.py +0 -0
  552. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_sql_helper.py +0 -0
  553. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_yaml_input.py +0 -0
  554. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/README.md +0 -0
  555. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/index.html +0 -0
  556. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/postcss.config.js +0 -0
  557. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/App.tsx +0 -0
  558. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/api/client.test.ts +0 -0
  559. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/api/client.ts +0 -0
  560. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/changelogNotes.test.ts +0 -0
  561. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/changelogNotes.ts +0 -0
  562. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
  563. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/CommandPalette.tsx +0 -0
  564. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/ConfirmModal.tsx +0 -0
  565. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/DetailTabs.tsx +0 -0
  566. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/Drawer.tsx +0 -0
  567. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/Empty.tsx +0 -0
  568. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/JsonView.tsx +0 -0
  569. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/KeyValueGrid.tsx +0 -0
  570. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
  571. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/PillList.tsx +0 -0
  572. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/RawDetail.tsx +0 -0
  573. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/SessionExpiredBanner.tsx +0 -0
  574. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/Table.tsx +0 -0
  575. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/WhatsNew.tsx +0 -0
  576. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/config/credits.test.ts +0 -0
  577. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/config/credits.ts +0 -0
  578. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/index.css +0 -0
  579. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/Shell.tsx +0 -0
  580. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
  581. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
  582. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/TopBar.tsx +0 -0
  583. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/lib/time.test.ts +0 -0
  584. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/lib/time.ts +0 -0
  585. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/main.tsx +0 -0
  586. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Agents.tsx +0 -0
  587. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Branches.tsx +0 -0
  588. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Changelog.tsx +0 -0
  589. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Components.tsx +0 -0
  590. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Configs.tsx +0 -0
  591. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
  592. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/DataApps.tsx +0 -0
  593. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Doctor.tsx +0 -0
  594. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
  595. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Flows.tsx +0 -0
  596. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Jobs.tsx +0 -0
  597. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/JobsAll.tsx +0 -0
  598. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Lineage.tsx +0 -0
  599. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
  600. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Members.tsx +0 -0
  601. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Org.tsx +0 -0
  602. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Projects.tsx +0 -0
  603. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Schedules.tsx +0 -0
  604. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Search.tsx +0 -0
  605. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
  606. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
  607. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Sharing.tsx +0 -0
  608. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Storage.tsx +0 -0
  609. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Streams.tsx +0 -0
  610. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Tokens.tsx +0 -0
  611. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/TokensAll.tsx +0 -0
  612. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
  613. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/jobsShared.tsx +0 -0
  614. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/storageSel.test.ts +0 -0
  615. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/tokensShared.test.ts +0 -0
  616. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/tokensShared.tsx +0 -0
  617. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/router.test.ts +0 -0
  618. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/router.ts +0 -0
  619. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/state.tsx +0 -0
  620. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/theme.tsx +0 -0
  621. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/types.ts +0 -0
  622. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/useHashSelection.ts +0 -0
  623. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/whatsnew.ts +0 -0
  624. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/tailwind.config.ts +0 -0
  625. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/tsconfig.json +0 -0
  626. {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/vite.config.ts +0 -0
@@ -467,7 +467,7 @@ kbagent auth register-projects [--stack URL|alias] [--all] [--project-id ID ...]
467
467
  # bearer token, and revoking the session is a host-operator action, not a remote one. `/auth/*`
468
468
  # is also the FIRST router to enforce the `permissions` policy: every route declares
469
469
  # `Depends(require_permission(...))`, so a denial answers HTTP 403 `PERMISSION_DENIED` over REST
470
- # exactly as on the CLI. The other ~30 routers do not check the engine yet.
470
+ # exactly as on the CLI. Every other route is checked too since #655 (see `permissions` below).
471
471
  # The policy comes from the config dir `serve` RESOLVES (its own `--config-dir`, then -- since
472
472
  # 0.91.0, #679 -- an explicit root `kbagent --config-dir`, then KBAGENT_CONFIG_DIR, then the
473
473
  # local/global chain) plus the session flags of the invocation. On 0.90.1 the root-level
@@ -479,7 +479,7 @@ kbagent auth register-projects [--stack URL|alias] [--all] [--project-id ID ...]
479
479
  # the allow list. `kbagent --deny-writes serve` does NOT work: `serve` is admin-class and
480
480
  # `--deny-writes` appends `cli:write`, which spans write+destructive+admin, so the CLI callback
481
481
  # blocks the `serve` command itself (exit 6) and no server ever starts. `--deny-destructive`
482
- # starts the server but no `/auth/*` operation is destructive, so it affects nothing here.
482
+ # starts the server and blocks every destructive route (none of them under `/auth/*`).
483
483
  # See docs/web-server.md.
484
484
 
485
485
  kbagent project create --url URL [--project ALIAS] [--name NAME] [--backend snowflake|bigquery] [--sync-backend-init]
@@ -507,10 +507,10 @@ kbagent project create --url URL [--project ALIAS] [--name NAME] [--backend snow
507
507
  # delivered and may have succeeded (retryable:false, message says not to repeat -- check
508
508
  # `auth status`, whose stored session + claim link is the evidence). `--sync-backend-init`
509
509
  # raises that call's read timeout to 300s, which can outlast an agent's foreground shell.
510
- kbagent project add --project NAME --url URL --token TOKEN
510
+ kbagent project add --project NAME --url URL [--token-stdin | --token-file PATH [--keep-token-file] | --token-env NAME | --token TOKEN]
511
511
  kbagent project list
512
512
  kbagent project remove --project NAME
513
- kbagent project edit --project NAME [--url URL] [--token TOKEN] [--new-alias NEW]
513
+ kbagent project edit --project NAME [--url URL] [--token-stdin | --token-file PATH [--keep-token-file] | --token-env NAME | --token TOKEN] [--new-alias NEW]
514
514
  kbagent project status [--project NAME]
515
515
  kbagent project refresh --project ALIAS [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
516
516
  kbagent project refresh --all [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
@@ -555,7 +555,10 @@ kbagent config set-folder --project NAME --component-id ID --config-id ID --name
555
555
  kbagent config row-create --project NAME --component-id ID --config-id ID --name ROW_NAME [--description D] [--configuration JSON|@file|-] [--is-disabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
556
556
  kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--change-description TEXT] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
557
557
  kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
558
- kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL]
558
+ kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL] [--no-open]
559
+ # oauth-url: opens the link in the default browser (interactive human mode only; never with
560
+ # --json, over SSH, in a container or in WSL without wslview); --no-open only prints it.
561
+ # Version gate in gotchas.md.
559
562
  kbagent config state-get --project NAME --component-id ID --config-id ID [--row-id ID] [--branch ID]
560
563
  kbagent config state-set --project NAME --component-id ID --config-id ID [--row-id ID] --state JSON|@file|- [--branch ID] [--dry-run] [--yes]
561
564
  # state-get/state-set (0.84.2+, #593): read/write a config's runtime state via the dedicated
@@ -625,7 +628,7 @@ kbagent storage table-detail --project NAME --table-id ID [--branch ID]
625
628
  # and `sql_path` (quoted, directly queryable path; null when Storage reports no location) --
626
629
  # see the semantic-layer dataset fqn note (#761); version gate in gotchas.md.
627
630
  kbagent storage create-bucket --project NAME --stage STAGE --name NAME [--description D] [--backend B] [--branch ID]
628
- kbagent storage create-table --project NAME --bucket-id ID --name NAME [--column COL:TYPE[(length)] ...] [--primary-key COL] [--not-null COL ...] [--default NAME=VALUE ...] [--source-table-id ID] [--source-branch-id N] [--time-partitioning-type DAY|HOUR|MONTH|YEAR] [--time-partitioning-field COL] [--time-partitioning-expiration-ms MS] [--range-partitioning-field COL --range-partitioning-start S --range-partitioning-end E --range-partitioning-interval I] [--clustering-field COL ...] [--branch ID] [--if-not-exists]
631
+ kbagent storage create-table --project NAME --bucket-id ID --name NAME [--column COL:TYPE[(length)] ...] [--primary-key COL] [--not-null COL ...] [--default NAME=VALUE ...] [--source-table-id ID] [--source-branch-id N] [--time-partitioning-type DAY|HOUR|MONTH|YEAR] [--time-partitioning-field COL] [--time-partitioning-expiration-ms MS] [--range-partitioning-field COL --range-partitioning-start S --range-partitioning-end E --range-partitioning-interval I] [--clustering-field COL ...] [--branch ID] [--if-not-exists] [--timeout SECONDS]
629
632
  # --column XOR --source-table-id (0.66.0+, BigQuery only): --source-table-id copies an existing table's data into the requested partition/clustering layout (schema derived from source) -> swap into place with swap-tables. Partition/clustering flags work in both modes (BigQuery only); time vs range partitioning are mutually exclusive. A non-BigQuery project fails fast (pre-flight backend check).
630
633
  kbagent storage upload-table --project NAME --table-id ID --file PATH [--incremental] [--delimiter D] [--enclosure E] [--no-auto-create] [--wait/--no-wait] [--timeout SECONDS] [--branch ID] [--progress]
631
634
  # upload-table / file-upload cloud upload (#834): on AWS stacks a file above 64 MiB goes up as an S3
@@ -663,7 +666,16 @@ kbagent storage delete-table --project NAME --table-id ID [--table-id ...] [--fo
663
666
  kbagent storage truncate-table --project NAME --table-id ID [--table-id ...] [--dry-run] [--yes] [--branch ID]
664
667
  kbagent storage delete-column --project NAME --table-id ID --column COL [--column ...] [--force] [--dry-run] [--yes] [--branch ID]
665
668
  kbagent storage delete-bucket --project NAME --bucket-id ID [--bucket-id ...] [--force] [--dry-run] [--yes] [--branch ID]
666
- kbagent storage swap-tables --project NAME --table-id ID --target-table-id ID --branch ID [--dry-run] [--yes]
669
+ kbagent storage swap-tables --project NAME --table-id ID --target-table-id ID --branch ID [--dry-run] [--yes] [--timeout SECONDS]
670
+ # --timeout SECONDS on create-table and swap-tables (since 0.99.0, #713): both halves
671
+ # of the repartition path move real data yet used to inherit the 60s metadata-job
672
+ # budget, so a large BigQuery table reported STORAGE_JOB_TIMEOUT for a job that was
673
+ # still running and would succeed. Default is now 300s on both. A local timeout
674
+ # NEVER cancels the job -- it keeps running server-side. The error is
675
+ # STORAGE_JOB_TIMEOUT, exit 4, retryable=false, details.job_id, and the message
676
+ # names `storage job-detail --job-id ID --wait` (create-table also names
677
+ # `storage table-detail`). Never re-run: a repeated swap swaps the tables back,
678
+ # a repeated --source-table-id create starts a second copy.
667
679
  kbagent storage clone-table --project NAME --table-id ID --branch ID [--dry-run]
668
680
  kbagent storage snapshot-create --project NAME --table-id ID [--description D] [--branch ID]
669
681
  kbagent storage snapshots --project NAME --table-id ID [--limit N] [--branch ID]
@@ -813,6 +825,25 @@ kbagent token refresh --project NAME --token-id ID [--yes]
813
825
  # is persisted. `permissions show` / `kbagent doctor` also generalized: they now flag ANY
814
826
  # persisted pattern matching zero known operations, not only the retired tool:* namespace.
815
827
  # PermissionEngine itself stays lenient at evaluation time -- only `permissions set` is strict.
828
+ # (since 0.99.0, #655) The policy also firewalls the WHOLE `kbagent serve` REST surface: every
829
+ # route is classified in server/route_permissions.py and checked by one app-level dependency
830
+ # against the SERVED config dir's policy -> HTTP 403 error_code PERMISSION_DENIED, the same
831
+ # code the CLI exits on. On 0.98.0 and older only /auth/* (0.90.1+) and /merge-requests/*
832
+ # (0.94.0+) were checked and every other route executed unchecked. Routes that declare their
833
+ # own `require_permission(...)` (those two routers) are skipped by the table. An unclassified
834
+ # route is REFUSED, not exempted (a test keeps the table
835
+ # and the live app in sync both ways); bootstrap paths (/health/ping, /health/auth-info,
836
+ # /ui-config, /docs, /redoc, /openapi.json, SPA shell) are never checked. A path param
837
+ # that collapses CLI leaves is checked like the CLI: POST/PUT/DELETE
838
+ # /semantic-layer/items/{kind}[/{name}] check the parent key (`semantic-layer.add`) AND
839
+ # the leaf `semantic-layer.add.<kind>` (route_permissions.LEAF_PATH_PARAMS).
840
+ # A `--scope organization` semantic-layer write is destructive-class over REST too:
841
+ # the handlers of scope PUT, models, items/{kind} (per-kind leaf key), import, promote
842
+ # and build check `<key> --scope organization` (FLAG_ESCALATIONS) for a typed OR an
843
+ # inherited organization scope, like the CLI.
844
+ # `GET /permissions/show` (serve, since 0.99.0) reports the EFFECTIVE policy (persisted block
845
+ # merged with the daemon's --deny-* flags); read-only by design -- no REST route can widen
846
+ # the policy that constrains it, so `permissions set|reset` stay terminal actions on the host.
816
847
  kbagent permissions list [--category read|write|destructive|admin]
817
848
  kbagent permissions show
818
849
  kbagent permissions set --mode allow|deny [--allow PATTERN ...] [--deny PATTERN ...]
@@ -900,6 +931,17 @@ kbagent merge-request resolve --component-id C --config-id I (--take ours|theirs
900
931
  # its hint-next respects it.
901
932
 
902
933
  kbagent workspace create --project ALIAS [--name NAME] [--backend TYPE] [--ui] [--read-only/--no-read-only]
934
+ # workspace create (#755): a failed create -- headless or --ui -- moves the keboola.sandboxes
935
+ # config it created to the trash and says so (--json error.details: sandbox_config_id,
936
+ # sandbox_config_rolled_back, branch_id, job_id for --ui) -- except when the outcome is
937
+ # unknown, where the config is kept (sandbox_config_kept_reason: outcome_unknown): a 5xx, a
938
+ # read/write TIMEOUT or RETRY_EXHAUSTED on the create POST, or any error after the --ui job was
939
+ # queued other than QUEUE_JOB_FAILED / WORKSPACE_NOT_FOUND; the --ui job is queued on the branch
940
+ # the config lives in (was: default branch -> Queue 400 on a pinned dev branch). --ui itself
941
+ # still ends in WORKSPACE_NOT_FOUND on current SaaS stacks: the keboola.sandboxes `create` task
942
+ # dropped Snowflake/BigQuery provisioning in 2026-03 (the UI uses SQL Editor sessions), so the
943
+ # green job attaches no Storage workspace. Not a race -- do not retry; use headless. Version
944
+ # gate for this entry lives in gotchas.md (these `# ` lines parse as ATX headings).
903
945
  kbagent workspace list [--project NAME ...] [--orphaned] [--branch ID] [--qs-compatible]
904
946
  kbagent workspace detail --project ALIAS --workspace-id ID [--branch ID]
905
947
  kbagent workspace delete --project ALIAS --workspace-id ID
@@ -958,10 +1000,17 @@ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL
958
1000
  # (1) create --use-managed-git-repo -> (2) `git-credentials-create --type http_token --permissions
959
1001
  # readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app deploy`.
960
1002
  # The platform injects the clone credentials at deploy time, so no credential wiring is needed.
961
- # deploy pins the LATEST configVersion when a git block is present and omits it for a PURE managed
962
- # repo (deploys from managedGitRepoId). Use `data-app runs` to debug a deploy that reverts to
963
- # stopped (setup-phase failures produce no container logs).
964
- kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--copy] [--reveal]
1003
+ # deploy pins the LATEST configVersion. For a PURE managed repo (no git block yet), it first
1004
+ # backfills parameters.dataApp.git from the managed repo's URL, then pins the resulting version
1005
+ # (CLI-15) -- omitting configVersion alone does NOT provision the app's workspace;
1006
+ # grant provisioning is gated on that block's presence, not on configVersion. The deploy result
1007
+ # reports it (`git_backfilled`, `git_branch`, `warnings[]`). The branch written is `--git-branch`;
1008
+ # without it, `main` for an app with no runs, and a VALIDATION_ERROR before any write for an app
1009
+ # with runs (branch unknown: pass `--git-branch` with the branch the code is on). It has no effect
1010
+ # on a deploy that does not backfill. Push the managed repo's code to that branch.
1011
+ # Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines). Use `data-app runs`
1012
+ # to debug a deploy that reverts to stopped (setup-phase failures produce no container logs).
1013
+ kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--git-branch BRANCH] [--copy] [--reveal]
965
1014
  kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
966
1015
  kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
967
1016
  kbagent data-app delete --project NAME --app-id ID [--yes]
@@ -1026,6 +1075,9 @@ kbagent config new --component-id ID [--name NAME] [--project NAME] [--output-di
1026
1075
  # the scaffold had no ID and always landed in the default branch tree, so the next
1027
1076
  # `sync push` created a DUPLICATE (34-config incident). With --configuration, the local file
1028
1077
  # mirrors the pushed encrypted body -- placeholders would overwrite the remote on next push.
1078
+ # The scaffold also records _keboola.base_config_hash (#792 E), the created config as the API
1079
+ # returned it, so `sync diff` compares it 3-way and push never overwrites an edit made in the UI.
1080
+ # Version gate in gotchas.md.
1029
1081
 
1030
1082
  # sync: GitOps -- configs as local files. init/pull/push/diff are filesystem-local (no serve REST surface).
1031
1083
  kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing] [--with-workspaces]
@@ -1041,6 +1093,13 @@ kbagent sync push --project ALIAS [--all-projects] [--dry-run] [--force] [--allo
1041
1093
  # under skipped_deletions (+ skipped_deletions_reason), also in --dry-run, whose summary.deleted counts only
1042
1094
  # what push would delete. A config/row deleted on the remote since the last pull diffs as remote_deleted and
1043
1095
  # is never re-created (it lands in skipped). Version gate in gotchas.md.
1096
+ # sync diff/push/pull and adopted files (#792 E): an untracked _config.yml whose _keboola.config_id
1097
+ # exists on the target has no baseline unless it records _keboola.base_config_hash; without one a
1098
+ # difference is a conflict (push skips it), two files with one id are both conflicts, and pull keeps
1099
+ # such a file with local changes (skipped) -- only --theirs overwrites it. Version gate in gotchas.md.
1100
+ # sync push encryption (#792 F): every #-secret is encrypted before the first write, so an
1101
+ # ENCRYPTION_FAILED stops push before anything reaches the remote (the message ends with "Nothing
1102
+ # was pushed.") and a retry creates nothing twice. Version gate in gotchas.md.
1044
1103
  # 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.
1045
1104
  # Partial failures change the exit code (#745): commands that collect per-item failures
1046
1105
  # and keep going exit 1 (was 0) when at least one item failed:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: keboola-cli
3
- Version: 0.98.0
3
+ Version: 0.99.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
@@ -84,6 +84,29 @@ A fresh Windows install has no real Python either: `python` resolves to a Micros
84
84
 
85
85
  Auto-updates kbagent on every launch; the self-update prefers the prebuilt wheel when available. Run `kbagent changelog` to see what changed. (Since 0.85.0 kbagent updates itself only -- if you also run `keboola-mcp-server` in Claude Desktop / Cursor, refresh it yourself with `uv tool install --upgrade --prerelease=allow keboola-mcp-server`.)
86
86
 
87
+ ### Installed under the old package name
88
+
89
+ The package was named `keboola-agent-cli` up to 0.62.0. It is named `keboola-cli` from 0.63.0. Both packages install the `kbagent` executable. uv treats an update to `keboola-cli` as a new tool and does not overwrite the executable that the old tool owns.
90
+
91
+ To check which name you have, run `uv tool list`. An old install is listed as `keboola-agent-cli`.
92
+
93
+ - kbagent 0.59.x and older cannot update itself. Every command prints `Auto-update failed; continuing with current version.` and the version does not change. Without the `[server]` extras, the uv error behind it is ``error: Executable already exists: kbagent (use `--force` to overwrite)``. No release can change this, because the update code runs from the old install.
94
+ - kbagent 0.60.0 to 0.62.x updates through a compatibility wheel and stays on the old name.
95
+ - kbagent 0.63.1 and newer installs a second tool, `keboola-cli`, when it updates. The new tool takes over the `kbagent` executable and the old `keboola-agent-cli` entry stays in `uv tool list`.
96
+
97
+ To move to `keboola-cli`, run these two commands in this order, in a shell where no kbagent is running:
98
+
99
+ ```bash
100
+ uv tool uninstall keboola-agent-cli
101
+ curl -LsSf https://raw.githubusercontent.com/keboola/cli/main/install.sh | sh
102
+ ```
103
+
104
+ On Windows, run the PowerShell install from the Windows section above as the second step. Your configuration is not touched: the configuration folder keeps the name `keboola-agent-cli` on purpose.
105
+
106
+ If `uv tool list` shows `keboola-cli` next to `keboola-agent-cli`, the update already worked. kbagent runs from `keboola-cli` and the old entry does no harm. Do not remove the old entry on its own: `uv tool uninstall keboola-agent-cli` also deletes the `kbagent` executable that `keboola-cli` uses, and the shell then reports `command not found`. To restore the executable, run `uv tool install --force --reinstall "keboola-cli[server] @ https://github.com/keboola/cli/releases/download/v<version>/keboola_cli-<version>-py3-none-any.whl"` with the latest version number from the [releases page](https://github.com/keboola/cli/releases/latest).
107
+
108
+ A failed startup update prints the last line of the uv output as `Cause:` (since 0.99.0), then the recovery command.
109
+
87
110
  ## Web UI (optional)
88
111
 
89
112
  Want a browser dashboard? One command:
@@ -155,7 +178,7 @@ Then either let the `kbagent` skill auto-trigger from natural prompts, or delega
155
178
  kbagent init --from-global --read-only
156
179
  ```
157
180
 
158
- Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules) prevent the agent from writing, deleting, or bypassing restrictions. See [Permissions Guide](docs/guide.md#permissions) for details.
181
+ Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules) stop the agent from writing, deleting, or changing the restrictions by mistake. They are guard rails, not a sandbox: a process that runs as the same OS user can get around them. For a hard lockout, run the agent as a different OS user ([ADR 0002](docs/adr/0002-sec-09-config-privilege-separation.md)). See [Permissions Guide](docs/guide.md#permissions) for details.
159
182
 
160
183
  ## Use as a library
161
184
 
@@ -182,9 +205,9 @@ with Client(url=os.environ["KBC_URL"], token=os.environ["KBC_TOKEN"]) as kbc:
182
205
  ![30-second demo](docs/assets/demo-readme-main.gif)
183
206
 
184
207
  ```bash
185
- # Connect a project (Storage API token from Keboola UI)
208
+ # Connect a project (Storage API token from Keboola UI, typed at a hidden prompt)
186
209
  kbagent project add --project prod \
187
- --url https://connection.keboola.com --token YOUR_TOKEN
210
+ --url https://connection.keboola.com --token-stdin
188
211
 
189
212
  # Find anything (table / config / flow / data app) across ALL projects in one call
190
213
  kbagent search "customer_id"
@@ -233,9 +256,12 @@ Four ways to register projects, depending on what you have. If you are a human
233
256
  at a terminal with a browser, start with **browser login** (last one below);
234
257
  the token-based options are the ones to use for CI and anything unattended.
235
258
 
236
- **Single project** — you have a Storage API token from the UI:
259
+ **Single project** — you have a Storage API token from the UI. `--token-stdin` shows a hidden prompt on a terminal and reads a pipe otherwise, so the token stays out of your shell history:
237
260
  ```bash
238
- kbagent project add --project prod --url https://connection.keboola.com --token YOUR_TOKEN
261
+ kbagent project add --project prod --url https://connection.keboola.com --token-stdin
262
+
263
+ # CI / non-interactive: pipe the token in
264
+ printf '%s' "$KBC_TOKEN" | kbagent project add --project prod --url https://connection.keboola.com --token-stdin
239
265
  ```
240
266
 
241
267
  **Many projects by ID** — you have a Manage API or Personal Access Token + the project IDs:
@@ -56,6 +56,29 @@ A fresh Windows install has no real Python either: `python` resolves to a Micros
56
56
 
57
57
  Auto-updates kbagent on every launch; the self-update prefers the prebuilt wheel when available. Run `kbagent changelog` to see what changed. (Since 0.85.0 kbagent updates itself only -- if you also run `keboola-mcp-server` in Claude Desktop / Cursor, refresh it yourself with `uv tool install --upgrade --prerelease=allow keboola-mcp-server`.)
58
58
 
59
+ ### Installed under the old package name
60
+
61
+ The package was named `keboola-agent-cli` up to 0.62.0. It is named `keboola-cli` from 0.63.0. Both packages install the `kbagent` executable. uv treats an update to `keboola-cli` as a new tool and does not overwrite the executable that the old tool owns.
62
+
63
+ To check which name you have, run `uv tool list`. An old install is listed as `keboola-agent-cli`.
64
+
65
+ - kbagent 0.59.x and older cannot update itself. Every command prints `Auto-update failed; continuing with current version.` and the version does not change. Without the `[server]` extras, the uv error behind it is ``error: Executable already exists: kbagent (use `--force` to overwrite)``. No release can change this, because the update code runs from the old install.
66
+ - kbagent 0.60.0 to 0.62.x updates through a compatibility wheel and stays on the old name.
67
+ - kbagent 0.63.1 and newer installs a second tool, `keboola-cli`, when it updates. The new tool takes over the `kbagent` executable and the old `keboola-agent-cli` entry stays in `uv tool list`.
68
+
69
+ To move to `keboola-cli`, run these two commands in this order, in a shell where no kbagent is running:
70
+
71
+ ```bash
72
+ uv tool uninstall keboola-agent-cli
73
+ curl -LsSf https://raw.githubusercontent.com/keboola/cli/main/install.sh | sh
74
+ ```
75
+
76
+ On Windows, run the PowerShell install from the Windows section above as the second step. Your configuration is not touched: the configuration folder keeps the name `keboola-agent-cli` on purpose.
77
+
78
+ If `uv tool list` shows `keboola-cli` next to `keboola-agent-cli`, the update already worked. kbagent runs from `keboola-cli` and the old entry does no harm. Do not remove the old entry on its own: `uv tool uninstall keboola-agent-cli` also deletes the `kbagent` executable that `keboola-cli` uses, and the shell then reports `command not found`. To restore the executable, run `uv tool install --force --reinstall "keboola-cli[server] @ https://github.com/keboola/cli/releases/download/v<version>/keboola_cli-<version>-py3-none-any.whl"` with the latest version number from the [releases page](https://github.com/keboola/cli/releases/latest).
79
+
80
+ A failed startup update prints the last line of the uv output as `Cause:` (since 0.99.0), then the recovery command.
81
+
59
82
  ## Web UI (optional)
60
83
 
61
84
  Want a browser dashboard? One command:
@@ -127,7 +150,7 @@ Then either let the `kbagent` skill auto-trigger from natural prompts, or delega
127
150
  kbagent init --from-global --read-only
128
151
  ```
129
152
 
130
- Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules) prevent the agent from writing, deleting, or bypassing restrictions. See [Permissions Guide](docs/guide.md#permissions) for details.
153
+ Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules) stop the agent from writing, deleting, or changing the restrictions by mistake. They are guard rails, not a sandbox: a process that runs as the same OS user can get around them. For a hard lockout, run the agent as a different OS user ([ADR 0002](docs/adr/0002-sec-09-config-privilege-separation.md)). See [Permissions Guide](docs/guide.md#permissions) for details.
131
154
 
132
155
  ## Use as a library
133
156
 
@@ -154,9 +177,9 @@ with Client(url=os.environ["KBC_URL"], token=os.environ["KBC_TOKEN"]) as kbc:
154
177
  ![30-second demo](docs/assets/demo-readme-main.gif)
155
178
 
156
179
  ```bash
157
- # Connect a project (Storage API token from Keboola UI)
180
+ # Connect a project (Storage API token from Keboola UI, typed at a hidden prompt)
158
181
  kbagent project add --project prod \
159
- --url https://connection.keboola.com --token YOUR_TOKEN
182
+ --url https://connection.keboola.com --token-stdin
160
183
 
161
184
  # Find anything (table / config / flow / data app) across ALL projects in one call
162
185
  kbagent search "customer_id"
@@ -205,9 +228,12 @@ Four ways to register projects, depending on what you have. If you are a human
205
228
  at a terminal with a browser, start with **browser login** (last one below);
206
229
  the token-based options are the ones to use for CI and anything unattended.
207
230
 
208
- **Single project** — you have a Storage API token from the UI:
231
+ **Single project** — you have a Storage API token from the UI. `--token-stdin` shows a hidden prompt on a terminal and reads a pipe otherwise, so the token stays out of your shell history:
209
232
  ```bash
210
- kbagent project add --project prod --url https://connection.keboola.com --token YOUR_TOKEN
233
+ kbagent project add --project prod --url https://connection.keboola.com --token-stdin
234
+
235
+ # CI / non-interactive: pipe the token in
236
+ printf '%s' "$KBC_TOKEN" | kbagent project add --project prod --url https://connection.keboola.com --token-stdin
211
237
  ```
212
238
 
213
239
  **Many projects by ID** — you have a Manage API or Personal Access Token + the project IDs:
@@ -81,8 +81,8 @@ explores traces of up to 5 actions. BFS returns the shortest counterexample.
81
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
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
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 |
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. Fixed in the code (F: push encrypts before its first write); the model is unchanged |
85
+ | I11 no lost remote update | violated: an adopted file with a config id is diffed 2-way, so push reverts a UI edit. Fixed in the code (E); the model is unchanged |
86
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
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
88
 
@@ -103,8 +103,8 @@ the regression test for each in `tests/test_sync_formal_counterexamples.py`.
103
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
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
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` |
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, Lean F4/F5 | MED -- **fixed** (without a baseline a difference is a `conflict`; the scaffold records `_keboola.base_config_hash`; pull keeps such a file) | `test_e_adopted_scaffold_push_does_not_overwrite_remote_edit` + `tests/test_sync_adopted_files.py` |
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 -- **fixed** (push encrypts every secret before its first write, so the abort writes nothing) | `test_f_aborted_push_does_not_duplicate_already_created_config` + `tests/test_sync_push_encrypt_first.py` |
108
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
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
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` |
@@ -120,11 +120,11 @@ and is deleted only by `--theirs`. That is what the I2 (sweep half), I5 and I8
120
120
  TLC/Lean rerun still reports them until the model's `Pull` is updated to match.
121
121
  Their tests are ordinary regression guards now.
122
122
 
123
- E, F and I reproduce on current code and are `xfail(strict=True)` (D, G and H
123
+ I reproduces on current code and is `xfail(strict=True)` (D, E, F, G and H
124
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
125
+ delete the `xfail` marker to adopt the fix. F's test reaches the aborted
126
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
127
+ remote-deleted config its first version used; since the F fix the aborted
128
+ push creates nothing. J reproduces and is `xfail`. K is deliberate, documented behavior, so it is an ordinary
129
129
  (unmarked) regression guard instead. B is fixed: its marker was removed
130
130
  and the test is now an ordinary regression guard.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "keboola-cli"
3
- version = "0.98.0"
3
+ version = "0.99.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": 1633,
7
+ "services/data_app_service.py": 1600,
8
8
  "services/storage_service.py": 1684,
9
9
  "services/sync_service.py": 1655
10
10
  }
@@ -792,7 +792,7 @@ class AuthClient(BaseHttpClient):
792
792
  f"project that already exists: create one at {self._base_url} in a "
793
793
  f"browser, then connect it with `kbagent auth login --stack "
794
794
  f"{self._base_url}` or `kbagent project add --project <alias> --url "
795
- f"{self._base_url} --token <token>`."
795
+ f"{self._base_url} --token-stdin`."
796
796
  ),
797
797
  status_code=404,
798
798
  error_code=ErrorCode.AUTH_NOT_SUPPORTED_ON_STACK,
@@ -969,7 +969,7 @@ class AuthClient(BaseHttpClient):
969
969
  message=(
970
970
  f"Browser login is not enabled on this Keboola stack yet "
971
971
  f"({self._base_url}). Use a static Storage token instead: "
972
- "kbagent project add --project <alias> --url <stack> --token <token>."
972
+ "kbagent project add --project <alias> --url <stack> --token-stdin."
973
973
  ),
974
974
  status_code=404,
975
975
  error_code=ErrorCode.AUTH_NOT_SUPPORTED_ON_STACK,
@@ -1042,7 +1042,7 @@ class AuthClient(BaseHttpClient):
1042
1042
  message=(
1043
1043
  f"Programmatic auth is not enabled on this Keboola stack yet "
1044
1044
  f"({self._base_url}). Use a static Storage token instead: "
1045
- "kbagent project add --project <alias> --url <stack> --token <token>."
1045
+ "kbagent project add --project <alias> --url <stack> --token-stdin."
1046
1046
  ),
1047
1047
  status_code=404,
1048
1048
  error_code=ErrorCode.AUTH_NOT_SUPPORTED_ON_STACK,
@@ -28,6 +28,10 @@ from dataclasses import dataclass
28
28
  # wslview from stalling the login flow.
29
29
  _WSLVIEW_PROBE_TIMEOUT_SECONDS = 2.0
30
30
 
31
+ # Timeout for handing a URL to `wslview`: it returns as soon as the Windows side
32
+ # has accepted the request, so anything longer means the shim is wedged.
33
+ _WSLVIEW_OPEN_TIMEOUT_SECONDS = 10.0
34
+
31
35
 
32
36
  @dataclass(frozen=True)
33
37
  class BrowserEnvironment:
@@ -168,6 +172,24 @@ def detect_browser_environment() -> BrowserEnvironment:
168
172
  return BrowserEnvironment(loopback_browser_usable=True, reason="", opener=opener)
169
173
 
170
174
 
175
+ def _open_via_wslview(url: str) -> None:
176
+ """Thread target for `open_browser` under WSL: hand ``url`` to `wslview`.
177
+
178
+ `wslview` passes the URL to the Windows-side default browser. Output is
179
+ captured, never logged, and every error is swallowed -- the URL must not
180
+ reach stderr (see `_open_silently`).
181
+ """
182
+ try:
183
+ subprocess.run(
184
+ ["wslview", url],
185
+ capture_output=True,
186
+ timeout=_WSLVIEW_OPEN_TIMEOUT_SECONDS,
187
+ check=False,
188
+ )
189
+ except Exception:
190
+ return
191
+
192
+
171
193
  def open_browser(url: str, *, wait_seconds: float = 0.0) -> bool:
172
194
  """Best-effort `webbrowser.open` on a daemon thread.
173
195
 
@@ -182,13 +204,24 @@ def open_browser(url: str, *, wait_seconds: float = 0.0) -> bool:
182
204
  right after the call (``data-app password --open``) passes it, because a
183
205
  daemon thread dies with the process -- possibly before the opener starts.
184
206
  The login flow keeps polling afterwards, so it leaves the default 0.
185
- """
186
- try:
187
- webbrowser.get()
188
- except webbrowser.Error:
189
- return False
190
207
 
191
- thread = threading.Thread(target=_open_silently, args=(url,), daemon=True)
208
+ Under WSL the URL goes to `wslview` first: `webbrowser` keys its Windows
209
+ handling off ``sys.platform == "win32"``, which is ``linux`` inside WSL, so
210
+ it would either find no handler at all or open a browser in the Linux
211
+ session -- a separate profile that shares none of the logins the URL needs.
212
+ It runs on the same daemon thread and honors ``wait_seconds`` the same way;
213
+ a working `wslview` (probed synchronously) counts as the available handler.
214
+ """
215
+ if _env_flag_set("WSL_INTEROP") and _wslview_is_working():
216
+ target = _open_via_wslview
217
+ else:
218
+ try:
219
+ webbrowser.get()
220
+ except webbrowser.Error:
221
+ return False
222
+ target = _open_silently
223
+
224
+ thread = threading.Thread(target=target, args=(url,), daemon=True)
192
225
  thread.start()
193
226
  if wait_seconds > 0:
194
227
  thread.join(timeout=wait_seconds)
@@ -14,7 +14,9 @@ import logging
14
14
  import os
15
15
  import shutil
16
16
  import sys
17
+ import tempfile
17
18
  import time
19
+ from dataclasses import dataclass
18
20
  from importlib.metadata import distribution
19
21
  from pathlib import Path
20
22
 
@@ -39,6 +41,7 @@ from .services.version_service import (
39
41
  get_update_timeout,
40
42
  prepare_kbagent_update_plan,
41
43
  resolve_kbagent_wheel_url,
44
+ summarize_install_failure,
42
45
  )
43
46
  from .update_runner import (
44
47
  DeferredUpdateReport,
@@ -68,6 +71,14 @@ class UpdateOutcome(enum.Enum):
68
71
  FAILED = "failed"
69
72
 
70
73
 
74
+ @dataclass(frozen=True)
75
+ class UpdateResult:
76
+ """An :class:`UpdateOutcome` plus what the installer printed when it failed (issue #771)."""
77
+
78
+ outcome: UpdateOutcome
79
+ output: str = ""
80
+
81
+
71
82
  # Process-level sentinel for the auto-update flow.
72
83
  #
73
84
  # Bug D fix from issue #263: ``kbagent repl`` re-enters the entire CLI
@@ -135,7 +146,22 @@ def _write_cache(latest_version: str | None) -> None:
135
146
  "last_check": time.time(),
136
147
  "latest_version": latest_version,
137
148
  }
138
- cache_path.write_text(json.dumps(payload), encoding="utf-8")
149
+ # Atomic replace (issue #271 sec-12): write a temp file next to the
150
+ # cache, then rename it over the cache in one step. A reader never sees
151
+ # a partial file, and a failed write keeps the previous cache. Each
152
+ # writer has its own temp file, so parallel kbagent starts need no
153
+ # lock: the last rename wins, and each value is a complete check result.
154
+ fd, tmp_name = tempfile.mkstemp(
155
+ dir=cache_path.parent, prefix=f".{cache_path.name}.", suffix=".tmp"
156
+ )
157
+ tmp_path = Path(tmp_name)
158
+ try:
159
+ with os.fdopen(fd, "w", encoding="utf-8") as tmp_file:
160
+ tmp_file.write(json.dumps(payload))
161
+ os.replace(tmp_path, cache_path)
162
+ except OSError:
163
+ tmp_path.unlink(missing_ok=True)
164
+ raise
139
165
  except OSError:
140
166
  pass # Non-critical; next run will re-fetch
141
167
 
@@ -273,9 +299,7 @@ def _should_skip() -> bool:
273
299
  return _should_skip_kbagent_stage() or _should_skip_all()
274
300
 
275
301
 
276
- def _perform_update(
277
- latest_version: str, *, command: tuple[str, ...] | None = None
278
- ) -> UpdateOutcome:
302
+ def _perform_update(latest_version: str, *, command: tuple[str, ...] | None = None) -> UpdateResult:
279
303
  """Download and install the latest version.
280
304
 
281
305
  Delegates to :func:`build_kbagent_upgrade_command` so this path stays
@@ -290,10 +314,10 @@ def _perform_update(
290
314
  latest_version: The version being updated to (for logging).
291
315
 
292
316
  Returns:
293
- :class:`UpdateOutcome`: ``SUCCESS`` on a clean install, ``TIMEOUT`` when
294
- the install outran :func:`get_update_timeout` -- it is still running and
295
- will finish on its own, so the next launch picks it up -- and ``FAILED``
296
- otherwise.
317
+ :class:`UpdateResult` whose ``outcome`` is ``SUCCESS`` on a clean install,
318
+ ``TIMEOUT`` when the install outran :func:`get_update_timeout` -- it is
319
+ still running and will finish on its own, so the next launch picks it up --
320
+ and ``FAILED`` otherwise, with the installer's output in ``output``.
297
321
  """
298
322
  # ``command`` is supplied by the startup planner. Keep the fallback only
299
323
  # for direct legacy callers; it must never be used after another stage has
@@ -304,17 +328,32 @@ def _perform_update(
304
328
  else:
305
329
  cmd = list(command)
306
330
  if cmd is None:
307
- return UpdateOutcome.FAILED
331
+ return UpdateResult(UpdateOutcome.FAILED)
308
332
 
309
333
  # Deliberately does NOT kill the installer when the deadline passes -- see
310
334
  # ``update_runner.run_install``. A terminated uv leaves the same
311
335
  # half-removed venv a Windows file lock does (issue #528).
312
336
  run = run_install(tuple(cmd), timeout=get_update_timeout())
313
337
  if run.status is InstallStatus.SUCCEEDED:
314
- return UpdateOutcome.SUCCESS
338
+ return UpdateResult(UpdateOutcome.SUCCESS)
315
339
  if run.status is InstallStatus.STILL_RUNNING:
316
- return UpdateOutcome.TIMEOUT
317
- return UpdateOutcome.FAILED
340
+ return UpdateResult(UpdateOutcome.TIMEOUT)
341
+ return UpdateResult(UpdateOutcome.FAILED, run.output)
342
+
343
+
344
+ def _format_update_failure(output: str, recovery_command: str | None) -> str:
345
+ """Render the startup banner for a failed install (issue #771).
346
+
347
+ Names the line the installer ended with, so the user can tell a network
348
+ error from a permanent one.
349
+ """
350
+ lines = ["Auto-update failed; continuing with current version."]
351
+ cause = summarize_install_failure(output)
352
+ if cause:
353
+ lines.append(f"Cause: {cause}")
354
+ if recovery_command:
355
+ lines.append(f"Recover with: {recovery_command}")
356
+ return "\n".join(lines) + "\n"
318
357
 
319
358
 
320
359
  def _re_exec() -> None:
@@ -594,9 +633,10 @@ def maybe_auto_update() -> None:
594
633
  return
595
634
 
596
635
  sys.stderr.write(f"Updating kbagent v{__version__} -> v{kbagent_plan.latest_version}...\n")
597
- outcome = _perform_update(
636
+ result = _perform_update(
598
637
  kbagent_plan.latest_version or __version__, command=kbagent_plan.command
599
638
  )
639
+ outcome = result.outcome
600
640
  if outcome is UpdateOutcome.SUCCESS:
601
641
  sys.stderr.write(f"Updated to v{kbagent_plan.latest_version}. Re-launching...\n")
602
642
  os.environ[ENV_UPDATED_FROM] = __version__
@@ -611,10 +651,7 @@ def maybe_auto_update() -> None:
611
651
  "background and applies on the next launch.\n"
612
652
  )
613
653
  else:
614
- sys.stderr.write(
615
- "Auto-update failed; continuing with current version. Recover with: "
616
- f"{kbagent_plan.recovery_command}\n"
617
- )
654
+ sys.stderr.write(_format_update_failure(result.output, kbagent_plan.recovery_command))
618
655
  except Exception:
619
656
  # Blanket catch: auto-update must NEVER crash the CLI.
620
657
  logger.debug("Auto-update check failed", exc_info=True)