keboola-cli 0.76.2__tar.gz → 0.77.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 (439) hide show
  1. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/CLAUDE.md +2 -2
  2. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/PKG-INFO +2 -2
  3. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/pyproject.toml +2 -2
  4. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/changelog.py +18 -0
  5. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/config.py +26 -0
  6. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/context.py +2 -2
  7. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/configs.py +4 -0
  8. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/config_service.py +35 -14
  9. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_row_cli.py +38 -0
  10. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_row_service.py +50 -0
  11. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_update.py +143 -0
  12. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_e2e.py +48 -0
  13. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_server_router_calls.py +50 -0
  14. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/package-lock.json +11 -21
  15. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/package.json +3 -0
  16. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/.gitignore +0 -0
  17. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/CONTRIBUTING.md +0 -0
  18. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/Makefile +0 -0
  19. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/README.md +0 -0
  20. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/examples/README.md +0 -0
  21. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/examples/storage_tui/README.md +0 -0
  22. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
  23. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/benchmark.py +0 -0
  24. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_command_sync.py +0 -0
  25. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_error_codes.py +0 -0
  26. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_mcp_parity.py +0 -0
  27. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/check_wheel_ui.py +0 -0
  28. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/debug_linkedby_type.sh +0 -0
  29. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/gen_command_reference.py +0 -0
  30. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/gen_release_notes.py +0 -0
  31. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/generate_changelog.py +0 -0
  32. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/generate_skill.py +0 -0
  33. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/hatch_build.py +0 -0
  34. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/lineage_deep.py +0 -0
  35. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/post-edit-quality.sh +0 -0
  36. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/pre-commit +0 -0
  37. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/sync_version.py +0 -0
  38. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/scripts/web-dev.sh +0 -0
  39. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/__init__.py +0 -0
  40. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/__main__.py +0 -0
  41. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/ai_client.py +0 -0
  42. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/auto_update.py +0 -0
  43. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/cli.py +0 -0
  44. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/__init__.py +0 -0
  45. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/_client.py +0 -0
  46. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/_core.py +0 -0
  47. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/_transfer.py +0 -0
  48. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/branches.py +0 -0
  49. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/configs.py +0 -0
  50. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/misc.py +0 -0
  51. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/query.py +0 -0
  52. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/queue.py +0 -0
  53. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/storage_files.py +0 -0
  54. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/storage_tables.py +0 -0
  55. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/stream.py +0 -0
  56. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/tokens.py +0 -0
  57. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/client/workspaces.py +0 -0
  58. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
  59. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
  60. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
  61. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_helpers.py +0 -0
  62. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
  63. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
  64. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
  65. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
  66. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
  67. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/agent.py +0 -0
  68. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/branch.py +0 -0
  69. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/changelog.py +0 -0
  70. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/component.py +0 -0
  71. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/data_app.py +0 -0
  72. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
  73. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/docs.py +0 -0
  74. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
  75. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
  76. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/feature.py +0 -0
  77. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/flow.py +0 -0
  78. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
  79. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/init.py +0 -0
  80. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/job.py +0 -0
  81. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/kai.py +0 -0
  82. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/lineage.py +0 -0
  83. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/org.py +0 -0
  84. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/permissions.py +0 -0
  85. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/project.py +0 -0
  86. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/repl.py +0 -0
  87. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/schedule.py +0 -0
  88. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/search.py +0 -0
  89. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
  90. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/serve.py +0 -0
  91. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
  92. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/storage.py +0 -0
  93. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/stream.py +0 -0
  94. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/sync.py +0 -0
  95. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/token.py +0 -0
  96. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/tool.py +0 -0
  97. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/transformation.py +0 -0
  98. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/version.py +0 -0
  99. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/commands/workspace.py +0 -0
  100. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/config_store.py +0 -0
  101. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/constants.py +0 -0
  102. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/data_science_client.py +0 -0
  103. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
  104. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/errors.py +0 -0
  105. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/http_base.py +0 -0
  106. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/json_utils.py +0 -0
  107. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/lib.py +0 -0
  108. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/manage_client.py +0 -0
  109. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/mcp_parity.py +0 -0
  110. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/metastore_client.py +0 -0
  111. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/models.py +0 -0
  112. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/output.py +0 -0
  113. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/permissions.py +0 -0
  114. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/py.typed +0 -0
  115. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/__init__.py +0 -0
  116. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
  117. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
  118. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
  119. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
  120. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
  121. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/result_models.py +0 -0
  122. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/scheduler_client.py +0 -0
  123. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/__init__.py +0 -0
  124. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
  125. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
  126. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/app.py +0 -0
  127. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/auth.py +0 -0
  128. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/dependencies.py +0 -0
  129. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/pricing.py +0 -0
  130. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
  131. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
  132. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
  133. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
  134. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
  135. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/data_apps.py +0 -0
  136. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
  137. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/docs.py +0 -0
  138. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
  139. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
  140. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
  141. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
  142. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
  143. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
  144. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
  145. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/mcp.py +0 -0
  146. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
  147. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
  148. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/projects.py +0 -0
  149. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
  150. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
  151. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
  152. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
  153. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/storage.py +0 -0
  154. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
  155. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/token.py +0 -0
  156. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
  157. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
  158. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
  159. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/server/sse.py +0 -0
  160. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/__init__.py +0 -0
  161. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_encryption.py +0 -0
  162. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
  163. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
  164. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
  165. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
  166. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
  167. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
  168. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
  169. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
  170. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
  171. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_models.py +0 -0
  172. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
  173. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
  174. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
  175. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
  176. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
  177. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/base.py +0 -0
  178. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/branch_service.py +0 -0
  179. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/component_service.py +0 -0
  180. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
  181. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/data_app_service.py +0 -0
  182. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
  183. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
  184. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/docs_service.py +0 -0
  185. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
  186. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
  187. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/feature_service.py +0 -0
  188. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/flow_service.py +0 -0
  189. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
  190. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
  191. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
  192. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/job_service.py +0 -0
  193. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
  194. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
  195. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/mcp_service.py +0 -0
  196. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/mcp_transport.py +0 -0
  197. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/member_service.py +0 -0
  198. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/org_service.py +0 -0
  199. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/project_service.py +0 -0
  200. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
  201. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/schedule_service.py +0 -0
  202. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/search_service.py +0 -0
  203. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
  204. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
  205. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
  206. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/storage_service.py +0 -0
  207. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
  208. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/sync_service.py +0 -0
  209. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/token_service.py +0 -0
  210. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/transformation_service.py +0 -0
  211. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
  212. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/version_service.py +0 -0
  213. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/services/workspace_service.py +0 -0
  214. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/stream_client.py +0 -0
  215. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
  216. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
  217. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/clone.py +0 -0
  218. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
  219. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/config_format.py +0 -0
  220. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
  221. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
  222. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/manifest.py +0 -0
  223. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/naming.py +0 -0
  224. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
  225. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
  226. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/__init__.py +0 -0
  227. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/conftest.py +0 -0
  228. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/helpers.py +0 -0
  229. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_cli.py +0 -0
  230. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_prompt.py +0 -0
  231. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_prompt_helper.py +0 -0
  232. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_runner.py +0 -0
  233. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agent_service.py +0 -0
  234. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_agents_store_events.py +0 -0
  235. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_ai_client.py +0 -0
  236. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_auto_update.py +0 -0
  237. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_base_service.py +0 -0
  238. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_branch_metadata_cli.py +0 -0
  239. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_branch_metadata_service.py +0 -0
  240. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_branch_service.py +0 -0
  241. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_build_hook.py +0 -0
  242. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_changelog_check.py +0 -0
  243. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_changelog_render.py +0 -0
  244. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_check_command_sync.py +0 -0
  245. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_choice_enums.py +0 -0
  246. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_cli.py +0 -0
  247. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_client.py +0 -0
  248. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_client_device_enrollment.py +0 -0
  249. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_component_cli.py +0 -0
  250. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_component_service.py +0 -0
  251. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_component_sync_action.py +0 -0
  252. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_create_cli.py +0 -0
  253. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_create_service.py +0 -0
  254. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_encryption.py +0 -0
  255. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_examples.py +0 -0
  256. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_metadata.py +0 -0
  257. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_rename.py +0 -0
  258. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_rename_cli.py +0 -0
  259. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_resolution.py +0 -0
  260. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_search.py +0 -0
  261. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_search_cli.py +0 -0
  262. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_set_default_bucket.py +0 -0
  263. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_config_store.py +0 -0
  264. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_cli.py +0 -0
  265. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_git_repo.py +0 -0
  266. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_plain_env_keys.py +0 -0
  267. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_secrets_cli.py +0 -0
  268. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_secrets_service.py +0 -0
  269. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_service.py +0 -0
  270. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_data_app_validate_repo_service.py +0 -0
  271. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_deep_lineage_service.py +0 -0
  272. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_dev_portal_cli.py +0 -0
  273. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_dev_portal_client.py +0 -0
  274. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_dev_portal_service.py +0 -0
  275. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_docs_cli.py +0 -0
  276. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_doctor_service.py +0 -0
  277. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_e2e_config_dir_mode.py +0 -0
  278. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_e2e_lineage_deep.py +0 -0
  279. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_encrypt_cli.py +0 -0
  280. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_encrypt_service.py +0 -0
  281. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_encryption.py +0 -0
  282. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_errors.py +0 -0
  283. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_feature_cli.py +0 -0
  284. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_feature_service.py +0 -0
  285. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_file_locking.py +0 -0
  286. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_cli.py +0 -0
  287. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_examples.py +0 -0
  288. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_service.py +0 -0
  289. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_flow_validation.py +0 -0
  290. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_gen_command_reference.py +0 -0
  291. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_gen_release_notes.py +0 -0
  292. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_helpers.py +0 -0
  293. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_http_base.py +0 -0
  294. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_http_client_cmd.py +0 -0
  295. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_http_forwarder_service.py +0 -0
  296. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_integration.py +0 -0
  297. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_job_idempotency_store.py +0 -0
  298. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_json_utils.py +0 -0
  299. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_kai_cli.py +0 -0
  300. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_kai_service.py +0 -0
  301. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_lib.py +0 -0
  302. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_lib_device_enrollment.py +0 -0
  303. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_lineage_service.py +0 -0
  304. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_local_ai_chat.py +0 -0
  305. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_manage_client.py +0 -0
  306. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_manage_token_bulk.py +0 -0
  307. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_manage_token_cli.py +0 -0
  308. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_deprecation_warnings.py +0 -0
  309. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_parity_map.py +0 -0
  310. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_service.py +0 -0
  311. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_mcp_transport.py +0 -0
  312. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_member_cli.py +0 -0
  313. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_member_service.py +0 -0
  314. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_metastore_client.py +0 -0
  315. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_models.py +0 -0
  316. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_normalize_script.py +0 -0
  317. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_org_service.py +0 -0
  318. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_output.py +0 -0
  319. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_permissions.py +0 -0
  320. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_permissions_cli.py +0 -0
  321. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_pricing.py +0 -0
  322. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_edit.py +0 -0
  323. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_edit_cli.py +0 -0
  324. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_info_cli.py +0 -0
  325. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_project_info_service.py +0 -0
  326. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_repl.py +0 -0
  327. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_result_models.py +0 -0
  328. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_run_broadcaster.py +0 -0
  329. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_schedule_cli.py +0 -0
  330. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_schedule_service.py +0 -0
  331. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_scheduler_client.py +0 -0
  332. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_search_cli.py +0 -0
  333. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_search_service.py +0 -0
  334. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_semantic_layer_cli.py +0 -0
  335. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_semantic_layer_schema.py +0 -0
  336. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_semantic_layer_service.py +0 -0
  337. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_serve_banner_encoding.py +0 -0
  338. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_serve_conversation_id.py +0 -0
  339. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_serve_ui.py +0 -0
  340. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
  341. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_server_smoke.py +0 -0
  342. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_services.py +0 -0
  343. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sharing_service.py +0 -0
  344. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_skill_frontmatter.py +0 -0
  345. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sql_split.py +0 -0
  346. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_clone.py +0 -0
  347. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_create_table.py +0 -0
  348. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_delete.py +0 -0
  349. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_describe_cli.py +0 -0
  350. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_describe_service.py +0 -0
  351. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_empty_definition.py +0 -0
  352. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_export_filters.py +0 -0
  353. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_files.py +0 -0
  354. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_snapshots.py +0 -0
  355. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_swap.py +0 -0
  356. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_tables.py +0 -0
  357. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_truncate.py +0 -0
  358. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_storage_write.py +0 -0
  359. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_stream_cli.py +0 -0
  360. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_stream_client.py +0 -0
  361. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_stream_service.py +0 -0
  362. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_branch_mapping.py +0 -0
  363. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_cli.py +0 -0
  364. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_clone.py +0 -0
  365. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_code_extraction.py +0 -0
  366. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_config_format.py +0 -0
  367. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_diff_engine.py +0 -0
  368. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_e2e.py +0 -0
  369. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_encrypt.py +0 -0
  370. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_force_pull_baseline.py +0 -0
  371. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_manifest.py +0 -0
  372. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_naming.py +0 -0
  373. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_plaintext_audit.py +0 -0
  374. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_reconcile.py +0 -0
  375. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_secrets.py +0 -0
  376. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_service.py +0 -0
  377. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_storage_jobs.py +0 -0
  378. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_sync_version_script.py +0 -0
  379. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_token_cli.py +0 -0
  380. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_token_service.py +0 -0
  381. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_tool_call_permissions.py +0 -0
  382. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_transformation_cli.py +0 -0
  383. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_transformation_ops.py +0 -0
  384. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_variables_cli.py +0 -0
  385. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_variables_service.py +0 -0
  386. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_version_service.py +0 -0
  387. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_cli.py +0 -0
  388. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_gc.py +0 -0
  389. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_service.py +0 -0
  390. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/tests/test_workspace_sql_helper.py +0 -0
  391. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/README.md +0 -0
  392. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/index.html +0 -0
  393. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/postcss.config.js +0 -0
  394. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/App.tsx +0 -0
  395. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/api/client.ts +0 -0
  396. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
  397. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/ConfirmModal.tsx +0 -0
  398. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/Drawer.tsx +0 -0
  399. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/Empty.tsx +0 -0
  400. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/JsonView.tsx +0 -0
  401. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
  402. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/components/Table.tsx +0 -0
  403. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/index.css +0 -0
  404. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/Shell.tsx +0 -0
  405. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
  406. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
  407. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/layout/TopBar.tsx +0 -0
  408. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/main.tsx +0 -0
  409. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Agents.tsx +0 -0
  410. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Branches.tsx +0 -0
  411. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Changelog.tsx +0 -0
  412. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Components.tsx +0 -0
  413. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Configs.tsx +0 -0
  414. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
  415. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/DataApps.tsx +0 -0
  416. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Doctor.tsx +0 -0
  417. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
  418. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Flows.tsx +0 -0
  419. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Jobs.tsx +0 -0
  420. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Lineage.tsx +0 -0
  421. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
  422. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Mcp.tsx +0 -0
  423. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Members.tsx +0 -0
  424. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Org.tsx +0 -0
  425. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Projects.tsx +0 -0
  426. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Schedules.tsx +0 -0
  427. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Search.tsx +0 -0
  428. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
  429. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
  430. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Sharing.tsx +0 -0
  431. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Storage.tsx +0 -0
  432. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Streams.tsx +0 -0
  433. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
  434. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/state.tsx +0 -0
  435. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/theme.tsx +0 -0
  436. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/src/types.ts +0 -0
  437. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/tailwind.config.ts +0 -0
  438. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/tsconfig.json +0 -0
  439. {keboola_cli-0.76.2 → keboola_cli-0.77.0}/web/frontend/vite.config.ts +0 -0
@@ -303,7 +303,7 @@ kbagent project member-set-role --project ALIAS --email EMAIL --role admin|guest
303
303
  kbagent config list [--project NAME] [--component-type TYPE] [--component-id ID] [--branch ID] [--include-rows]
304
304
  kbagent config detail --project NAME [--project NAME ...] --component-id ID [--config-id ID] [--branch ID] [--with-state]
305
305
  kbagent config search --query PATTERN [--project NAME] [--component-type TYPE] [--ignore-case] [--regex] [--branch ID]
306
- kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
306
+ kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--change-description TEXT] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
307
307
  kbagent config set-default-bucket --project NAME --component-id ID --config-id ID (--bucket BUCKET_ID | --clear) [--dry-run] [--branch ID]
308
308
  kbagent config rename --project NAME --component-id ID --config-id ID --name "New Name" [--branch ID] [--directory DIR]
309
309
  kbagent config variables-set --project NAME --component-id ID --config-id ID --var KEY=VALUE [--var ...] [--replace] [--variables-id ID] [--values-id ID] [--branch ID] [--dry-run]
@@ -315,7 +315,7 @@ kbagent config set-metadata --project NAME --component-id ID --config-id ID --ke
315
315
  kbagent config delete-metadata --project NAME --component-id ID --config-id ID --metadata-id ID [--branch ID] [--yes]
316
316
  kbagent config set-folder --project NAME --component-id ID --config-id ID --name FOLDER [--branch ID]
317
317
  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]
318
- kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
318
+ 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]
319
319
  kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
320
320
  kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL]
321
321
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: keboola-cli
3
- Version: 0.76.2
3
+ Version: 0.77.0
4
4
  Summary: AI-friendly CLI for managing Keboola projects
5
5
  Author-email: Keboola <dev@keboola.com>
6
6
  License-Expression: MIT
@@ -17,7 +17,7 @@ Requires-Dist: prompt-toolkit>=3.0
17
17
  Requires-Dist: pydantic>=2.5
18
18
  Requires-Dist: pyyaml>=6
19
19
  Requires-Dist: rich>=13
20
- Requires-Dist: typer[all]>=0.12
20
+ Requires-Dist: typer>=0.12
21
21
  Provides-Extra: server
22
22
  Requires-Dist: fastapi>=0.115; extra == 'server'
23
23
  Requires-Dist: python-multipart>=0.0.31; extra == 'server'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "keboola-cli"
3
- version = "0.76.2"
3
+ version = "0.77.0"
4
4
  description = "AI-friendly CLI for managing Keboola projects"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -9,7 +9,7 @@ authors = [
9
9
  { name = "Keboola", email = "dev@keboola.com" },
10
10
  ]
11
11
  dependencies = [
12
- "typer[all]>=0.12",
12
+ "typer>=0.12",
13
13
  "rich>=13",
14
14
  "httpx>=0.27",
15
15
  "pydantic>=2.5",
@@ -24,6 +24,24 @@ from .constants import CHANGELOG_HEADLINE_MAX_CHARS
24
24
 
25
25
  # Ordered newest-first. Each value is a list of brief one-line descriptions.
26
26
  CHANGELOG: dict[str, list[str]] = {
27
+ "0.77.0": [
28
+ "New (#505): `kbagent config update` and `kbagent config row-update` accept "
29
+ "`--change-description TEXT`, which writes the new config version's "
30
+ "`changeDescription` -- the version-history audit line -- instead of the generic "
31
+ "auto-generated default. On shared production configs that history is the paper "
32
+ "trail, so a change can now say *why* it happened. Omitting the flag preserves the "
33
+ "previous default verbatim, and `--dry-run` echoes the description that would be "
34
+ "sent (`change_description` in `--json`). Note this is distinct from `--description`, "
35
+ "which sets the configuration's display description. Both `kbagent serve` PATCH "
36
+ "routes mirror the flag. Thanks to @jordanrburger.",
37
+ ],
38
+ "0.76.3": [
39
+ "Security: bump npm dependencies flagged by Dependabot in `web/backend` and "
40
+ "`web/frontend` -- `@fastify/static` (path traversal / auth bypass), "
41
+ "`brace-expansion` and `find-my-way` (DoS), `postcss` (source-map path traversal), "
42
+ "and `dompurify` (XSS/sanitization bypass, pinned via an npm override on the "
43
+ "`monaco-editor`/`mermaid` transitive copy). No behavior change.",
44
+ ],
27
45
  "0.76.2": [
28
46
  "Fix (#528, #530): self-update no longer risks leaving the running Windows uv tool "
29
47
  "environment partially upgraded. kbagent now completes all network checks and command "
@@ -647,6 +647,11 @@ def config_update(
647
647
  "--merge",
648
648
  help="Deep-merge into existing config instead of replacing",
649
649
  ),
650
+ change_description: str | None = typer.Option(
651
+ None,
652
+ "--change-description",
653
+ help="Version changeDescription for the audit trail (default: auto-generated)",
654
+ ),
650
655
  dry_run: bool = typer.Option(
651
656
  False,
652
657
  "--dry-run",
@@ -692,6 +697,10 @@ def config_update(
692
697
  # Preview changes without applying
693
698
  kbagent config update --project P --component-id C --config-id ID \\
694
699
  --set 'parameters.db.host=new-host' --dry-run
700
+
701
+ # Set a meaningful version changeDescription for the audit trail
702
+ kbagent config update --project P --component-id C --config-id ID \\
703
+ --set 'parameters.db.host=new-host' --change-description "AI-1234: point at new DB host"
695
704
  """
696
705
  formatter = get_formatter(ctx)
697
706
  service = get_service(ctx, "config_service")
@@ -753,6 +762,7 @@ def config_update(
753
762
  set_paths=parsed_sets,
754
763
  merge=effective_merge,
755
764
  dry_run=dry_run,
765
+ change_description=change_description,
756
766
  branch_id=branch,
757
767
  allow_plaintext_fallback=allow_plaintext,
758
768
  )
@@ -782,6 +792,9 @@ def config_update(
782
792
  for change in changes:
783
793
  formatter.console.print(f" {change}")
784
794
  formatter.console.print()
795
+ change_desc = result.get("change_description")
796
+ if change_desc:
797
+ formatter.console.print(f"[dim]changeDescription:[/dim] {change_desc}")
785
798
  _emit_normalizations_warning(formatter, normalizations)
786
799
  return
787
800
 
@@ -2259,6 +2272,11 @@ def config_row_update(
2259
2272
  "--merge",
2260
2273
  help="Deep-merge into existing row config instead of replacing",
2261
2274
  ),
2275
+ change_description: str | None = typer.Option(
2276
+ None,
2277
+ "--change-description",
2278
+ help="Version changeDescription for the audit trail (default: auto-generated)",
2279
+ ),
2262
2280
  dry_run: bool = typer.Option(
2263
2281
  False,
2264
2282
  "--dry-run",
@@ -2313,6 +2331,10 @@ def config_row_update(
2313
2331
 
2314
2332
  # Disable a row (excludes it from job runs)
2315
2333
  kbagent config row-update --project P --component-id C --config-id ID --row-id R --is-disabled
2334
+
2335
+ # Set a meaningful version changeDescription for the audit trail
2336
+ kbagent config row-update --project P --component-id C --config-id ID --row-id R \\
2337
+ --set 'parameters.table=new_table' --change-description "AI-1234: repoint row"
2316
2338
  """
2317
2339
  if is_disabled and is_enabled:
2318
2340
  formatter = get_formatter(ctx)
@@ -2369,6 +2391,7 @@ def config_row_update(
2369
2391
  set_paths=parsed_sets,
2370
2392
  merge=effective_merge,
2371
2393
  dry_run=dry_run,
2394
+ change_description=change_description,
2372
2395
  is_disabled=is_disabled_value,
2373
2396
  branch_id=branch,
2374
2397
  allow_plaintext_fallback=allow_plaintext,
@@ -2396,6 +2419,9 @@ def config_row_update(
2396
2419
  for change in changes:
2397
2420
  formatter.console.print(f" {change}")
2398
2421
  formatter.console.print()
2422
+ change_desc = result.get("change_description")
2423
+ if change_desc:
2424
+ formatter.console.print(f"[dim]changeDescription:[/dim] {change_desc}")
2399
2425
  return
2400
2426
 
2401
2427
  if formatter.json_mode:
@@ -172,7 +172,7 @@ Use `kbagent <command> --help` for full flag details and examples.
172
172
  Use storage_workspace_id with `kbagent workspace detail --workspace-id ID`,
173
173
  NOT parameters.id (which 404s).
174
174
 
175
- kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
175
+ kbagent config update --project NAME --component-id ID --config-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--configuration-file PATH] [--set PATH=VALUE ...] [--merge] [--change-description TEXT] [--dry-run] [--branch ID] [--allow-plaintext-on-encrypt-failure]
176
176
  Update config metadata and/or configuration content. --set targets a
177
177
  nested key (e.g. parameters.db.host=new-host). --merge deep-merges into
178
178
  existing config (preserves sibling keys). --dry-run previews changes.
@@ -257,7 +257,7 @@ Use `kbagent <command> --help` for full flag details and examples.
257
257
  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]
258
258
  Create a new configuration row. Returns the new row ID. Optional --configuration accepts JSON inline, @file, or stdin. #-prefixed secrets auto-encrypt before write (fail-closed; since 0.54.0).
259
259
 
260
- kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
260
+ 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]
261
261
  Update an existing configuration row. Pass only the fields you want to change. #-prefixed secrets auto-encrypt before write (fail-closed; since 0.54.0).
262
262
 
263
263
  kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
@@ -20,6 +20,7 @@ class ConfigUpdate(BaseModel):
20
20
  set_paths: list[tuple[str, Any]] | None = None
21
21
  merge: bool = False
22
22
  dry_run: bool = False
23
+ change_description: str | None = None
23
24
  branch_id: int | None = None
24
25
 
25
26
 
@@ -36,6 +37,7 @@ class ConfigUpdateRow(BaseModel):
36
37
  description: str | None = None
37
38
  configuration: dict[str, Any] | None = None
38
39
  is_disabled: bool | None = None
40
+ change_description: str | None = None
39
41
  branch_id: int | None = None
40
42
 
41
43
 
@@ -172,6 +174,7 @@ def config_update(
172
174
  set_paths=body.set_paths,
173
175
  merge=body.merge,
174
176
  dry_run=body.dry_run,
177
+ change_description=body.change_description,
175
178
  branch_id=body.branch_id,
176
179
  )
177
180
 
@@ -401,6 +404,7 @@ def row_update(
401
404
  name=body.name,
402
405
  description=body.description,
403
406
  configuration=body.configuration,
407
+ change_description=body.change_description,
404
408
  is_disabled=body.is_disabled,
405
409
  branch_id=body.branch_id,
406
410
  )
@@ -66,6 +66,23 @@ def _infer_component_type(component_id: str) -> str | None:
66
66
  return None
67
67
 
68
68
 
69
+ def _default_change_description(command: str, *, has_metadata: bool, has_content: bool) -> str:
70
+ """Build the default config-version ``changeDescription`` for a write.
71
+
72
+ Used when the caller does not pass an explicit ``--change-description``.
73
+ ``command`` is the kbagent command that produced the version (e.g.
74
+ ``"config update"``), and the flags describe which parts changed so the
75
+ version-history line reads e.g. ``Updated metadata + configuration via
76
+ kbagent config update``.
77
+ """
78
+ parts = []
79
+ if has_metadata:
80
+ parts.append("metadata")
81
+ if has_content:
82
+ parts.append("configuration")
83
+ return f"Updated {' + '.join(parts)} via kbagent {command}"
84
+
85
+
69
86
  def _find_matches_in_json(
70
87
  obj: Any,
71
88
  match_fn: Any,
@@ -663,6 +680,7 @@ class ConfigService(BaseService):
663
680
  set_paths: list[tuple[str, Any]] | None = None,
664
681
  merge: bool = False,
665
682
  dry_run: bool = False,
683
+ change_description: str | None = None,
666
684
  branch_id: int | None = None,
667
685
  allow_plaintext_fallback: bool = False,
668
686
  ) -> dict[str, Any]:
@@ -680,6 +698,9 @@ class ConfigService(BaseService):
680
698
  merge: If True, deep-merge *configuration* or *set_paths* into
681
699
  the existing config instead of replacing. When using
682
700
  *set_paths* merge is always implied.
701
+ change_description: Text stored as the new config version's
702
+ ``changeDescription`` (the version-history audit line). When
703
+ ``None`` a default is generated from what changed.
683
704
  dry_run: If True, compute and return the diff without applying.
684
705
  branch_id: If set, update in a specific dev branch.
685
706
  If None, uses the project's active branch (if any).
@@ -737,6 +758,10 @@ class ConfigService(BaseService):
737
758
  component_id, final_config
738
759
  )
739
760
 
761
+ change_desc = change_description or _default_change_description(
762
+ "config update", has_metadata=has_metadata, has_content=has_content
763
+ )
764
+
740
765
  if dry_run:
741
766
  current = client.get_config_detail(
742
767
  component_id, config_id, branch_id=effective_branch_id
@@ -751,6 +776,7 @@ class ConfigService(BaseService):
751
776
  "config_id": config_id,
752
777
  "branch_id": effective_branch_id,
753
778
  "changes": changes,
779
+ "change_description": change_desc,
754
780
  "old_configuration": old_cfg,
755
781
  "new_configuration": new_cfg,
756
782
  "normalizations": normalizations,
@@ -768,13 +794,6 @@ class ConfigService(BaseService):
768
794
  allow_plaintext_fallback=allow_plaintext_fallback,
769
795
  )
770
796
 
771
- change_parts = []
772
- if has_metadata:
773
- change_parts.append("metadata")
774
- if has_content:
775
- change_parts.append("configuration")
776
- change_desc = f"Updated {' + '.join(change_parts)} via kbagent config update"
777
-
778
797
  result = client.update_config(
779
798
  component_id=component_id,
780
799
  config_id=config_id,
@@ -1821,6 +1840,7 @@ class ConfigService(BaseService):
1821
1840
  set_paths: list[tuple[str, Any]] | None = None,
1822
1841
  merge: bool = False,
1823
1842
  dry_run: bool = False,
1843
+ change_description: str | None = None,
1824
1844
  is_disabled: bool | None = None,
1825
1845
  branch_id: int | None = None,
1826
1846
  allow_plaintext_fallback: bool = False,
@@ -1838,6 +1858,9 @@ class ConfigService(BaseService):
1838
1858
  set_paths: List of (path, value) tuples for targeted updates.
1839
1859
  merge: If True, deep-merge *configuration* into the existing row
1840
1860
  config instead of replacing.
1861
+ change_description: Text stored as the new row version's
1862
+ ``changeDescription``. When ``None`` a default is generated
1863
+ from what changed.
1841
1864
  dry_run: If True, compute and return the diff without applying.
1842
1865
  is_disabled: When True, disable the row; when False, enable it;
1843
1866
  when None, leave the current state unchanged.
@@ -1889,6 +1912,10 @@ class ConfigService(BaseService):
1889
1912
  branch_id=effective_branch_id,
1890
1913
  )
1891
1914
 
1915
+ change_desc = change_description or _default_change_description(
1916
+ "config row-update", has_metadata=has_metadata, has_content=has_content
1917
+ )
1918
+
1892
1919
  if dry_run:
1893
1920
  current_row = client.get_config_row(
1894
1921
  component_id, config_id, row_id, branch_id=effective_branch_id
@@ -1910,17 +1937,11 @@ class ConfigService(BaseService):
1910
1937
  "row_id": row_id,
1911
1938
  "branch_id": effective_branch_id,
1912
1939
  "changes": changes,
1940
+ "change_description": change_desc,
1913
1941
  "old_configuration": old_cfg,
1914
1942
  "new_configuration": new_cfg,
1915
1943
  }
1916
1944
 
1917
- change_parts = []
1918
- if has_metadata:
1919
- change_parts.append("metadata")
1920
- if has_content:
1921
- change_parts.append("configuration")
1922
- change_desc = f"Updated {' + '.join(change_parts)} via kbagent config row-update"
1923
-
1924
1945
  # Encrypt #-prefixed secrets before they reach Storage (issue #378).
1925
1946
  # Real write only -- dry-run returned above with plaintext diff.
1926
1947
  if final_config is not None:
@@ -309,6 +309,44 @@ class TestConfigRowUpdateCli:
309
309
  assert cfg["parameters"]["table"] == "invoices"
310
310
  assert cfg["parameters"]["limit"] == 1000 # sibling preserved
311
311
 
312
+ def test_change_description_flag_forwarded(self, tmp_config_dir: Path) -> None:
313
+ """--change-description reaches the client as change_description."""
314
+ store = setup_single_project(tmp_config_dir)
315
+ mock_client = MagicMock()
316
+ mock_client.update_config_row.return_value = {**SAMPLE_ROW}
317
+ service = ConfigService(
318
+ config_store=store,
319
+ client_factory=lambda url, token: mock_client,
320
+ )
321
+
322
+ with pytest.MonkeyPatch.context() as mp:
323
+ mp.setattr(
324
+ "keboola_agent_cli.commands.config.get_service",
325
+ lambda ctx, name: service,
326
+ )
327
+ result = _invoke(
328
+ tmp_config_dir,
329
+ "row-update",
330
+ [
331
+ "--project",
332
+ "prod",
333
+ "--component-id",
334
+ "keboola.ex-db-snowflake",
335
+ "--config-id",
336
+ "cfg-001",
337
+ "--row-id",
338
+ "row-001",
339
+ "--name",
340
+ "New Name",
341
+ "--change-description",
342
+ "AI-1234: rename row",
343
+ ],
344
+ )
345
+
346
+ assert result.exit_code == 0, result.output
347
+ call_kwargs = mock_client.update_config_row.call_args.kwargs
348
+ assert call_kwargs["change_description"] == "AI-1234: rename row"
349
+
312
350
  def test_dry_run_output(self, tmp_config_dir: Path) -> None:
313
351
  """--dry-run shows diff in JSON mode."""
314
352
  store = setup_single_project(tmp_config_dir)
@@ -300,6 +300,56 @@ class TestUpdateConfigRow:
300
300
  call_kwargs = client.update_config_row.call_args.kwargs
301
301
  assert call_kwargs["branch_id"] == 99
302
302
 
303
+ def test_custom_change_description_forwarded(self, tmp_config_dir: Path) -> None:
304
+ """An explicit change_description is sent verbatim to the client."""
305
+ service, client = _make_service(tmp_config_dir)
306
+
307
+ service.update_config_row(
308
+ alias="prod",
309
+ component_id="keboola.ex-db-snowflake",
310
+ config_id="cfg-001",
311
+ row_id="row-001",
312
+ name="New Name",
313
+ change_description="AI-1234: bump row limit",
314
+ )
315
+
316
+ call_kwargs = client.update_config_row.call_args.kwargs
317
+ assert call_kwargs["change_description"] == "AI-1234: bump row limit"
318
+
319
+ def test_default_change_description_when_omitted(self, tmp_config_dir: Path) -> None:
320
+ """Omitting change_description preserves the generated default."""
321
+ service, client = _make_service(tmp_config_dir)
322
+
323
+ service.update_config_row(
324
+ alias="prod",
325
+ component_id="keboola.ex-db-snowflake",
326
+ config_id="cfg-001",
327
+ row_id="row-001",
328
+ name="New Name",
329
+ )
330
+
331
+ call_kwargs = client.update_config_row.call_args.kwargs
332
+ assert call_kwargs["change_description"] == (
333
+ "Updated metadata via kbagent config row-update"
334
+ )
335
+
336
+ def test_dry_run_includes_change_description(self, tmp_config_dir: Path) -> None:
337
+ """dry_run surfaces the change_description that would be sent."""
338
+ service, client = _make_service(tmp_config_dir)
339
+
340
+ result = service.update_config_row(
341
+ alias="prod",
342
+ component_id="keboola.ex-db-snowflake",
343
+ config_id="cfg-001",
344
+ row_id="row-001",
345
+ set_paths=[("parameters.table", "orders")],
346
+ change_description="AI-1234: repoint table",
347
+ dry_run=True,
348
+ )
349
+
350
+ assert result["change_description"] == "AI-1234: repoint table"
351
+ client.update_config_row.assert_not_called()
352
+
303
353
 
304
354
  # ---------------------------------------------------------------------------
305
355
  # delete_config_row tests
@@ -457,3 +457,146 @@ class TestConfigUpdateCli:
457
457
  assert result.exit_code == 0, result.output
458
458
  cfg = mock_client.update_config.call_args.kwargs["configuration"]
459
459
  assert cfg["parameters"]["tables"] == {"new": "table"}
460
+
461
+
462
+ # ---------------------------------------------------------------------------
463
+ # change-description tests
464
+ # ---------------------------------------------------------------------------
465
+
466
+
467
+ class TestConfigServiceUpdateChangeDescription:
468
+ """Tests for the version changeDescription on ConfigService.update_config."""
469
+
470
+ def test_custom_change_description_forwarded(self, tmp_config_dir: Path) -> None:
471
+ """An explicit change_description is sent verbatim to the client."""
472
+ service, client = _make_service(tmp_config_dir)
473
+
474
+ service.update_config(
475
+ alias="prod",
476
+ component_id="keboola.ex-db-snowflake",
477
+ config_id="cfg-001",
478
+ name="New Name",
479
+ change_description="AI-1234: bump timeout",
480
+ )
481
+
482
+ call_kwargs = client.update_config.call_args.kwargs
483
+ assert call_kwargs["change_description"] == "AI-1234: bump timeout"
484
+
485
+ def test_default_change_description_when_omitted(self, tmp_config_dir: Path) -> None:
486
+ """Omitting change_description preserves the generated default."""
487
+ service, client = _make_service(tmp_config_dir)
488
+
489
+ service.update_config(
490
+ alias="prod",
491
+ component_id="keboola.ex-db-snowflake",
492
+ config_id="cfg-001",
493
+ name="New Name",
494
+ )
495
+
496
+ call_kwargs = client.update_config.call_args.kwargs
497
+ assert call_kwargs["change_description"] == ("Updated metadata via kbagent config update")
498
+
499
+ def test_dry_run_includes_change_description(self, tmp_config_dir: Path) -> None:
500
+ """dry_run surfaces the change_description that would be sent."""
501
+ service, client = _make_service(tmp_config_dir)
502
+
503
+ result = service.update_config(
504
+ alias="prod",
505
+ component_id="keboola.ex-db-snowflake",
506
+ config_id="cfg-001",
507
+ set_paths=[("parameters.user", "new-admin")],
508
+ change_description="AI-1234: rotate creds",
509
+ dry_run=True,
510
+ )
511
+
512
+ assert result["change_description"] == "AI-1234: rotate creds"
513
+ client.update_config.assert_not_called()
514
+
515
+
516
+ class TestConfigUpdateChangeDescriptionCli:
517
+ """CLI-level tests for --change-description on config update."""
518
+
519
+ def _invoke(self, tmp_config_dir: Path, args: list[str]) -> Result:
520
+ return runner.invoke(
521
+ app,
522
+ ["--json", "--config-dir", str(tmp_config_dir), "config", "update", *args],
523
+ )
524
+
525
+ def test_change_description_flag_forwarded(self, tmp_config_dir: Path) -> None:
526
+ """--change-description reaches the client as change_description."""
527
+ store = setup_single_project(tmp_config_dir)
528
+
529
+ mock_client = MagicMock()
530
+ mock_client.get_config_detail.return_value = SAMPLE_CONFIG_DETAIL
531
+ mock_client.update_config.return_value = {
532
+ "id": "cfg-001",
533
+ "name": "My Config",
534
+ "componentId": "keboola.ex-db-snowflake",
535
+ }
536
+
537
+ with pytest.MonkeyPatch.context() as mp:
538
+ mp.setattr(
539
+ "keboola_agent_cli.commands.config.get_service",
540
+ lambda ctx, name: ConfigService(
541
+ config_store=store,
542
+ client_factory=lambda url, token: mock_client,
543
+ ),
544
+ )
545
+
546
+ result = self._invoke(
547
+ tmp_config_dir,
548
+ [
549
+ "--project",
550
+ "prod",
551
+ "--component-id",
552
+ "keboola.ex-db-snowflake",
553
+ "--config-id",
554
+ "cfg-001",
555
+ "--set",
556
+ "parameters.user=new-admin",
557
+ "--change-description",
558
+ "AI-1234: rotate creds",
559
+ ],
560
+ )
561
+
562
+ assert result.exit_code == 0, result.output
563
+ call_kwargs = mock_client.update_config.call_args.kwargs
564
+ assert call_kwargs["change_description"] == "AI-1234: rotate creds"
565
+
566
+ def test_dry_run_echoes_change_description(self, tmp_config_dir: Path) -> None:
567
+ """--dry-run --json output includes the change_description."""
568
+ store = setup_single_project(tmp_config_dir)
569
+
570
+ mock_client = MagicMock()
571
+ mock_client.get_config_detail.return_value = SAMPLE_CONFIG_DETAIL
572
+
573
+ with pytest.MonkeyPatch.context() as mp:
574
+ mp.setattr(
575
+ "keboola_agent_cli.commands.config.get_service",
576
+ lambda ctx, name: ConfigService(
577
+ config_store=store,
578
+ client_factory=lambda url, token: mock_client,
579
+ ),
580
+ )
581
+
582
+ result = self._invoke(
583
+ tmp_config_dir,
584
+ [
585
+ "--project",
586
+ "prod",
587
+ "--component-id",
588
+ "keboola.ex-db-snowflake",
589
+ "--config-id",
590
+ "cfg-001",
591
+ "--set",
592
+ "parameters.user=new-admin",
593
+ "--change-description",
594
+ "AI-1234: rotate creds",
595
+ "--dry-run",
596
+ ],
597
+ )
598
+
599
+ assert result.exit_code == 0, result.output
600
+ data = json.loads(result.output)["data"]
601
+ assert data["change_description"] == "AI-1234: rotate creds"
602
+ mock_client.update_config.assert_not_called()
@@ -1793,6 +1793,54 @@ class TestFullE2E:
1793
1793
  assert db_config["port"] == 5439
1794
1794
  assert "schema" not in db_config
1795
1795
 
1796
+ # --change-description sets the version changeDescription verbatim.
1797
+ change_desc = f"{RUN_ID} AI-1234: e2e change description"
1798
+ dry = self._run_ok(
1799
+ "config",
1800
+ "update",
1801
+ "--project",
1802
+ self.alias,
1803
+ "--component-id",
1804
+ TEST_COMPONENT_ID,
1805
+ "--config-id",
1806
+ config_id,
1807
+ "--set",
1808
+ "parameters.audit_probe=1",
1809
+ "--change-description",
1810
+ change_desc,
1811
+ "--dry-run",
1812
+ )
1813
+ # --dry-run echoes the change description that would be sent.
1814
+ assert dry["data"]["change_description"] == change_desc
1815
+
1816
+ self._run_ok(
1817
+ "config",
1818
+ "update",
1819
+ "--project",
1820
+ self.alias,
1821
+ "--component-id",
1822
+ TEST_COMPONENT_ID,
1823
+ "--config-id",
1824
+ config_id,
1825
+ "--set",
1826
+ "parameters.audit_probe=1",
1827
+ "--change-description",
1828
+ change_desc,
1829
+ )
1830
+
1831
+ # Verify the new version's changeDescription via config detail.
1832
+ data = self._run_ok(
1833
+ "config",
1834
+ "detail",
1835
+ "--project",
1836
+ self.alias,
1837
+ "--component-id",
1838
+ TEST_COMPONENT_ID,
1839
+ "--config-id",
1840
+ config_id,
1841
+ )
1842
+ assert data["data"]["changeDescription"] == change_desc
1843
+
1796
1844
  def _test_config_merge(self, config_id: str) -> None:
1797
1845
  """Test config update --merge: partial merge without losing existing keys."""
1798
1846
  # Current state: host=final.example.com, port=5439, database=final_db