keboola-cli 0.96.2__tar.gz → 0.100.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (880) hide show
  1. keboola_cli-0.100.2/CLAUDE.md +1544 -0
  2. keboola_cli-0.100.2/CONTRIBUTING.md +1132 -0
  3. keboola_cli-0.100.2/Makefile +221 -0
  4. keboola_cli-0.100.2/PKG-INFO +409 -0
  5. keboola_cli-0.100.2/README.md +381 -0
  6. keboola_cli-0.100.2/formal/sync/README.md +130 -0
  7. keboola_cli-0.100.2/pyproject.toml +199 -0
  8. keboola_cli-0.100.2/scripts/check_cli_spec.py +1477 -0
  9. keboola_cli-0.100.2/scripts/cli_spec_baseline.json +731 -0
  10. keboola_cli-0.100.2/scripts/file_size_baseline.json +10 -0
  11. keboola_cli-0.100.2/scripts/hatch_build.py +193 -0
  12. keboola_cli-0.100.2/scripts/post-edit-quality.sh +86 -0
  13. keboola_cli-0.100.2/scripts/pre-commit +65 -0
  14. keboola_cli-0.100.2/scripts/release_latest.py +279 -0
  15. keboola_cli-0.100.2/scripts/sync_version.py +200 -0
  16. keboola_cli-0.100.2/src/keboola_agent_cli/__init__.py +42 -0
  17. keboola_cli-0.100.2/src/keboola_agent_cli/auth/auth_client.py +1071 -0
  18. keboola_cli-0.100.2/src/keboola_agent_cli/auth/environment.py +245 -0
  19. keboola_cli-0.100.2/src/keboola_agent_cli/auto_update.py +811 -0
  20. keboola_cli-0.100.2/src/keboola_agent_cli/changelog.py +3698 -0
  21. keboola_cli-0.100.2/src/keboola_agent_cli/cli.py +500 -0
  22. keboola_cli-0.100.2/src/keboola_agent_cli/client/__init__.py +47 -0
  23. keboola_cli-0.100.2/src/keboola_agent_cli/client/_core.py +410 -0
  24. keboola_cli-0.100.2/src/keboola_agent_cli/client/_s3_multipart.py +626 -0
  25. keboola_cli-0.100.2/src/keboola_agent_cli/client/_transfer.py +790 -0
  26. keboola_cli-0.100.2/src/keboola_agent_cli/client/configs.py +899 -0
  27. keboola_cli-0.100.2/src/keboola_agent_cli/client/merge_requests.py +347 -0
  28. keboola_cli-0.100.2/src/keboola_agent_cli/client/misc.py +241 -0
  29. keboola_cli-0.100.2/src/keboola_agent_cli/client/queue.py +292 -0
  30. keboola_cli-0.100.2/src/keboola_agent_cli/client/storage_files.py +418 -0
  31. keboola_cli-0.100.2/src/keboola_agent_cli/client/storage_tables.py +1574 -0
  32. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_all_projects.py +45 -0
  33. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_config_clone_cmd.py +191 -0
  34. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_config_oauth.py +147 -0
  35. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_config_trash_cmd.py +119 -0
  36. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_config_variables_render.py +114 -0
  37. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_data_app_git.py +242 -0
  38. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_data_app_password.py +547 -0
  39. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_data_app_runtime.py +434 -0
  40. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_flow_triggers.py +141 -0
  41. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_helpers.py +692 -0
  42. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_lineage_build_output.py +74 -0
  43. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_lineage_tree.py +276 -0
  44. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_merge_request_common.py +339 -0
  45. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_progress.py +314 -0
  46. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_project_create.py +77 -0
  47. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_project_pin.py +79 -0
  48. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_semantic_layer_crud.py +722 -0
  49. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +196 -0
  50. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_semantic_layer_scope.py +252 -0
  51. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_storage_delete.py +187 -0
  52. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_storage_describe.py +566 -0
  53. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_storage_jobs.py +153 -0
  54. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_storage_snapshots.py +298 -0
  55. keboola_cli-0.100.2/src/keboola_agent_cli/commands/_sync_clone_render.py +89 -0
  56. keboola_cli-0.100.2/src/keboola_agent_cli/commands/agent.py +973 -0
  57. keboola_cli-0.100.2/src/keboola_agent_cli/commands/auth.py +736 -0
  58. keboola_cli-0.100.2/src/keboola_agent_cli/commands/billing.py +113 -0
  59. keboola_cli-0.100.2/src/keboola_agent_cli/commands/branch.py +436 -0
  60. keboola_cli-0.100.2/src/keboola_agent_cli/commands/component.py +378 -0
  61. keboola_cli-0.100.2/src/keboola_agent_cli/commands/config.py +2428 -0
  62. keboola_cli-0.100.2/src/keboola_agent_cli/commands/context.py +2694 -0
  63. keboola_cli-0.100.2/src/keboola_agent_cli/commands/data_app.py +995 -0
  64. keboola_cli-0.100.2/src/keboola_agent_cli/commands/dev_portal.py +573 -0
  65. keboola_cli-0.100.2/src/keboola_agent_cli/commands/docs.py +77 -0
  66. keboola_cli-0.100.2/src/keboola_agent_cli/commands/doctor.py +20 -0
  67. keboola_cli-0.100.2/src/keboola_agent_cli/commands/encrypt.py +142 -0
  68. keboola_cli-0.100.2/src/keboola_agent_cli/commands/feature.py +312 -0
  69. keboola_cli-0.100.2/src/keboola_agent_cli/commands/flow.py +1070 -0
  70. keboola_cli-0.100.2/src/keboola_agent_cli/commands/http_client.py +167 -0
  71. keboola_cli-0.100.2/src/keboola_agent_cli/commands/init.py +294 -0
  72. keboola_cli-0.100.2/src/keboola_agent_cli/commands/job.py +715 -0
  73. keboola_cli-0.100.2/src/keboola_agent_cli/commands/kai.py +302 -0
  74. keboola_cli-0.100.2/src/keboola_agent_cli/commands/lineage.py +1223 -0
  75. keboola_cli-0.100.2/src/keboola_agent_cli/commands/notification.py +475 -0
  76. keboola_cli-0.100.2/src/keboola_agent_cli/commands/org.py +318 -0
  77. keboola_cli-0.100.2/src/keboola_agent_cli/commands/permissions.py +441 -0
  78. keboola_cli-0.100.2/src/keboola_agent_cli/commands/project.py +1297 -0
  79. keboola_cli-0.100.2/src/keboola_agent_cli/commands/schedule.py +349 -0
  80. keboola_cli-0.100.2/src/keboola_agent_cli/commands/search.py +237 -0
  81. keboola_cli-0.100.2/src/keboola_agent_cli/commands/semantic_layer.py +1134 -0
  82. keboola_cli-0.100.2/src/keboola_agent_cli/commands/serve.py +401 -0
  83. keboola_cli-0.100.2/src/keboola_agent_cli/commands/sharing.py +364 -0
  84. keboola_cli-0.100.2/src/keboola_agent_cli/commands/storage.py +2292 -0
  85. keboola_cli-0.100.2/src/keboola_agent_cli/commands/stream.py +272 -0
  86. keboola_cli-0.100.2/src/keboola_agent_cli/commands/sync.py +1428 -0
  87. keboola_cli-0.100.2/src/keboola_agent_cli/commands/token.py +388 -0
  88. keboola_cli-0.100.2/src/keboola_agent_cli/commands/transformation.py +422 -0
  89. keboola_cli-0.100.2/src/keboola_agent_cli/commands/version.py +157 -0
  90. keboola_cli-0.100.2/src/keboola_agent_cli/commands/workspace.py +750 -0
  91. keboola_cli-0.100.2/src/keboola_agent_cli/config_store.py +901 -0
  92. keboola_cli-0.100.2/src/keboola_agent_cli/constants.py +1132 -0
  93. keboola_cli-0.100.2/src/keboola_agent_cli/data_science_client.py +372 -0
  94. keboola_cli-0.100.2/src/keboola_agent_cli/errors.py +402 -0
  95. keboola_cli-0.100.2/src/keboola_agent_cli/lib.py +770 -0
  96. keboola_cli-0.100.2/src/keboola_agent_cli/metastore_client.py +505 -0
  97. keboola_cli-0.100.2/src/keboola_agent_cli/models.py +550 -0
  98. keboola_cli-0.100.2/src/keboola_agent_cli/output.py +1185 -0
  99. keboola_cli-0.100.2/src/keboola_agent_cli/permissions.py +731 -0
  100. keboola_cli-0.100.2/src/keboola_agent_cli/result_models.py +502 -0
  101. keboola_cli-0.100.2/src/keboola_agent_cli/server/_serve_command_map.py +307 -0
  102. keboola_cli-0.100.2/src/keboola_agent_cli/server/agent_runner.py +1302 -0
  103. keboola_cli-0.100.2/src/keboola_agent_cli/server/app.py +1228 -0
  104. keboola_cli-0.100.2/src/keboola_agent_cli/server/dependencies.py +449 -0
  105. keboola_cli-0.100.2/src/keboola_agent_cli/server/route_permissions.py +535 -0
  106. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/configs.py +670 -0
  107. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/data_apps.py +415 -0
  108. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/jobs.py +199 -0
  109. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/lineage.py +218 -0
  110. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/permissions.py +63 -0
  111. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/schedules.py +56 -0
  112. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/semantic_layer.py +921 -0
  113. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/storage.py +810 -0
  114. keboola_cli-0.100.2/src/keboola_agent_cli/server/routers/workspaces.py +339 -0
  115. keboola_cli-0.100.2/src/keboola_agent_cli/services/_auth_registration.py +392 -0
  116. keboola_cli-0.100.2/src/keboola_agent_cli/services/_data_app_bodies.py +539 -0
  117. keboola_cli-0.100.2/src/keboola_agent_cli/services/_encryption.py +330 -0
  118. keboola_cli-0.100.2/src/keboola_agent_cli/services/_lineage_ai.py +447 -0
  119. keboola_cli-0.100.2/src/keboola_agent_cli/services/_lineage_er.py +182 -0
  120. keboola_cli-0.100.2/src/keboola_agent_cli/services/_lineage_mermaid.py +244 -0
  121. keboola_cli-0.100.2/src/keboola_agent_cli/services/_lineage_paths.py +91 -0
  122. keboola_cli-0.100.2/src/keboola_agent_cli/services/_lineage_trace.py +323 -0
  123. keboola_cli-0.100.2/src/keboola_agent_cli/services/_semantic_layer_crud.py +317 -0
  124. keboola_cli-0.100.2/src/keboola_agent_cli/services/_semantic_layer_internals.py +1342 -0
  125. keboola_cli-0.100.2/src/keboola_agent_cli/services/_semantic_layer_scope.py +307 -0
  126. keboola_cli-0.100.2/src/keboola_agent_cli/services/_storage_downloads.py +101 -0
  127. keboola_cli-0.100.2/src/keboola_agent_cli/services/_storage_jobs.py +322 -0
  128. keboola_cli-0.100.2/src/keboola_agent_cli/services/_storage_tables.py +99 -0
  129. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_baseline.py +596 -0
  130. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_bulk.py +237 -0
  131. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_clone.py +278 -0
  132. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_project_guard.py +136 -0
  133. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_push_ops.py +772 -0
  134. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_workspace.py +465 -0
  135. keboola_cli-0.100.2/src/keboola_agent_cli/services/_sync_writeback.py +262 -0
  136. keboola_cli-0.100.2/src/keboola_agent_cli/services/auth_service.py +1160 -0
  137. keboola_cli-0.100.2/src/keboola_agent_cli/services/base.py +540 -0
  138. keboola_cli-0.100.2/src/keboola_agent_cli/services/component_service.py +1135 -0
  139. keboola_cli-0.100.2/src/keboola_agent_cli/services/config_service.py +2431 -0
  140. keboola_cli-0.100.2/src/keboola_agent_cli/services/data_app_service.py +2069 -0
  141. keboola_cli-0.100.2/src/keboola_agent_cli/services/deep_lineage_service.py +1024 -0
  142. keboola_cli-0.100.2/src/keboola_agent_cli/services/flow_service.py +1008 -0
  143. keboola_cli-0.100.2/src/keboola_agent_cli/services/job_idempotency_store.py +360 -0
  144. keboola_cli-0.100.2/src/keboola_agent_cli/services/job_service.py +986 -0
  145. keboola_cli-0.100.2/src/keboola_agent_cli/services/merge_request_service.py +1472 -0
  146. keboola_cli-0.100.2/src/keboola_agent_cli/services/org_service.py +657 -0
  147. keboola_cli-0.100.2/src/keboola_agent_cli/services/project_service.py +1032 -0
  148. keboola_cli-0.100.2/src/keboola_agent_cli/services/semantic_layer_service.py +1902 -0
  149. keboola_cli-0.100.2/src/keboola_agent_cli/services/storage_service.py +2665 -0
  150. keboola_cli-0.100.2/src/keboola_agent_cli/services/stream_service.py +381 -0
  151. keboola_cli-0.100.2/src/keboola_agent_cli/services/sync_service.py +2370 -0
  152. keboola_cli-0.100.2/src/keboola_agent_cli/services/token_service.py +327 -0
  153. keboola_cli-0.100.2/src/keboola_agent_cli/services/version_service.py +1330 -0
  154. keboola_cli-0.100.2/src/keboola_agent_cli/services/workspace_service.py +1477 -0
  155. keboola_cli-0.100.2/src/keboola_agent_cli/sync/branch_registry.py +270 -0
  156. keboola_cli-0.100.2/src/keboola_agent_cli/sync/config_format.py +400 -0
  157. keboola_cli-0.100.2/src/keboola_agent_cli/sync/diff_engine.py +614 -0
  158. keboola_cli-0.100.2/src/keboola_agent_cli/update_notice.py +181 -0
  159. keboola_cli-0.100.2/src/keboola_agent_cli/update_runner.py +755 -0
  160. keboola_cli-0.100.2/tests/conftest.py +152 -0
  161. keboola_cli-0.100.2/tests/snapshots/human_output/branch_merge_warning.txt +10 -0
  162. keboola_cli-0.100.2/tests/snapshots/human_output/config_detail_api_error.txt +6 -0
  163. keboola_cli-0.100.2/tests/snapshots/human_output/config_detail_panel.txt +19 -0
  164. keboola_cli-0.100.2/tests/snapshots/human_output/config_list_fanout_failure.txt +7 -0
  165. keboola_cli-0.100.2/tests/snapshots/human_output/config_list_table.txt +10 -0
  166. keboola_cli-0.100.2/tests/snapshots/human_output/project_remove_success.txt +6 -0
  167. keboola_cli-0.100.2/tests/test_all_projects_and_warnings.py +355 -0
  168. keboola_cli-0.100.2/tests/test_api_call_counts.py +563 -0
  169. keboola_cli-0.100.2/tests/test_auth_environment.py +515 -0
  170. keboola_cli-0.100.2/tests/test_auth_sentinel_guards.py +461 -0
  171. keboola_cli-0.100.2/tests/test_auth_service.py +1953 -0
  172. keboola_cli-0.100.2/tests/test_auto_update.py +1488 -0
  173. keboola_cli-0.100.2/tests/test_branch_registry.py +244 -0
  174. keboola_cli-0.100.2/tests/test_branch_zero.py +439 -0
  175. keboola_cli-0.100.2/tests/test_check_cli_spec.py +471 -0
  176. keboola_cli-0.100.2/tests/test_cli.py +8866 -0
  177. keboola_cli-0.100.2/tests/test_cli_auth.py +1370 -0
  178. keboola_cli-0.100.2/tests/test_cli_contract.py +117 -0
  179. keboola_cli-0.100.2/tests/test_cli_human_snapshots.py +166 -0
  180. keboola_cli-0.100.2/tests/test_client.py +4314 -0
  181. keboola_cli-0.100.2/tests/test_component_service.py +1365 -0
  182. keboola_cli-0.100.2/tests/test_component_sync_action.py +837 -0
  183. keboola_cli-0.100.2/tests/test_config_create_cli.py +1013 -0
  184. keboola_cli-0.100.2/tests/test_config_row_cli.py +1134 -0
  185. keboola_cli-0.100.2/tests/test_config_store.py +1455 -0
  186. keboola_cli-0.100.2/tests/test_data_app_cli.py +1070 -0
  187. keboola_cli-0.100.2/tests/test_data_app_service.py +2529 -0
  188. keboola_cli-0.100.2/tests/test_deep_lineage_ai.py +659 -0
  189. keboola_cli-0.100.2/tests/test_deep_lineage_service.py +1348 -0
  190. keboola_cli-0.100.2/tests/test_doc_examples.py +178 -0
  191. keboola_cli-0.100.2/tests/test_e2e.py +14913 -0
  192. keboola_cli-0.100.2/tests/test_effective_branch.py +464 -0
  193. keboola_cli-0.100.2/tests/test_error_forwarding.py +349 -0
  194. keboola_cli-0.100.2/tests/test_flow_cli.py +1123 -0
  195. keboola_cli-0.100.2/tests/test_flow_service.py +784 -0
  196. keboola_cli-0.100.2/tests/test_frozen_dist.py +225 -0
  197. keboola_cli-0.100.2/tests/test_helpers.py +843 -0
  198. keboola_cli-0.100.2/tests/test_http_client_cmd.py +137 -0
  199. keboola_cli-0.100.2/tests/test_install_script.py +237 -0
  200. keboola_cli-0.100.2/tests/test_job_idempotency_store.py +424 -0
  201. keboola_cli-0.100.2/tests/test_lib.py +565 -0
  202. keboola_cli-0.100.2/tests/test_lineage_view.py +771 -0
  203. keboola_cli-0.100.2/tests/test_major_gate.py +799 -0
  204. keboola_cli-0.100.2/tests/test_merge_request_client.py +538 -0
  205. keboola_cli-0.100.2/tests/test_merge_request_service.py +1904 -0
  206. keboola_cli-0.100.2/tests/test_metastore_client.py +744 -0
  207. keboola_cli-0.100.2/tests/test_migration_page.py +75 -0
  208. keboola_cli-0.100.2/tests/test_org_service.py +1477 -0
  209. keboola_cli-0.100.2/tests/test_partial_failure_exit_code.py +1151 -0
  210. keboola_cli-0.100.2/tests/test_permissions.py +589 -0
  211. keboola_cli-0.100.2/tests/test_permissions_cli.py +833 -0
  212. keboola_cli-0.100.2/tests/test_pinned_installs.py +172 -0
  213. keboola_cli-0.100.2/tests/test_project_edit_cli.py +531 -0
  214. keboola_cli-0.100.2/tests/test_project_ref.py +488 -0
  215. keboola_cli-0.100.2/tests/test_project_token_stdin_no_leak.py +289 -0
  216. keboola_cli-0.100.2/tests/test_release_latest.py +460 -0
  217. keboola_cli-0.100.2/tests/test_release_workflow_major.py +249 -0
  218. keboola_cli-0.100.2/tests/test_s3_multipart.py +869 -0
  219. keboola_cli-0.100.2/tests/test_search_cli.py +583 -0
  220. keboola_cli-0.100.2/tests/test_semantic_layer_cli.py +2049 -0
  221. keboola_cli-0.100.2/tests/test_semantic_layer_scope.py +680 -0
  222. keboola_cli-0.100.2/tests/test_semantic_layer_scope_cli.py +609 -0
  223. keboola_cli-0.100.2/tests/test_semantic_layer_service.py +3576 -0
  224. keboola_cli-0.100.2/tests/test_serve_extras_hint.py +36 -0
  225. keboola_cli-0.100.2/tests/test_serve_telemetry.py +259 -0
  226. keboola_cli-0.100.2/tests/test_server_active_project.py +125 -0
  227. keboola_cli-0.100.2/tests/test_server_dry_run_guard.py +431 -0
  228. keboola_cli-0.100.2/tests/test_server_production_branch.py +246 -0
  229. keboola_cli-0.100.2/tests/test_server_route_permissions.py +896 -0
  230. keboola_cli-0.100.2/tests/test_server_router_calls.py +3538 -0
  231. keboola_cli-0.100.2/tests/test_server_semantic_layer_routes_e2e.py +697 -0
  232. keboola_cli-0.100.2/tests/test_server_smoke.py +553 -0
  233. keboola_cli-0.100.2/tests/test_services.py +5237 -0
  234. keboola_cli-0.100.2/tests/test_storage_create_table.py +495 -0
  235. keboola_cli-0.100.2/tests/test_storage_delete.py +1454 -0
  236. keboola_cli-0.100.2/tests/test_storage_describe_cli.py +1308 -0
  237. keboola_cli-0.100.2/tests/test_storage_empty_definition.py +152 -0
  238. keboola_cli-0.100.2/tests/test_storage_files.py +1719 -0
  239. keboola_cli-0.100.2/tests/test_storage_import_jobs.py +1033 -0
  240. keboola_cli-0.100.2/tests/test_storage_swap.py +770 -0
  241. keboola_cli-0.100.2/tests/test_storage_write.py +2696 -0
  242. keboola_cli-0.100.2/tests/test_sync_adopted_files.py +275 -0
  243. keboola_cli-0.100.2/tests/test_sync_diff_engine.py +647 -0
  244. keboola_cli-0.100.2/tests/test_sync_formal_counterexamples.py +964 -0
  245. keboola_cli-0.100.2/tests/test_sync_project_guard.py +367 -0
  246. keboola_cli-0.100.2/tests/test_sync_push_encrypt_first.py +261 -0
  247. keboola_cli-0.100.2/tests/test_sync_reconcile.py +542 -0
  248. keboola_cli-0.100.2/tests/test_sync_service.py +4882 -0
  249. keboola_cli-0.100.2/tests/test_sync_version_script.py +316 -0
  250. keboola_cli-0.100.2/tests/test_sync_workspaces.py +1414 -0
  251. keboola_cli-0.100.2/tests/test_transfer_progress.py +517 -0
  252. keboola_cli-0.100.2/tests/test_update_runner.py +896 -0
  253. keboola_cli-0.100.2/tests/test_variables_cli.py +719 -0
  254. keboola_cli-0.100.2/tests/test_version_service.py +1222 -0
  255. keboola_cli-0.100.2/tests/test_workspace_cli.py +1931 -0
  256. keboola_cli-0.100.2/tests/test_workspace_gc.py +594 -0
  257. keboola_cli-0.100.2/tests/test_workspace_service.py +2891 -0
  258. keboola_cli-0.100.2/web/README.md +180 -0
  259. keboola_cli-0.100.2/web/frontend/package-lock.json +5597 -0
  260. keboola_cli-0.100.2/web/frontend/package.json +38 -0
  261. keboola_cli-0.100.2/web/frontend/src/components/CommandPalette.tsx +520 -0
  262. keboola_cli-0.100.2/web/frontend/src/lib/branch.test.ts +40 -0
  263. keboola_cli-0.100.2/web/frontend/src/lib/branch.ts +18 -0
  264. keboola_cli-0.100.2/web/frontend/src/pages/Configs.tsx +609 -0
  265. keboola_cli-0.100.2/web/frontend/src/pages/DataApps.tsx +472 -0
  266. keboola_cli-0.100.2/web/frontend/src/pages/Flows.tsx +474 -0
  267. keboola_cli-0.100.2/web/frontend/src/pages/LocalAi.tsx +498 -0
  268. keboola_cli-0.100.2/web/frontend/src/pages/Schedules.tsx +64 -0
  269. keboola_cli-0.100.2/web/frontend/src/pages/Storage.tsx +1334 -0
  270. keboola_cli-0.100.2/web/frontend/src/pages/Streams.tsx +538 -0
  271. keboola_cli-0.100.2/web/frontend/src/pages/jobsShared.test.ts +21 -0
  272. keboola_cli-0.100.2/web/frontend/src/pages/jobsShared.tsx +529 -0
  273. keboola_cli-0.100.2/web/frontend/src/whatsnew.ts +244 -0
  274. keboola_cli-0.96.2/CLAUDE.md +0 -1309
  275. keboola_cli-0.96.2/CONTRIBUTING.md +0 -971
  276. keboola_cli-0.96.2/Makefile +0 -205
  277. keboola_cli-0.96.2/PKG-INFO +0 -376
  278. keboola_cli-0.96.2/README.md +0 -348
  279. keboola_cli-0.96.2/formal/sync/README.md +0 -130
  280. keboola_cli-0.96.2/pyproject.toml +0 -197
  281. keboola_cli-0.96.2/scripts/file_size_baseline.json +0 -11
  282. keboola_cli-0.96.2/scripts/hatch_build.py +0 -193
  283. keboola_cli-0.96.2/scripts/post-edit-quality.sh +0 -68
  284. keboola_cli-0.96.2/scripts/pre-commit +0 -60
  285. keboola_cli-0.96.2/scripts/sync_version.py +0 -174
  286. keboola_cli-0.96.2/src/keboola_agent_cli/__init__.py +0 -40
  287. keboola_cli-0.96.2/src/keboola_agent_cli/auth/auth_client.py +0 -1071
  288. keboola_cli-0.96.2/src/keboola_agent_cli/auth/environment.py +0 -212
  289. keboola_cli-0.96.2/src/keboola_agent_cli/auto_update.py +0 -620
  290. keboola_cli-0.96.2/src/keboola_agent_cli/changelog.py +0 -3498
  291. keboola_cli-0.96.2/src/keboola_agent_cli/cli.py +0 -499
  292. keboola_cli-0.96.2/src/keboola_agent_cli/client/__init__.py +0 -43
  293. keboola_cli-0.96.2/src/keboola_agent_cli/client/_core.py +0 -354
  294. keboola_cli-0.96.2/src/keboola_agent_cli/client/_transfer.py +0 -656
  295. keboola_cli-0.96.2/src/keboola_agent_cli/client/configs.py +0 -882
  296. keboola_cli-0.96.2/src/keboola_agent_cli/client/merge_requests.py +0 -336
  297. keboola_cli-0.96.2/src/keboola_agent_cli/client/misc.py +0 -240
  298. keboola_cli-0.96.2/src/keboola_agent_cli/client/queue.py +0 -290
  299. keboola_cli-0.96.2/src/keboola_agent_cli/client/storage_files.py +0 -353
  300. keboola_cli-0.96.2/src/keboola_agent_cli/client/storage_tables.py +0 -1252
  301. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_config_clone_cmd.py +0 -196
  302. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_config_oauth.py +0 -98
  303. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_config_trash_cmd.py +0 -119
  304. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_data_app_git.py +0 -257
  305. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_data_app_password.py +0 -546
  306. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -454
  307. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_flow_triggers.py +0 -140
  308. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_helpers.py +0 -385
  309. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_merge_request_common.py +0 -338
  310. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_project_create.py +0 -75
  311. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -641
  312. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -44
  313. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_storage_describe.py +0 -555
  314. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -297
  315. keboola_cli-0.96.2/src/keboola_agent_cli/commands/_sync_clone_render.py +0 -76
  316. keboola_cli-0.96.2/src/keboola_agent_cli/commands/agent.py +0 -973
  317. keboola_cli-0.96.2/src/keboola_agent_cli/commands/auth.py +0 -731
  318. keboola_cli-0.96.2/src/keboola_agent_cli/commands/billing.py +0 -110
  319. keboola_cli-0.96.2/src/keboola_agent_cli/commands/branch.py +0 -444
  320. keboola_cli-0.96.2/src/keboola_agent_cli/commands/component.py +0 -375
  321. keboola_cli-0.96.2/src/keboola_agent_cli/commands/config.py +0 -2541
  322. keboola_cli-0.96.2/src/keboola_agent_cli/commands/context.py +0 -2404
  323. keboola_cli-0.96.2/src/keboola_agent_cli/commands/data_app.py +0 -1022
  324. keboola_cli-0.96.2/src/keboola_agent_cli/commands/dev_portal.py +0 -571
  325. keboola_cli-0.96.2/src/keboola_agent_cli/commands/docs.py +0 -81
  326. keboola_cli-0.96.2/src/keboola_agent_cli/commands/doctor.py +0 -18
  327. keboola_cli-0.96.2/src/keboola_agent_cli/commands/encrypt.py +0 -145
  328. keboola_cli-0.96.2/src/keboola_agent_cli/commands/feature.py +0 -311
  329. keboola_cli-0.96.2/src/keboola_agent_cli/commands/flow.py +0 -1051
  330. keboola_cli-0.96.2/src/keboola_agent_cli/commands/http_client.py +0 -162
  331. keboola_cli-0.96.2/src/keboola_agent_cli/commands/init.py +0 -281
  332. keboola_cli-0.96.2/src/keboola_agent_cli/commands/job.py +0 -732
  333. keboola_cli-0.96.2/src/keboola_agent_cli/commands/kai.py +0 -301
  334. keboola_cli-0.96.2/src/keboola_agent_cli/commands/lineage.py +0 -1470
  335. keboola_cli-0.96.2/src/keboola_agent_cli/commands/notification.py +0 -471
  336. keboola_cli-0.96.2/src/keboola_agent_cli/commands/org.py +0 -292
  337. keboola_cli-0.96.2/src/keboola_agent_cli/commands/permissions.py +0 -426
  338. keboola_cli-0.96.2/src/keboola_agent_cli/commands/project.py +0 -1318
  339. keboola_cli-0.96.2/src/keboola_agent_cli/commands/schedule.py +0 -343
  340. keboola_cli-0.96.2/src/keboola_agent_cli/commands/search.py +0 -233
  341. keboola_cli-0.96.2/src/keboola_agent_cli/commands/semantic_layer.py +0 -1039
  342. keboola_cli-0.96.2/src/keboola_agent_cli/commands/serve.py +0 -384
  343. keboola_cli-0.96.2/src/keboola_agent_cli/commands/sharing.py +0 -358
  344. keboola_cli-0.96.2/src/keboola_agent_cli/commands/storage.py +0 -2331
  345. keboola_cli-0.96.2/src/keboola_agent_cli/commands/stream.py +0 -271
  346. keboola_cli-0.96.2/src/keboola_agent_cli/commands/sync.py +0 -1394
  347. keboola_cli-0.96.2/src/keboola_agent_cli/commands/token.py +0 -387
  348. keboola_cli-0.96.2/src/keboola_agent_cli/commands/transformation.py +0 -421
  349. keboola_cli-0.96.2/src/keboola_agent_cli/commands/version.py +0 -127
  350. keboola_cli-0.96.2/src/keboola_agent_cli/commands/workspace.py +0 -729
  351. keboola_cli-0.96.2/src/keboola_agent_cli/config_store.py +0 -888
  352. keboola_cli-0.96.2/src/keboola_agent_cli/constants.py +0 -1045
  353. keboola_cli-0.96.2/src/keboola_agent_cli/data_science_client.py +0 -374
  354. keboola_cli-0.96.2/src/keboola_agent_cli/errors.py +0 -383
  355. keboola_cli-0.96.2/src/keboola_agent_cli/lib.py +0 -668
  356. keboola_cli-0.96.2/src/keboola_agent_cli/metastore_client.py +0 -315
  357. keboola_cli-0.96.2/src/keboola_agent_cli/models.py +0 -546
  358. keboola_cli-0.96.2/src/keboola_agent_cli/output.py +0 -1070
  359. keboola_cli-0.96.2/src/keboola_agent_cli/permissions.py +0 -667
  360. keboola_cli-0.96.2/src/keboola_agent_cli/result_models.py +0 -432
  361. keboola_cli-0.96.2/src/keboola_agent_cli/server/_serve_command_map.py +0 -292
  362. keboola_cli-0.96.2/src/keboola_agent_cli/server/agent_runner.py +0 -1296
  363. keboola_cli-0.96.2/src/keboola_agent_cli/server/app.py +0 -1182
  364. keboola_cli-0.96.2/src/keboola_agent_cli/server/dependencies.py +0 -306
  365. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/configs.py +0 -666
  366. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/data_apps.py +0 -411
  367. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/jobs.py +0 -195
  368. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/lineage.py +0 -228
  369. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/schedules.py +0 -54
  370. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -682
  371. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/storage.py +0 -746
  372. keboola_cli-0.96.2/src/keboola_agent_cli/server/routers/workspaces.py +0 -318
  373. keboola_cli-0.96.2/src/keboola_agent_cli/services/_auth_registration.py +0 -390
  374. keboola_cli-0.96.2/src/keboola_agent_cli/services/_data_app_bodies.py +0 -274
  375. keboola_cli-0.96.2/src/keboola_agent_cli/services/_encryption.py +0 -315
  376. keboola_cli-0.96.2/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -382
  377. keboola_cli-0.96.2/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -1303
  378. keboola_cli-0.96.2/src/keboola_agent_cli/services/_storage_tables.py +0 -51
  379. keboola_cli-0.96.2/src/keboola_agent_cli/services/_sync_baseline.py +0 -553
  380. keboola_cli-0.96.2/src/keboola_agent_cli/services/_sync_bulk.py +0 -230
  381. keboola_cli-0.96.2/src/keboola_agent_cli/services/_sync_clone.py +0 -258
  382. keboola_cli-0.96.2/src/keboola_agent_cli/services/_sync_push_ops.py +0 -660
  383. keboola_cli-0.96.2/src/keboola_agent_cli/services/_sync_workspace.py +0 -461
  384. keboola_cli-0.96.2/src/keboola_agent_cli/services/_sync_writeback.py +0 -258
  385. keboola_cli-0.96.2/src/keboola_agent_cli/services/auth_service.py +0 -1094
  386. keboola_cli-0.96.2/src/keboola_agent_cli/services/base.py +0 -459
  387. keboola_cli-0.96.2/src/keboola_agent_cli/services/component_service.py +0 -1114
  388. keboola_cli-0.96.2/src/keboola_agent_cli/services/config_service.py +0 -2431
  389. keboola_cli-0.96.2/src/keboola_agent_cli/services/data_app_service.py +0 -2120
  390. keboola_cli-0.96.2/src/keboola_agent_cli/services/deep_lineage_service.py +0 -1443
  391. keboola_cli-0.96.2/src/keboola_agent_cli/services/flow_service.py +0 -1007
  392. keboola_cli-0.96.2/src/keboola_agent_cli/services/job_idempotency_store.py +0 -302
  393. keboola_cli-0.96.2/src/keboola_agent_cli/services/job_service.py +0 -979
  394. keboola_cli-0.96.2/src/keboola_agent_cli/services/merge_request_service.py +0 -1426
  395. keboola_cli-0.96.2/src/keboola_agent_cli/services/org_service.py +0 -651
  396. keboola_cli-0.96.2/src/keboola_agent_cli/services/project_service.py +0 -994
  397. keboola_cli-0.96.2/src/keboola_agent_cli/services/semantic_layer_service.py +0 -1646
  398. keboola_cli-0.96.2/src/keboola_agent_cli/services/storage_service.py +0 -2636
  399. keboola_cli-0.96.2/src/keboola_agent_cli/services/stream_service.py +0 -369
  400. keboola_cli-0.96.2/src/keboola_agent_cli/services/sync_service.py +0 -2433
  401. keboola_cli-0.96.2/src/keboola_agent_cli/services/token_service.py +0 -327
  402. keboola_cli-0.96.2/src/keboola_agent_cli/services/version_service.py +0 -866
  403. keboola_cli-0.96.2/src/keboola_agent_cli/services/workspace_service.py +0 -1318
  404. keboola_cli-0.96.2/src/keboola_agent_cli/sync/branch_registry.py +0 -244
  405. keboola_cli-0.96.2/src/keboola_agent_cli/sync/config_format.py +0 -393
  406. keboola_cli-0.96.2/src/keboola_agent_cli/sync/diff_engine.py +0 -597
  407. keboola_cli-0.96.2/src/keboola_agent_cli/update_runner.py +0 -629
  408. keboola_cli-0.96.2/tests/conftest.py +0 -141
  409. keboola_cli-0.96.2/tests/test_api_call_counts.py +0 -543
  410. keboola_cli-0.96.2/tests/test_auth_environment.py +0 -382
  411. keboola_cli-0.96.2/tests/test_auth_sentinel_guards.py +0 -461
  412. keboola_cli-0.96.2/tests/test_auth_service.py +0 -1607
  413. keboola_cli-0.96.2/tests/test_auto_update.py +0 -1335
  414. keboola_cli-0.96.2/tests/test_branch_registry.py +0 -165
  415. keboola_cli-0.96.2/tests/test_cli.py +0 -8529
  416. keboola_cli-0.96.2/tests/test_cli_auth.py +0 -1300
  417. keboola_cli-0.96.2/tests/test_client.py +0 -4285
  418. keboola_cli-0.96.2/tests/test_component_service.py +0 -1325
  419. keboola_cli-0.96.2/tests/test_component_sync_action.py +0 -770
  420. keboola_cli-0.96.2/tests/test_config_create_cli.py +0 -989
  421. keboola_cli-0.96.2/tests/test_config_row_cli.py +0 -915
  422. keboola_cli-0.96.2/tests/test_config_store.py +0 -1410
  423. keboola_cli-0.96.2/tests/test_data_app_cli.py +0 -1025
  424. keboola_cli-0.96.2/tests/test_data_app_service.py +0 -2185
  425. keboola_cli-0.96.2/tests/test_deep_lineage_service.py +0 -1306
  426. keboola_cli-0.96.2/tests/test_e2e.py +0 -14679
  427. keboola_cli-0.96.2/tests/test_effective_branch.py +0 -444
  428. keboola_cli-0.96.2/tests/test_flow_cli.py +0 -1103
  429. keboola_cli-0.96.2/tests/test_flow_service.py +0 -720
  430. keboola_cli-0.96.2/tests/test_frozen_dist.py +0 -222
  431. keboola_cli-0.96.2/tests/test_helpers.py +0 -521
  432. keboola_cli-0.96.2/tests/test_http_client_cmd.py +0 -107
  433. keboola_cli-0.96.2/tests/test_job_idempotency_store.py +0 -291
  434. keboola_cli-0.96.2/tests/test_lib.py +0 -453
  435. keboola_cli-0.96.2/tests/test_merge_request_client.py +0 -515
  436. keboola_cli-0.96.2/tests/test_merge_request_service.py +0 -1824
  437. keboola_cli-0.96.2/tests/test_metastore_client.py +0 -522
  438. keboola_cli-0.96.2/tests/test_org_service.py +0 -1430
  439. keboola_cli-0.96.2/tests/test_permissions.py +0 -566
  440. keboola_cli-0.96.2/tests/test_permissions_cli.py +0 -800
  441. keboola_cli-0.96.2/tests/test_project_edit_cli.py +0 -324
  442. keboola_cli-0.96.2/tests/test_project_ref.py +0 -484
  443. keboola_cli-0.96.2/tests/test_search_cli.py +0 -559
  444. keboola_cli-0.96.2/tests/test_semantic_layer_cli.py +0 -2034
  445. keboola_cli-0.96.2/tests/test_semantic_layer_service.py +0 -3559
  446. keboola_cli-0.96.2/tests/test_serve_telemetry.py +0 -249
  447. keboola_cli-0.96.2/tests/test_server_router_calls.py +0 -3007
  448. keboola_cli-0.96.2/tests/test_server_semantic_layer_routes_e2e.py +0 -697
  449. keboola_cli-0.96.2/tests/test_server_smoke.py +0 -552
  450. keboola_cli-0.96.2/tests/test_services.py +0 -5208
  451. keboola_cli-0.96.2/tests/test_storage_create_table.py +0 -433
  452. keboola_cli-0.96.2/tests/test_storage_delete.py +0 -1282
  453. keboola_cli-0.96.2/tests/test_storage_describe_cli.py +0 -1305
  454. keboola_cli-0.96.2/tests/test_storage_empty_definition.py +0 -152
  455. keboola_cli-0.96.2/tests/test_storage_files.py +0 -1648
  456. keboola_cli-0.96.2/tests/test_storage_swap.py +0 -456
  457. keboola_cli-0.96.2/tests/test_storage_write.py +0 -2445
  458. keboola_cli-0.96.2/tests/test_sync_diff_engine.py +0 -596
  459. keboola_cli-0.96.2/tests/test_sync_formal_counterexamples.py +0 -985
  460. keboola_cli-0.96.2/tests/test_sync_reconcile.py +0 -536
  461. keboola_cli-0.96.2/tests/test_sync_service.py +0 -4881
  462. keboola_cli-0.96.2/tests/test_sync_version_script.py +0 -244
  463. keboola_cli-0.96.2/tests/test_sync_workspaces.py +0 -1412
  464. keboola_cli-0.96.2/tests/test_update_runner.py +0 -694
  465. keboola_cli-0.96.2/tests/test_variables_cli.py +0 -670
  466. keboola_cli-0.96.2/tests/test_version_service.py +0 -1229
  467. keboola_cli-0.96.2/tests/test_workspace_cli.py +0 -1883
  468. keboola_cli-0.96.2/tests/test_workspace_gc.py +0 -392
  469. keboola_cli-0.96.2/tests/test_workspace_service.py +0 -2479
  470. keboola_cli-0.96.2/web/README.md +0 -179
  471. keboola_cli-0.96.2/web/frontend/package-lock.json +0 -5597
  472. keboola_cli-0.96.2/web/frontend/package.json +0 -37
  473. keboola_cli-0.96.2/web/frontend/src/components/CommandPalette.tsx +0 -519
  474. keboola_cli-0.96.2/web/frontend/src/pages/Configs.tsx +0 -607
  475. keboola_cli-0.96.2/web/frontend/src/pages/DataApps.tsx +0 -471
  476. keboola_cli-0.96.2/web/frontend/src/pages/Flows.tsx +0 -473
  477. keboola_cli-0.96.2/web/frontend/src/pages/LocalAi.tsx +0 -497
  478. keboola_cli-0.96.2/web/frontend/src/pages/Schedules.tsx +0 -63
  479. keboola_cli-0.96.2/web/frontend/src/pages/Storage.tsx +0 -1335
  480. keboola_cli-0.96.2/web/frontend/src/pages/Streams.tsx +0 -537
  481. keboola_cli-0.96.2/web/frontend/src/pages/jobsShared.tsx +0 -528
  482. keboola_cli-0.96.2/web/frontend/src/whatsnew.ts +0 -232
  483. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/.gitignore +0 -0
  484. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/LICENSE +0 -0
  485. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/examples/README.md +0 -0
  486. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/examples/storage_tui/README.md +0 -0
  487. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
  488. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/plugins/kbagent/skills/kbagent-cicd-migration/scripts/migrate_cicd.py +0 -0
  489. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py +0 -0
  490. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_command_sync.py +0 -0
  491. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_error_codes.py +0 -0
  492. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_file_size.py +0 -0
  493. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_release_scope.py +0 -0
  494. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_sentinel_guards.py +0 -0
  495. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_version_gates.py +0 -0
  496. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/check_wheel_ui.py +0 -0
  497. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/debug_linkedby_type.sh +0 -0
  498. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/gen_command_reference.py +0 -0
  499. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/gen_endpoint_reference.py +0 -0
  500. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/gen_release_notes.py +0 -0
  501. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/generate_changelog.py +0 -0
  502. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/generate_skill.py +0 -0
  503. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/lineage_deep.py +0 -0
  504. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/scripts/web-dev.sh +0 -0
  505. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/__main__.py +0 -0
  506. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/ai_client.py +0 -0
  507. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/__init__.py +0 -0
  508. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/device.py +0 -0
  509. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/models.py +0 -0
  510. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/pkce.py +0 -0
  511. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/sentinel.py +0 -0
  512. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/state_store.py +0 -0
  513. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/token_provider.py +0 -0
  514. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/auth/totp.py +0 -0
  515. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/_client.py +0 -0
  516. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/billing.py +0 -0
  517. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/branches.py +0 -0
  518. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/editor.py +0 -0
  519. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/notifications.py +0 -0
  520. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/query.py +0 -0
  521. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/stream.py +0 -0
  522. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/tokens.py +0 -0
  523. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/triggers.py +0 -0
  524. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/client/workspaces.py +0 -0
  525. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/__init__.py +0 -0
  526. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_auth_picker.py +0 -0
  527. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_checkbox_select.py +0 -0
  528. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_merge_request_render.py +0 -0
  529. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_merge_request_writes.py +0 -0
  530. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
  531. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_project_ref.py +0 -0
  532. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
  533. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_storage_table_detail.py +0 -0
  534. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_storage_tables_render.py +0 -0
  535. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_sync_push_render.py +0 -0
  536. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/_url_copy.py +0 -0
  537. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/changelog.py +0 -0
  538. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/config_state.py +0 -0
  539. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/merge_request.py +0 -0
  540. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/commands/repl.py +0 -0
  541. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/dev_portal_client.py +0 -0
  542. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/effective_branch.py +0 -0
  543. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/frozen_dist.py +0 -0
  544. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/http_base.py +0 -0
  545. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/json_utils.py +0 -0
  546. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/manage_client.py +0 -0
  547. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/project_ref.py +0 -0
  548. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/py.typed +0 -0
  549. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/resources/__init__.py +0 -0
  550. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
  551. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
  552. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
  553. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
  554. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
  555. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/scheduler_client.py +0 -0
  556. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/__init__.py +0 -0
  557. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/agents_store.py +0 -0
  558. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/auth.py +0 -0
  559. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/pricing.py +0 -0
  560. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
  561. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/agents.py +0 -0
  562. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
  563. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/auth.py +0 -0
  564. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/billing.py +0 -0
  565. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/branches.py +0 -0
  566. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/components.py +0 -0
  567. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
  568. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/docs.py +0 -0
  569. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
  570. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/feature.py +0 -0
  571. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/flows.py +0 -0
  572. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/health.py +0 -0
  573. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/kai.py +0 -0
  574. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/members.py +0 -0
  575. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/merge_requests.py +0 -0
  576. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/notifications.py +0 -0
  577. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/org.py +0 -0
  578. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/projects.py +0 -0
  579. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/search.py +0 -0
  580. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
  581. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/stream.py +0 -0
  582. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/token.py +0 -0
  583. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
  584. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
  585. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/server/sse.py +0 -0
  586. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/__init__.py +0 -0
  587. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_column_descriptions.py +0 -0
  588. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_config_clone.py +0 -0
  589. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_config_set_guard.py +0 -0
  590. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_config_trash.py +0 -0
  591. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_data_app_password.py +0 -0
  592. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_describe_batch_input.py +0 -0
  593. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
  594. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_semantic_layer_fqn.py +0 -0
  595. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
  596. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
  597. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
  598. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
  599. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_clone_warnings.py +0 -0
  600. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_data_app.py +0 -0
  601. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_models.py +0 -0
  602. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_stale.py +0 -0
  603. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
  604. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_table_detail.py +0 -0
  605. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_token_last_used.py +0 -0
  606. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
  607. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/_workspace_load_plan.py +0 -0
  608. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/agent_service.py +0 -0
  609. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/billing_service.py +0 -0
  610. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/branch_service.py +0 -0
  611. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
  612. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
  613. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/docs_service.py +0 -0
  614. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/doctor_service.py +0 -0
  615. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
  616. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/feature_service.py +0 -0
  617. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/flow_validation.py +0 -0
  618. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
  619. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/kai_service.py +0 -0
  620. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/lineage_service.py +0 -0
  621. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/member_service.py +0 -0
  622. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/notification_service.py +0 -0
  623. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
  624. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/schedule_service.py +0 -0
  625. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/search_service.py +0 -0
  626. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/sharing_service.py +0 -0
  627. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
  628. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/table_usage.py +0 -0
  629. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/transformation_service.py +0 -0
  630. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/services/variables_service.py +0 -0
  631. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/stream_client.py +0 -0
  632. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/__init__.py +0 -0
  633. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
  634. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/branch_scope.py +0 -0
  635. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/clone.py +0 -0
  636. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
  637. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/git_utils.py +0 -0
  638. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/manifest.py +0 -0
  639. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/naming.py +0 -0
  640. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/secrets.py +0 -0
  641. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/sync/sql_split.py +0 -0
  642. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/telemetry.py +0 -0
  643. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/src/keboola_agent_cli/yaml_input.py +0 -0
  644. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/__init__.py +0 -0
  645. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/helpers.py +0 -0
  646. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agent_cli.py +0 -0
  647. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agent_prompt.py +0 -0
  648. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agent_prompt_helper.py +0 -0
  649. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agent_runner.py +0 -0
  650. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agent_service.py +0 -0
  651. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agent_tombstone.py +0 -0
  652. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_agents_store_events.py +0 -0
  653. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_ai_client.py +0 -0
  654. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_client.py +0 -0
  655. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_device.py +0 -0
  656. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_models.py +0 -0
  657. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_picker.py +0 -0
  658. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_pkce.py +0 -0
  659. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_register_projects.py +0 -0
  660. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_sentinel.py +0 -0
  661. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_state_store.py +0 -0
  662. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_auth_totp.py +0 -0
  663. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_base_service.py +0 -0
  664. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_billing_cli.py +0 -0
  665. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_billing_client.py +0 -0
  666. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_billing_service.py +0 -0
  667. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_branch_metadata_cli.py +0 -0
  668. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_branch_metadata_service.py +0 -0
  669. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_branch_service.py +0 -0
  670. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_build_hook.py +0 -0
  671. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_changelog_check.py +0 -0
  672. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_changelog_render.py +0 -0
  673. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_check_command_sync.py +0 -0
  674. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_check_file_size.py +0 -0
  675. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_check_release_scope.py +0 -0
  676. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_check_sentinel_guards.py +0 -0
  677. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_check_version_gates.py +0 -0
  678. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_checkbox_select.py +0 -0
  679. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_choice_enums.py +0 -0
  680. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_client_device_enrollment.py +0 -0
  681. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_client_token_events.py +0 -0
  682. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_component_cli.py +0 -0
  683. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_clone_cli.py +0 -0
  684. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_clone_service.py +0 -0
  685. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_create_service.py +0 -0
  686. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_encryption.py +0 -0
  687. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_examples.py +0 -0
  688. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_metadata.py +0 -0
  689. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_rename.py +0 -0
  690. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_rename_cli.py +0 -0
  691. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_resolution.py +0 -0
  692. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_row_service.py +0 -0
  693. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_search.py +0 -0
  694. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_search_cli.py +0 -0
  695. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_set_default_bucket.py +0 -0
  696. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_set_guard.py +0 -0
  697. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_state.py +0 -0
  698. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_trash.py +0 -0
  699. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_config_update.py +0 -0
  700. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_data_app_git_repo.py +0 -0
  701. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_data_app_password.py +0 -0
  702. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_data_app_plain_env_keys.py +0 -0
  703. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_data_app_secrets_cli.py +0 -0
  704. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_data_app_secrets_service.py +0 -0
  705. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_data_app_validate_repo_service.py +0 -0
  706. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_dev_portal_cli.py +0 -0
  707. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_dev_portal_client.py +0 -0
  708. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_dev_portal_service.py +0 -0
  709. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_docs_cli.py +0 -0
  710. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_doctor_service.py +0 -0
  711. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_e2e_auth.py +0 -0
  712. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_e2e_config_dir_mode.py +0 -0
  713. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_e2e_lineage_deep.py +0 -0
  714. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_encrypt_cli.py +0 -0
  715. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_encrypt_service.py +0 -0
  716. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_encryption.py +0 -0
  717. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_errors.py +0 -0
  718. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_feature_cli.py +0 -0
  719. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_feature_service.py +0 -0
  720. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_file_locking.py +0 -0
  721. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_flow_examples.py +0 -0
  722. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_flow_validation.py +0 -0
  723. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_gen_command_reference.py +0 -0
  724. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_gen_endpoint_reference.py +0 -0
  725. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_gen_release_notes.py +0 -0
  726. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_generate_promotion_pipeline.py +0 -0
  727. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_http_base.py +0 -0
  728. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_http_base_auth.py +0 -0
  729. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_http_forwarder_service.py +0 -0
  730. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_integration.py +0 -0
  731. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_job_options.py +0 -0
  732. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_json_utils.py +0 -0
  733. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_kai_cli.py +0 -0
  734. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_kai_service.py +0 -0
  735. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_lib_device_enrollment.py +0 -0
  736. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_license_consistency.py +0 -0
  737. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_lineage_service.py +0 -0
  738. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_local_ai_chat.py +0 -0
  739. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_manage_client.py +0 -0
  740. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_manage_token_bulk.py +0 -0
  741. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_manage_token_cli.py +0 -0
  742. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_mcp_migration_recipe.py +0 -0
  743. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_member_cli.py +0 -0
  744. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_member_service.py +0 -0
  745. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_merge_request_cli.py +0 -0
  746. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_migrate_cicd.py +0 -0
  747. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_models.py +0 -0
  748. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_normalize_script.py +0 -0
  749. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_notification_cli.py +0 -0
  750. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_notification_client.py +0 -0
  751. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_notification_service.py +0 -0
  752. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_output.py +0 -0
  753. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_pricing.py +0 -0
  754. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_project_create_cli.py +0 -0
  755. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_project_edit.py +0 -0
  756. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_project_info_cli.py +0 -0
  757. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_project_info_service.py +0 -0
  758. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_release_kbagent_ai_kit_sync.py +0 -0
  759. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_repl.py +0 -0
  760. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_result_models.py +0 -0
  761. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_run_broadcaster.py +0 -0
  762. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_schedule_cli.py +0 -0
  763. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_schedule_service.py +0 -0
  764. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_scheduler_client.py +0 -0
  765. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_search_service.py +0 -0
  766. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_semantic_layer_schema.py +0 -0
  767. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_serve_banner_encoding.py +0 -0
  768. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_serve_conversation_id.py +0 -0
  769. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_serve_ui.py +0 -0
  770. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_server_auth.py +0 -0
  771. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_server_permissions.py +0 -0
  772. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_server_project_ref.py +0 -0
  773. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sharing_cli.py +0 -0
  774. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sharing_service.py +0 -0
  775. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_skill_frontmatter.py +0 -0
  776. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sql_split.py +0 -0
  777. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_clone.py +0 -0
  778. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_describe_service.py +0 -0
  779. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_export_filters.py +0 -0
  780. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_snapshots.py +0 -0
  781. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_table_definition.py +0 -0
  782. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_tables.py +0 -0
  783. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_storage_truncate.py +0 -0
  784. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_stream_cli.py +0 -0
  785. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_stream_client.py +0 -0
  786. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_stream_service.py +0 -0
  787. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_baseline_stamping.py +0 -0
  788. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_branch_mapping.py +0 -0
  789. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_branch_scope.py +0 -0
  790. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_cli.py +0 -0
  791. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_cli_behavior.py +0 -0
  792. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_clone.py +0 -0
  793. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_clone_links.py +0 -0
  794. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_code_extraction.py +0 -0
  795. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_config_format.py +0 -0
  796. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_data_app_type.py +0 -0
  797. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_e2e.py +0 -0
  798. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_encrypt.py +0 -0
  799. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_force_pull_baseline.py +0 -0
  800. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_manifest.py +0 -0
  801. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_naming.py +0 -0
  802. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_plaintext_audit.py +0 -0
  803. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_pull_companion_files.py +0 -0
  804. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_push_script_guard.py +0 -0
  805. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_secrets.py +0 -0
  806. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_sync_storage_jobs.py +0 -0
  807. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_table_usage.py +0 -0
  808. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_telemetry.py +0 -0
  809. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_token_cli.py +0 -0
  810. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_token_provider.py +0 -0
  811. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_token_service.py +0 -0
  812. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_transformation_cli.py +0 -0
  813. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_transformation_ops.py +0 -0
  814. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_triggers_client.py +0 -0
  815. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_url_copy.py +0 -0
  816. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_variables_service.py +0 -0
  817. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_workspace_sql_helper.py +0 -0
  818. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/tests/test_yaml_input.py +0 -0
  819. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/index.html +0 -0
  820. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/postcss.config.js +0 -0
  821. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/App.tsx +0 -0
  822. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/api/client.test.ts +0 -0
  823. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/api/client.ts +0 -0
  824. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/changelogNotes.test.ts +0 -0
  825. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/changelogNotes.ts +0 -0
  826. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/AgentRunView.tsx +0 -0
  827. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/ConfirmModal.tsx +0 -0
  828. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/DetailTabs.tsx +0 -0
  829. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/Drawer.tsx +0 -0
  830. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/Empty.tsx +0 -0
  831. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/JsonView.tsx +0 -0
  832. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/KeyValueGrid.tsx +0 -0
  833. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
  834. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/PillList.tsx +0 -0
  835. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/RawDetail.tsx +0 -0
  836. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/SessionExpiredBanner.tsx +0 -0
  837. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/Table.tsx +0 -0
  838. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/components/WhatsNew.tsx +0 -0
  839. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/config/credits.test.ts +0 -0
  840. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/config/credits.ts +0 -0
  841. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/index.css +0 -0
  842. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/layout/Shell.tsx +0 -0
  843. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/layout/Sidebar.tsx +0 -0
  844. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/layout/StatusBar.tsx +0 -0
  845. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/layout/TopBar.tsx +0 -0
  846. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/lib/time.test.ts +0 -0
  847. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/lib/time.ts +0 -0
  848. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/main.tsx +0 -0
  849. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Agents.tsx +0 -0
  850. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Branches.tsx +0 -0
  851. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Changelog.tsx +0 -0
  852. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Components.tsx +0 -0
  853. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Dashboard.tsx +0 -0
  854. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Doctor.tsx +0 -0
  855. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Encrypt.tsx +0 -0
  856. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Jobs.tsx +0 -0
  857. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/JobsAll.tsx +0 -0
  858. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Lineage.tsx +0 -0
  859. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Members.tsx +0 -0
  860. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Org.tsx +0 -0
  861. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Projects.tsx +0 -0
  862. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Search.tsx +0 -0
  863. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
  864. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
  865. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Sharing.tsx +0 -0
  866. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Tokens.tsx +0 -0
  867. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/TokensAll.tsx +0 -0
  868. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/Workspaces.tsx +0 -0
  869. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/storageSel.test.ts +0 -0
  870. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/tokensShared.test.ts +0 -0
  871. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/pages/tokensShared.tsx +0 -0
  872. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/router.test.ts +0 -0
  873. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/router.ts +0 -0
  874. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/state.tsx +0 -0
  875. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/theme.tsx +0 -0
  876. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/types.ts +0 -0
  877. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/src/useHashSelection.ts +0 -0
  878. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/tailwind.config.ts +0 -0
  879. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/tsconfig.json +0 -0
  880. {keboola_cli-0.96.2 → keboola_cli-0.100.2}/web/frontend/vite.config.ts +0 -0
@@ -0,0 +1,1544 @@
1
+ # CLAUDE.md - Development Context for Claude Code
2
+
3
+ > **Contributors**: Read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a PR.
4
+ > It covers coding style, security principles, Keboola API best practices,
5
+ > and the full checklist for adding new CLI commands.
6
+
7
+ ## Build and Run
8
+
9
+ ```bash
10
+ # Install in development mode (editable)
11
+ uv pip install -e ".[dev]"
12
+
13
+ # Or install dependencies only
14
+ uv sync
15
+
16
+ # Run the CLI
17
+ kbagent --help
18
+ uv run kbagent --help
19
+
20
+ # Run a specific command
21
+ kbagent --json project list
22
+ ```
23
+
24
+ A `Makefile` provides shortcuts for common tasks. Run `make help` to see all targets, or use:
25
+
26
+ ```bash
27
+ make install # install in dev mode
28
+ make test # run all tests
29
+ make lint # run ruff linter
30
+ make format # format code
31
+ make check # lint + format-check + changelog-check + test (CI-like)
32
+ make hooks # install pre-commit hook
33
+ make clean # remove caches and build artifacts
34
+ ```
35
+
36
+ ## Testing
37
+
38
+ ```bash
39
+ # Run all tests
40
+ uv run pytest tests/ -v
41
+
42
+ # Run a specific test file
43
+ uv run pytest tests/test_cli.py -v
44
+
45
+ # Run a specific test class or method
46
+ uv run pytest tests/test_cli.py::TestProjectAdd -v
47
+ uv run pytest tests/test_cli.py::TestProjectAdd::test_project_add_success_json -v
48
+ ```
49
+
50
+ ## Project Structure
51
+
52
+ ```
53
+ src/keboola_agent_cli/
54
+ __init__.py # PUBLIC SDK ENTRYPOINT + __version__. Re-exports the importable
55
+ # facade (Client, Files, FileEntry) and the typed result models
56
+ # (JobResult, QueryResult, UploadTableResult, SyncPushResult,
57
+ # ConfigDetailResult, CloneResult, JobIdempotencyStore). Everything
58
+ # in __all__ is committed public API (semver). __version__ is read
59
+ # at runtime via importlib.metadata; never hardcoded. See docs/sdk.md.
60
+ lib.py # In-process SDK facade: Client (query/run_job/config_detail/
61
+ # upload_table + .files + .raw) over KeboolaClient. Stateless,
62
+ # config-dir-free, token passed at construction (issue #415). See docs/sdk.md.
63
+ result_models.py # Typed pydantic return contracts for the SDK facade (extra="allow",
64
+ # populate_by_name); the semver-stable shapes consumers type against (issue #428).
65
+ py.typed # PEP 561 marker -- ships in the wheel so downstream mypy/ty treat the SDK as typed.
66
+ __main__.py # python -m support
67
+ cli.py # Typer root app, global options, subcommand wiring
68
+ constants.py # Shared constants + dynamic APP_NAME resolution (retry params, timeouts, defaults)
69
+ json_utils.py # Deep-merge, set_nested_value, compute_diff utilities
70
+ models.py # Pydantic models shared across layers
71
+ effective_branch.py # resolve_branch(): the ONLY code that applies the `branch use` active branch;
72
+ # records project + branch for the `Target:` line / `targets` key (#766)
73
+ project_ref.py # resolve_project_ref(): a project ID given where an alias is expected -> the
74
+ # alias (CLI-22); applied by commands/_project_ref.py and serve's dependency
75
+ output.py # OutputFormatter: JSON vs Rich dual-mode output
76
+ errors.py # KeboolaApiError, ConfigError, ErrorCode enum, mask_token()
77
+ config_store.py # JSON persistence for config.json (0600 permissions)
78
+ permissions.py # PermissionEngine (--deny-writes / --deny-destructive session firewall)
79
+ changelog.py # Version changelog data + helpers (update on every release)
80
+ auto_update.py # Auto-update on startup + "What's new" display
81
+
82
+ # LAYER 3 -- HTTP clients (all inherit BaseHttpClient in http_base.py:
83
+ # shared 429/5xx retry + exponential backoff)
84
+ http_base.py # BaseHttpClient - shared retry/backoff + common HTTP infra
85
+ client/ # Storage API + Queue API package (X-StorageApi-Token);
86
+ # split by endpoint family (storage_tables/storage_files/configs/
87
+ # queue/tokens/branches/stream/query/workspaces/editor/misc + _core/_transfer),
88
+ # composed into one KeboolaClient via mixins (#520)
89
+ manage_client.py # Manage API (X-KBC-ManageApiToken)
90
+ ai_client.py # AI Service API (component schemas, Kai)
91
+ data_science_client.py # Data Science API (data apps)
92
+ metastore_client.py # Metastore API (semantic layer)
93
+ dev_portal_client.py # Developer Portal API
94
+ stream_client.py # Stream / Data Streams API (OTLP/HTTP sources)
95
+
96
+ commands/ # LAYER 1 -- thin Typer commands, one file per group (31 modules):
97
+ # project config job storage flow branch workspace data_app
98
+ # sync semantic_layer agent stream feature dev_portal kai
99
+ # sharing lineage schedule search org component encrypt
100
+ # permissions serve http_client repl init doctor version
101
+ # changelog context
102
+ # _helpers.py = formatter/service-factory/error-mapping; _*.py = private helpers
103
+ services/ # LAYER 2 -- business logic, one <group>_service.py per command group
104
+ # (DI: receives ConfigStore + client_factory; base.py = parallel infra;
105
+ # member_service, variables_service, repo_validate_service,
106
+ # deep_lineage_service are extra non-1:1 services)
107
+ server/ # FastAPI app behind `kbagent serve` (REST API + Web UI mount + SSE)
108
+ sync/ # GitOps sync engine (manifest v3, pull/push/diff, branch-linking)
109
+ _ui_dist/ # bundled React SPA served by `kbagent serve --ui`
110
+
111
+ tests/ # ~137 files; mirror the layers (one test_<module>.py per command/service)
112
+ conftest.py # Shared fixtures (tmp_config_dir, config_store, formatters)
113
+ helpers.py # Shared test utilities
114
+ test_cli.py # End-to-end CLI tests via typer.testing.CliRunner
115
+ test_e2e*.py # E2E tests against a real API (make test-e2e; needs E2E_API_TOKEN + E2E_URL)
116
+ test_integration.py # Integration tests (edge cases, linting)
117
+ ```
118
+
119
+ ## Architecture: 3-Layer Design
120
+
121
+ ```
122
+ CLI Commands (commands/) --> Services (services/) --> API Client (client/, manage_client.py)
123
+ Typer, output Business logic HTTP, endpoints
124
+ ```
125
+
126
+ - API changes: modify only the relevant LAYER 3 client (`client/` package, `manage_client.py`, ...)
127
+ - Business logic changes: modify only `services/`
128
+ - UI changes: modify only `commands/`
129
+
130
+ ### HTTP Clients
131
+
132
+ Seven clients, all inheriting `BaseHttpClient` (`http_base.py`) which provides shared retry/backoff logic (429/5xx, exponential backoff, 3 retries) and common HTTP infrastructure:
133
+
134
+ - **KeboolaClient** (`client/` package): Storage API + Queue API, auth via `X-StorageApi-Token`
135
+ - **ManageClient** (`manage_client.py`): Manage API, auth via `X-KBC-ManageApiToken`
136
+ - **AiServiceClient** (`ai_client.py`): AI Service API (component schemas, Kai), URL derived as `ai.{stack_suffix}`
137
+ - **DataScienceClient** (`data_science_client.py`): Data Science API (data apps)
138
+ - **MetastoreClient** (`metastore_client.py`): Metastore API (semantic layer)
139
+ - **DeveloperPortalClient** (`dev_portal_client.py`): Developer Portal API (component publishing)
140
+ - **StreamClient** (`stream_client.py`): Stream / Data Streams API (OTLP/HTTP sources)
141
+
142
+ ### No MCP passthrough (removed in 0.85.0)
143
+
144
+ kbagent used to proxy `keboola-mcp-server` tools through a `tool` command group. That
145
+ passthrough -- the group, `McpService`, the `/mcp/*` routes, the `--type mcp_tool` agent
146
+ flavour and the MCP server install/auto-update -- was removed in 0.85.0 (epic #390 phase 3).
147
+ Every tool the catalog exposed has a native command; the historical tool-to-command map is
148
+ `docs/mcp-migration.md`. Do not reintroduce an MCP client here: add a native command instead.
149
+ `keboola-mcp-server` itself is unaffected and still works with Claude Desktop / Cursor -- it
150
+ is simply a separate distribution kbagent no longer manages.
151
+
152
+ ## Versioning
153
+
154
+ **Single source of truth: `pyproject.toml`** (`version = "X.Y.Z"`).
155
+
156
+ - `src/keboola_agent_cli/__init__.py` reads the version at runtime via `importlib.metadata.version(APP_NAME)`. `APP_NAME` is resolved **dynamically** in `constants.py` (`_resolve_app_name()`: prefers the current distribution `keboola-cli`, falls back to the legacy `keboola-agent-cli` so the #424 migration-bridge wheel keeps working) -- it is **not** a fixed literal. **Never hardcode a version string in `__init__.py`.**
157
+ - `plugins/kbagent/.claude-plugin/plugin.json` must match. Run `make version-sync` (or `python scripts/sync_version.py`) to update it.
158
+ - The pre-commit hook and CI automatically check version consistency.
159
+
160
+ ### Version bumps happen ONLY in a dedicated release PR
161
+
162
+ **Feature/fix PRs MUST NOT bump the version and MUST NOT add a `changelog.py`
163
+ entry.** PRs are routinely developed in parallel (separate AI sessions, one per
164
+ issue); when each of them bumps `pyproject.toml`, every merge is a version
165
+ conflict and the merge order silently renumbers releases. The historical
166
+ `KNOWN_UNRELEASED` list in `scripts/generate_changelog.py` -- 18 versions whose
167
+ content shipped with no release notes -- is exactly what that pattern produces.
168
+
169
+ The flow is instead:
170
+
171
+ 1. **Feature PR**: merges to `main` with NO change to `pyproject.toml`
172
+ `version` and NO `changelog.py` entry. When the PR documents version-gated
173
+ behavior (gotchas.md, commands-reference.md, this file), it tags it with
174
+ the literal placeholder **`vNEXT`** -- `(since vNEXT)` / `vNEXT+`.
175
+ `make version-gate-check` ignores the placeholder (it only matches numeric
176
+ versions) but rejects a guessed numeric version with no changelog entry,
177
+ so a numeric future tag cannot even pass CI. Writing `vNEXT` in a feature
178
+ PR is correct and stays green -- the placeholder only becomes fatal in a
179
+ version-raising PR (below).
180
+ 2. **Release PR** (its only job): bump `pyproject.toml`, review everything
181
+ merged since the last release (`git log v<last>..origin/main`), write ONE
182
+ changelog entry covering all of it (one bullet per logical change, with
183
+ `(#PR)` references), replace every `vNEXT` placeholder with the real
184
+ version (`make vnext-check` verifies it -- CI runs the same check
185
+ automatically on any PR that raises the version, so a missed placeholder
186
+ is a red build, not a silent ship), add the curated What's-new entry to
187
+ `web/frontend/src/whatsnew.ts` when the release ships UI-visible features
188
+ (skipping it errors nowhere -- the popup falls back to the previous reel
189
+ and the release's UI work ships dark), run `make version-sync`. Merge,
190
+ then tag the merge commit -- **the tag push is the ONLY manual action**:
191
+ the pipeline renders the release notes from the changelog entry
192
+ (`scripts/gen_release_notes.py`; never write them by hand), publishes
193
+ PyPI + native binaries, and creates + fills the GitHub Release. Verify
194
+ afterwards: pipeline green, `gh release view` shows a non-empty body and
195
+ both wheels. Full checklist: `CONTRIBUTING.md` >
196
+ "Releasing a new version".
197
+
198
+ **Inside the release PR**: edit `pyproject.toml`, add the changelog entry to `src/keboola_agent_cli/changelog.py`, then run `make version-sync`. Do not edit `__init__.py` or `plugin.json` manually. `make changelog-check` (release-time, needs `gh`) enforces changelog completeness in both directions.
199
+
200
+ The one exception is a **beta/pre-release** (below): there the bump deliberately
201
+ rides the feature branch, because the pre-release tag and GitHub Release are cut
202
+ from that branch -- the branch temporarily *is* the release PR.
203
+
204
+ ### Beta / pre-release versions
205
+
206
+ Beta and release-candidate versions follow **PEP 440**: `0.44.0b1`, `0.44.0rc1`, ... -- **not** the SemVer `-beta.1` form (hatchling + uv require PEP 440 syntax in `pyproject.toml`). Three independent gates keep stable users safe from accidentally landing on a beta:
207
+
208
+ 1. **PEP 440 pre-release suffix.** pip / uv default to **skipping** pre-releases unless told otherwise (`--pre` for pip, `--prerelease=allow` for uv).
209
+ 2. **GitHub Release `prerelease: true` flag.** The auto-update startup hook reads `/releases/latest`, which never names a release marked `prerelease`; when it reads the release list, it skips every release marked `prerelease` (and every PEP 440 pre-release version) unless `--beta` is given. Marking the release `--prerelease` makes it invisible to the auto-update path.
210
+ 3. **Tag-pinned install URL.** When `--beta` opts into a pre-release, the install command appends `@v<version>` to the git+ source URL so uv pulls the **exact commit** the tag points to. Without this, uv would resolve the default branch (`main`) and -- if the beta lives on a feature branch -- silently install the stale main HEAD even though the version fetcher advertised the beta tag.
211
+
212
+ **Author workflow (release a beta from a feature branch):**
213
+
214
+ ```bash
215
+ # 1. Bump pyproject.toml to PEP 440 pre-release form on the feature branch
216
+ # version = "0.44.0b1"
217
+ make version-sync # propagates to plugin.json / marketplace.json
218
+
219
+ # 2. Add a changelog entry under that key in src/keboola_agent_cli/changelog.py
220
+ # 3. Commit + push to PR (NOT to main -- main stays on the stable channel)
221
+ git push origin feat/my-feature
222
+
223
+ # 4. Tag the PR head SHA + push tag
224
+ git tag v0.44.0b1 && git push origin v0.44.0b1
225
+
226
+ # 5. KEY STEP: create the GitHub Release WITH --prerelease pointing at the tag
227
+ gh release create v0.44.0b1 --prerelease \
228
+ --title "v0.44.0 — Beta 1" \
229
+ --notes-file release-notes-0.44.0b1.md
230
+ ```
231
+
232
+ When the beta cooks long enough, merge the PR (stable squash) and ship `0.44.0` from main with a normal release **without** `--prerelease` -- auto-update picks it up on next startup.
233
+
234
+ **User opt-in (consume betas):**
235
+
236
+ - One-shot: `kbagent update --beta` -- resolver opts into pre-releases for this invocation only.
237
+ - Per-shell: `export KBAGENT_INCLUDE_PRERELEASE=1` -- every `kbagent update` / `kbagent version` in that shell treats betas as installable.
238
+ - **No persistent setting.** Each beta install is an active choice; never a forgotten "I once typed --beta six months ago" foot-gun.
239
+
240
+ The startup auto-update hook is **never** affected by `--beta` / env opt-in -- it uses the stable channel only. Beta installs only come from explicit `kbagent update --beta`.
241
+
242
+ Full author checklist: see `CONTRIBUTING.md` > "Releasing a beta (pre-release) version".
243
+
244
+ ## Coding Conventions
245
+
246
+ > **0. (BINDING) Follow [CONTRIBUTING.md](CONTRIBUTING.md) in full.** Every code change -- human or AI agent -- must satisfy the rules in `CONTRIBUTING.md`. Specifically, the "Code Quality Patterns" section is non-negotiable: dataclasses (not bare tuples) for multi-value returns; categorical arguments before variable ones; `ErrorCode` enum (never raw strings); file-size budgets (measured in CODE LINES -- docstrings and comments are free; `make loc-check`); context managers over lambdas; named functions over assigned anonymous functions; `ty` clean for new code. The `.claude/settings.json` post-edit hooks run `ruff check --fix`, `ruff format`, and `ty check` after every edit -- when an AI agent edits a file in this repo, those checks fire automatically and any failure must be addressed before continuing. If a rule conflicts with an existing pattern in legacy code, **fix it in the PR you are touching** or open a follow-up issue; do not propagate the pattern.
247
+
248
+ 1. **Typer commands** are thin - they parse arguments, call a service, and format output. No business logic in commands.
249
+
250
+ 2. **Services** receive `ConfigStore` and a `client_factory` callable via dependency injection. This enables easy testing with mocks.
251
+
252
+ 3. **All data models** use Pydantic 2.x (`BaseModel`). Models are defined in `models.py` and shared across layers.
253
+
254
+ 4. **Dual output**: every command supports `--json` for structured output and Rich formatting for human-readable output. Use `OutputFormatter.output(data, human_formatter)`.
255
+
256
+ 5. **Error handling**: commands catch `KeboolaApiError` and `ConfigError`, map them to the appropriate exit code, and output structured errors in JSON mode. Report a `KeboolaApiError` with `emit_api_error(formatter, exc)` (`commands/_helpers.py`), which keeps its `retryable` and `details`. `tests/test_error_forwarding.py` fails on a handler that drops them.
257
+
258
+ 6. **Exit codes**: 0=success, 1=general error, 2=usage error, 3=auth error, 4=network error, 5=config error, 6=permission denied, 7=job timed out and cancelled (`JOB_TIMEOUT_TERMINATED`), 130=interrupted.
259
+
260
+ 7. **Token masking**: tokens are never printed in full. Use `mask_token()` from `errors.py`.
261
+
262
+ 8. **Config file**: stored at `~/.config/keboola-agent-cli/config.json` with `0600` permissions. Managed by `ConfigStore`.
263
+
264
+ 9. **Tests**: use `typer.testing.CliRunner` for CLI tests, `unittest.mock` for mocking services and clients, `pytest` fixtures from `conftest.py`.
265
+
266
+ 10. **Dependencies**: typer, rich, httpx, pydantic, platformdirs, jsonschema, pyyaml. Dev: pytest, pytest-httpx, pytest-asyncio, ruff.
267
+
268
+ 11. **Error accumulation**: multi-project operations collect per-project errors without stopping. One project failing doesn't block others (see `lineage_service.py`, `org_service.py`).
269
+
270
+ 12. **Manage token security**: never persisted, never passed as CLI argument, never logged. Default-deny since 0.29.0: only via interactive hidden prompt; the `KBC_MANAGE_API_TOKEN` env var is **ignored** unless the top-level `--allow-env-manage-token` flag is passed. Default-deny closes the AI-exfiltration risk where any subprocess (including the AI agent itself) inherits the manage token via env. CI/CD callers must opt in explicitly.
271
+
272
+ 13. **Idempotency**: `org setup` skips already-registered projects by matching `project_id`. Safe to re-run.
273
+
274
+ 14. **Protected main branch**: direct pushes to `main` are blocked. Always create a feature branch, commit there, push, create a PR via `gh pr create`, merge via `gh pr merge`, then switch back to main and pull.
275
+
276
+ 15. **Pre-commit checks are mandatory.** Before every `git commit`, run `ruff check` and `ruff format --check` on changed files. A pre-commit hook (`scripts/pre-commit`, install via `make hooks`) does this automatically. **Never commit without passing lint + format.** If using sub-agents that write code, always run `make check` (or at minimum `ruff check src/ tests/ && ruff format . --check`) before committing their output.
277
+
278
+ 16. **E2E test coverage**: Every new CLI command MUST have a corresponding E2E test in `tests/test_e2e.py`. Run `make test-e2e` to verify. E2E tests require `E2E_API_TOKEN` and `E2E_URL` env vars and exercise the full CLI against a real Keboola project.
279
+
280
+ 17. **Plugin & agent sync are mandatory, NOT CI-enforced.** When adding/removing/renaming any command -- and at every version bump -- follow `CONTRIBUTING.md` sections "Documentation changes (mandatory!)", "Plugin synchronization map", and "Releasing a new version". CI catches drift only in `SKILL.md` (decision table), `plugin.json` (version), and `changelog.py` (release entries). The following files are **silent-drift risks** that ship broken if you forget them:
281
+ - `src/keboola_agent_cli/commands/context.py` (`AGENT_CONTEXT`)
282
+ - `CLAUDE.md` `## All CLI Commands` section (this file)
283
+ - `plugins/kbagent/agents/keboola-expert.md` -- **highest risk** (Rule 6 VERSION GATE, tool selection matrix, inline gotchas)
284
+ - `plugins/kbagent/skills/kbagent/SKILL.md` -- description triggers and workflow links (the auto-generated table is CI-checked, the rest is not)
285
+ - `plugins/kbagent/skills/kbagent/references/commands-reference.md`
286
+ - `plugins/kbagent/skills/kbagent/references/gotchas.md` (every new gotcha **MUST** be tagged with a version -- `(since v0.90.1)` in a feature PR, replaced with the real `(since vX.Y.Z)` by the release PR; the *replacement* is now CI-enforced on any version-raising PR, the *tagging* still is not)
287
+ - `plugins/kbagent/skills/kbagent/references/<topic>-workflow.md` (e.g. `semantic-layer-workflow.md`, `workspace-workflow.md`, `sync-workflow.md`)
288
+
289
+ Forgetting any of these does not fail tests or lint -- it ships an AI agent that quietly recommends commands that do not exist on the user's installed kbagent version, or refuses commands that do. Treat the change as **not done** until every applicable file has been updated.
290
+
291
+ 18. **Session-sentinel guards are CI-enforced.** `make check-sentinel-guards`
292
+ (in `make check`) rejects three kinds of drift: a `config.json` credential
293
+ write that is not sentinel-aware, a `BaseHttpClient` subclass that neither
294
+ declares `SESSION_AUTH_FEATURE` nor is recorded as bearer-capable, and a
295
+ `require_static_token` guard missing from `SESSION_UNSUPPORTED_FEATURES`
296
+ (`services/_auth_registration.py`) -- the tuple `auth login` /
297
+ `auth register-projects` disclose and every doc surface defers to. Run
298
+ `python scripts/check_sentinel_guards.py --list` to see the inventory.
299
+
300
+ 19. **Only `effective_branch.resolve_branch()` applies the active branch.**
301
+ Commands and services get the branch ID from it and never read
302
+ `ProjectConfig.active_branch_id` themselves: the function records the
303
+ project and branch, and `OutputFormatter` reports them (a `Target:` line
304
+ on stderr, `targets` in the `--json` envelope, also for `--dry-run`).
305
+ `tests/test_effective_branch.py` fails on a new direct read. A read that
306
+ only shows or manages the active branch must be on its list, with a reason.
307
+
308
+ 20. **Services receive project aliases, never project IDs.** `--project`
309
+ (and `project use`, `KBAGENT_PROJECT`, serve's `{project}` / `?project=`)
310
+ also takes a project ID; the root command group
311
+ (`commands/_project_ref.py`) translates it to the alias before the command
312
+ runs. A new command gets this without extra code. A new command whose
313
+ `--project` is not a registry lookup (a NEW alias like `project add`, an
314
+ offline filter like `lineage show`) must be added to `NO_LOOKUP_COMMANDS`
315
+ there, and an option with another name that takes an existing alias (like
316
+ `config clone --target-project`) to `ALIAS_OPTIONS`.
317
+ `tests/test_project_ref.py` fails on a new option whose flag contains
318
+ `project`, `alias` or `stack` until it is in `ALIAS_OPTIONS` or in the
319
+ test's `NOT_AN_ALIAS` list; an option with any other name (like
320
+ `sync clone --target`) needs that decision by hand.
321
+
322
+ 21. **The CLI interface spec is binding.** Every change to the command-line interface or the `kbagent serve` REST API follows [`docs/cli-interface-spec.md`](docs/cli-interface-spec.md); `make cli-spec-check` enforces the rules that a machine can check.
323
+
324
+ ## Claude Code Plugin
325
+
326
+ The plugin lives here in `plugins/kbagent/` and is **published through `keboola/ai-kit`**. It exposes: a CLI (`kbagent`), three skills (`kbagent`, `kbagent-cicd-migration`, `kbagent-promotion-pipeline`), three slash commands (`/kbagent:setup`, `/keboola`, `/kbagent:review`), and two specialist subagents (`keboola-expert`, `kbagent-pr-reviewer`). All are namespaced under `kbagent:`. `/kbagent:setup` is the documented one-command first-run path (install CLI -> connect project -> `doctor`); it runs in the main context and spawns no subagent.
327
+
328
+ **Source here, publication there.** The source stays in this repo because four CI gates validate it against the live command tree (`make skill-gen` / `make skill-check`, `scripts/sync_version.py`, `scripts/check_command_sync.py`, `make version-check`) -- none of which exist in ai-kit. What ai-kit owns is the *catalogue*: its `keboola-claude-kit` marketplace carries an external `git-subdir` entry pointing at `plugins/kbagent` in this repo, pinned to a release tag. Keboola has ONE Claude Code marketplace, and it is not this one.
329
+
330
+ **Install path users are told to use:**
331
+ ```
332
+ /plugin marketplace add keboola/ai-kit
333
+ /plugin install kbagent@keboola-claude-kit
334
+ /kbagent:setup
335
+ ```
336
+
337
+ **The sync mechanism** is the `ai-kit-marketplace` job in `.github/workflows/release-kbagent.yml`: on every stable tag it rewrites the kbagent entry's `version` + `source.ref` in ai-kit and opens a PR there (a PR, not a push -- ai-kit's evals must see it). It needs `secrets.AI_KIT_TOKEN` in the `release` environment. No-op safe: an entry already at this version opens nothing.
338
+
339
+ **`.claude-plugin/marketplace.json` in this repo is a DEPRECATED SHIM.** Do not delete it and do not remove its `kbagent` entry: existing installs from `keboola-agent-cli` resolve updates through it, and `scripts/sync_version.py` + `make version-check` still keep its `version` in lock-step with `pyproject.toml`. Its entry `description` carries the migration notice users see in `/plugin` listings. Plan: keep for ~3 releases, then drop the entry and leave a `renames` tombstone. `renames` cannot redirect across marketplaces, so the migration is necessarily a manual two-line user action -- which is why the notice lives in the description. Its relative `source` follows the default branch, so it must be pinned to the last 0.x tag before 1.x documents reach `main` (`CONTRIBUTING.md` > "Releasing a new major version"); for a 1.x version `scripts/sync_version.py` refuses an unpinned shim and never changes the version of a pinned one.
340
+
341
+ **Update rules** -- see `CONTRIBUTING.md` > "Documentation changes (mandatory!)", "Plugin synchronization map", and "Releasing a new version" for the binding checklists. Coding convention #17 above is the short version. Do **not** maintain a parallel update list here -- it always drifts.
342
+
343
+ **Structure:**
344
+ ```
345
+ .claude-plugin/marketplace.json # DEPRECATED shim marketplace (kept so old installs keep updating)
346
+ plugins/kbagent/
347
+ .claude-plugin/
348
+ plugin.json # Plugin manifest (auto-synced from pyproject.toml)
349
+ CLAUDE.md # Operational guidance for Claude Code main agents
350
+ agents/
351
+ keboola-expert.md # Specialist subagent system prompt (HIGHEST silent-drift risk)
352
+ kbagent-pr-reviewer.md # Read-only PR-review subagent system prompt
353
+ commands/
354
+ setup.md # /kbagent:setup slash command (one-command first-run setup)
355
+ keboola.md # /keboola slash command
356
+ review.md # /kbagent:review slash command
357
+ skills/
358
+ kbagent/
359
+ SKILL.md # Trigger rules + auto-generated decision table
360
+ references/
361
+ commands-reference.md # Per-command notes (hand-maintained)
362
+ gotchas.md # Response parsing + (since vX.Y.Z) behavior log
363
+ <topic>-workflow.md # One file per workflow (workspace, branch, sync, ...)
364
+ kbagent-cicd-migration/ # CI/CD migration skill
365
+ kbagent-promotion-pipeline/ # Promotion-pipeline skill
366
+ ```
367
+
368
+ `SKILL.md` instructs Claude to run `kbagent context` as its first step, which dynamically loads the full CLI documentation. That keeps command *signatures* in sync automatically -- but it does **not** save the agent's tool-selection matrix, the gotchas log, or the version-gate examples in `keboola-expert.md`. Those are static and must be updated by hand whenever the CLI changes.
369
+
370
+ ## All CLI Commands
371
+
372
+ > **Hand-maintained, no CI freshness check.** When you add/remove/rename a
373
+ > command, you must edit this section AND the other silent-drift surfaces
374
+ > listed in convention #17 above. See `CONTRIBUTING.md` >
375
+ > "Plugin synchronization map" for the full list.
376
+
377
+ ```
378
+ # Global options: --json, --verbose, --no-color, --config-dir, --conversation-id, --deny-writes, --deny-destructive, --allow-env-manage-token
379
+ # --conversation-id ID (#716): sets the X-Conversation-ID observability header for the
380
+ # invocation; equivalent to KBAGENT_CONVERSATION_ID and takes precedence over it. Exists because an
381
+ # agent harness does not persist shell state between tool calls, so the documented one-time `export`
382
+ # was unsatisfiable -- and re-prepending `export ...` to every command stops it matching a
383
+ # `Bash(kbagent ...)` permission allow-rule, so every call fell through to the safety classifier.
384
+ # For a whole session, set the env var in the harness's own env block instead (Claude Code:
385
+ # settings.json -> env). Neither set = header omitted, as before. Version gate for this entry
386
+ # lives in gotchas.md -- a `(since vNEXT)` tag cannot be written on these `# ` comment lines,
387
+ # because check_version_gates.py parses them as ATX markdown headings (where a `vNEXT` is fatal).
388
+ # --project (CLI-22) takes a registered alias OR a project ID. An alias wins; an ID registered under
389
+ # several aliases is CONFIG_ERROR (exit 5) listing them, unless all are on one stack and exactly one is a
390
+ # session alias. Same for KBAGENT_PROJECT, `project use`, `config clone --target-project`,
391
+ # `sync clone --target`, the `semantic-layer promote/diff` project options, `auth * --stack`, and
392
+ # serve's {project} / ?project= / ?stack= (path and query only, not request bodies). Not for
393
+ # `project add` / `project create` (new alias) or `lineage show` (offline filter). Version gate in
394
+ # gotchas.md.
395
+ # Headless / token-only (0.50.0+): export KBAGENT_PROJECT_FROM_ENV=1 + KBC_TOKEN + KBC_STORAGE_API_URL to synthesize an in-memory `__env__` project (no `project add`, no config.json on disk; token never persisted). Use `--project __env__`. Same env setup also powers `kbagent serve`.
396
+
397
+ kbagent auth login [--stack URL|alias] [--device-code] [--register-projects]
398
+ kbagent auth login-password --email EMAIL (--password PASSWORD | --password-stdin) [--totp-secret SECRET] [--stack URL|alias] [--register-projects]
399
+ kbagent auth status [--stack URL|alias]
400
+ kbagent auth logout [--stack URL|alias] [--remove-projects] [--yes]
401
+ kbagent auth register-projects [--stack URL|alias] [--all] [--project-id ID ...] [--alias ID=ALIAS ...] [--yes]
402
+ # auth stack (CLI-32): without --stack every auth command (and serve's /auth/* without ?stack=) takes the
403
+ # stack of KBAGENT_PROJECT > active project > sole registered project > CONFIG_ERROR naming --stack,
404
+ # KBAGENT_PROJECT and `project use`. Before, only the active project. With --stack given,
405
+ # KBAGENT_PROJECT is not read. A KBAGENT_PROJECT that names no registered project is CONFIG_ERROR in
406
+ # status/logout and is skipped with a `warnings` entry in login/login-password/register-projects.
407
+ # Version gate lives in gotchas.md.
408
+ # auth login-password (0.84.0+): the deliberate unattended exception to auth login's "needs a human at
409
+ # a browser" rule -- email + password (+ TOTP if the account has MFA) grant, no browser, safe to run
410
+ # from a CI secret-backed workflow step. Prefer --password-stdin (or KBC_LOGIN_PASSWORD) over
411
+ # --password -- a value on the command line lands in shell history and process listings;
412
+ # --password/--password-stdin are mutually exclusive (ConfigError if both given).
413
+ # --email/--password/--totp-secret also read from
414
+ # KBC_LOGIN_EMAIL/KBC_LOGIN_PASSWORD/KBC_LOGIN_TOTP_SECRET env vars (mirroring KBC_TOKEN's convention),
415
+ # so a workflow can set them once in a step's env: block. --totp-secret is the base32 TOTP SEED (not
416
+ # a 6-digit code) -- kbagent computes the current code itself (auth/totp.py, stdlib-only RFC 6238),
417
+ # so no human ever types a live code. Only the TOTP factor is resolvable this way; a WebAuthn/passkey-
418
+ # only account gets AUTH_MFA_INVALID and must use `auth login` (needs a browser) instead. Stores the
419
+ # session in auth.json exactly like `auth login` does -- same auth-mode, same "session" column in
420
+ # `project list`, same downstream command support. Storing an account's password (and TOTP seed) as
421
+ # CI secrets is a bigger blast radius than a single scoped project token: use a dedicated,
422
+ # least-privileged service account, never a real human's own credentials. New error code:
423
+ # AUTH_MFA_INVALID.
424
+ # auth (since 0.80.0): browser-based login -- PKCE authorization-code by default (falls back to the
425
+ # RFC 8628 device flow ONLY on a pre-exchange failure: no loopback browser, callback timeout, or an
426
+ # SSH/container/WSL heuristic; --device-code forces it). APPROVAL REQUIRES A HUMAN AT A BROWSER,
427
+ # but driving the command does not: in an ATTENDED session an agent MAY run
428
+ # `auth login --device-code` in a BACKGROUND shell, relay the verification URL + user code it prints
429
+ # before polling starts, and confirm with `auth status` (exit 0 = signed in, exit 3 = not yet). Never
430
+ # in a foreground tool shell (~120s timeout kills the flow mid-flight), never from an unattended task
431
+ # (nobody can approve), never blind-retry without checking `auth status` first (orphans a session);
432
+ # use `auth login-password` or a static Storage token for CI/headless instead. Issues a
433
+ # USER-scoped "programmatic session" (kbc_at_* access token + kbc_rt_* refresh token) stored in
434
+ # auth.json (0600), a sibling of config.json -- config.json's schema and CURRENT_CONFIG_VERSION are
435
+ # unchanged. --register-projects writes each accessible project into config.json with the sentinel
436
+ # token `kbc-session://{project_id}`. A session now works with nearly every command -- the Storage
437
+ # and Manage client paths plus (added by CLI-13) the Scheduler (flow schedule / schedule-remove),
438
+ # Data Streams (stream), Data Science (data-app), the semantic-layer group, the AI Service, and
439
+ # Storage bucket sharing (sharing share / unshare). `serve` reaches them too, because it delegates to
440
+ # the same already-guarded services (see server/dependencies.py). Only three features still fail fast
441
+ # on a sentinel-token project (AUTH_NOT_SUPPORTED_ON_STACK) naming the static-token fallback: the
442
+ # authoritative list is SESSION_UNSUPPORTED_FEATURES in services/_auth_registration.py, shipped to
443
+ # callers as `session_unsupported_features` in --json -- do not re-derive it by hand. `dev-portal` is NOT on it
444
+ # (it authenticates with its own identity, never a project token). Over `serve`, a session that
445
+ # expires at runtime answers HTTP 401 with
446
+ # error_code SESSION_EXPIRED -- a browser login only completes on the host. Serving session projects
447
+ # means whoever holds KBAGENT_SERVE_TOKEN acts as the signed-in USER; see docs/web-server.md.
448
+ # New error codes: AUTH_NOT_SUPPORTED_ON_STACK, AUTH_FLOW_TIMEOUT, AUTH_FLOW_DENIED, AUTH_FLOW_EXPIRED,
449
+ # AUTH_BROWSER_UNAVAILABLE, AUTH_STATE_MISMATCH, SESSION_EXPIRED, SESSION_NOT_FOUND.
450
+ # `auth register-projects` (0.80.0+): fixes the usability gap where nothing was registered unless
451
+ # --register-projects was passed at login, and where the alias offered was a slug of the project
452
+ # NAME (never the numeric id; the id itself resolves as `--project` once registered, CLI-22). Lists every project the session
453
+ # can access with a collision-free suggested alias, then lets the caller pick which to register.
454
+ # --all selects every candidate; --project-id ID (repeatable) selects specific ones (unknown id ->
455
+ # ConfigError); omitting both runs an interactive arrow-key + spacebar checkbox picker (every
456
+ # not-yet-registered project preselected, [a] toggles all, [enter] accepts) followed by a single
457
+ # "Edit aliases?" confirm (default No) that opens the old per-project alias prompt only if opted
458
+ # into -- each row already shows its suggested alias. On a piped stdin or a terminal without real
459
+ # interactive capabilities, it falls back to the original numbers/ranges/'all'/'none' typed prompt.
460
+ # In a non-TTY or --json context with neither --all nor --project-id, it fails fast telling the
461
+ # caller to pass --all or --project-id. --alias ID=ALIAS (repeatable) overrides the
462
+ # suggested alias in every mode. --yes skips only the picker's final confirmation. Never overwrites
463
+ # an existing alias: same project+stack already registered -> status "exists" (no-op); alias taken by
464
+ # something else -> status "skipped" with a rename hint. `auth login` (no --register-projects) also
465
+ # offers this same picker interactively right after a successful login when stdout is a TTY and
466
+ # --json was not used; otherwise it just prints the `auth register-projects` hint. Same picker fix
467
+ # applies retroactively to `auth login --register-projects` (now suffixes on an alias collision
468
+ # instead of silently skipping the second project). See docs/programmatic-auth-login-plan.md
469
+ # section 4.5 for the full design.
470
+ # `auth` over `kbagent serve` (since v0.90.1): `register-projects` / `status` / the project-candidate
471
+ # listing get a `server/routers/auth.py` counterpart -- `POST /auth/register-projects`,
472
+ # `GET /auth/status`, `GET /auth/projects` (the interactive picker's data source; no CLI leaf
473
+ # command of its own). `login` / `login-password` / `logout` deliberately have NO endpoint -- a
474
+ # browser login only completes on the host, a password grant must never sit behind the serve
475
+ # bearer token, and revoking the session is a host-operator action, not a remote one. `/auth/*`
476
+ # is also the FIRST router to enforce the `permissions` policy: every route declares
477
+ # `Depends(require_permission(...))`, so a denial answers HTTP 403 `PERMISSION_DENIED` over REST
478
+ # exactly as on the CLI. Every other route is checked too since #655 (see `permissions` below).
479
+ # The policy comes from the config dir `serve` RESOLVES (its own `--config-dir`, then -- since
480
+ # 0.91.0, #679 -- an explicit root `kbagent --config-dir`, then KBAGENT_CONFIG_DIR, then the
481
+ # local/global chain) plus the session flags of the invocation. On 0.90.1 the root-level
482
+ # `--config-dir` was IGNORED here, so a policy stored beside the projects the caller named was
483
+ # silently not the one enforced; on that version pass --config-dir to `serve` itself.
484
+ # Reachable ways to enforce: a persisted narrow policy
485
+ # (`kbagent permissions set --mode allow --deny auth.register-projects`, needs a real
486
+ # terminal for the confirmation code), or `--mode deny` with `serve` (and the reads you want) in
487
+ # the allow list. `kbagent --deny-writes serve` does NOT work: `serve` is admin-class and
488
+ # `--deny-writes` appends `cli:write`, which spans write+destructive+admin, so the CLI callback
489
+ # blocks the `serve` command itself (exit 6) and no server ever starts. `--deny-destructive`
490
+ # starts the server and blocks every destructive route (none of them under `/auth/*`).
491
+ # See docs/web-server.md.
492
+
493
+ kbagent project create --url URL [--project ALIAS] [--name NAME] [--backend snowflake|bigquery] [--sync-backend-init]
494
+ # project create (since 0.95.0, DMD-1940): the ONLY kbagent command that works from nothing --
495
+ # no account, no token, no `auth login`. POSTs the unauthenticated provisioning endpoint
496
+ # (`/manage/programmatic-projects`, gated by the `agent-provisioning` stack feature
497
+ # / `STACK_FEATURES__AGENT_PROVISIONING`, off on most stacks -- the COMMAND is always
498
+ # registered, so `--help` proves nothing about the stack; without the feature the stack 404s
499
+ # and this exits 1 with AUTH_NOT_SUPPORTED_ON_STACK, naming the flag and the browser path),
500
+ # stores the returned project-pinned session in auth.json, and registers the project in
501
+ # config.json under the `kbc-session://` sentinel -- becoming the default project when nothing
502
+ # else was registered. THE PROJECT IT CREATES IS OWNED BY NOBODY: the result's `confirm_url` is a
503
+ # single-use, days-limited link a human must open and sign in at to take ownership; relay it
504
+ # verbatim. `auth status` re-prints it as `agent_confirm_url` while it is pending, so losing the
505
+ # terminal is recoverable -- losing the claim window is not. Confirming REVOKES this session, so
506
+ # the documented next step is `kbagent auth login --stack URL`; the alias survives it (the
507
+ # sentinel keys on project id + stack, never on the session). Refuses with exit 5 when a session
508
+ # for that stack already exists -- auth.json holds one session per stack, and whoever has one has
509
+ # an account and should create the project in the UI. `--backend` omitted keeps the stack
510
+ # maintainer's own default; `--sync-backend-init` waits for backend init instead of the async
511
+ # default (which warns that the first Storage command may fail until it lands). The provisioning
512
+ # POST is never auto-retried on 5xx/429 -- it is not idempotent, and each success creates an
513
+ # organization, a billable project and a credit grant. A timeout is classified rather than
514
+ # lumped together: a connect timeout never reached the stack (retryable), a READ timeout was
515
+ # delivered and may have succeeded (retryable:false, message says not to repeat -- check
516
+ # `auth status`, whose stored session + claim link is the evidence). `--sync-backend-init`
517
+ # raises that call's read timeout to 300s, which can outlast an agent's foreground shell.
518
+ kbagent project add --project NAME --url URL [--token-stdin | --token-file PATH [--keep-token-file] | --token-env NAME | --token TOKEN]
519
+ kbagent project list
520
+ kbagent project remove --project NAME
521
+ kbagent project edit --project NAME [--url URL] [--token-stdin | --token-file PATH [--keep-token-file] | --token-env NAME | --token TOKEN] [--new-alias NEW]
522
+ kbagent project status [--project NAME | --all-projects]
523
+ kbagent project refresh --project ALIAS [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
524
+ kbagent project refresh --all [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
525
+ kbagent project description-get --project NAME
526
+ kbagent project description-set --project NAME [--text STR | --file PATH | --stdin]
527
+ kbagent project use ALIAS
528
+ kbagent project current
529
+ # Active project (CLI-32): `project remove` (and DELETE /projects/{alias}, bulk-delete, `auth logout
530
+ # --remove-projects`) CLEARS the active project instead of moving it to the next alias; `init --project`
531
+ # that leaves it out clears it too. Results carry `active_project_cleared` / `active_project_set`
532
+ # (project use/add, org setup, auth registration, project create). `project current` adds
533
+ # `resolved_alias` + `resolved_source` (env|active_project|sole|none). Existing keys and the `pin`
534
+ # source value are unchanged. Version gate lives in gotchas.md.
535
+ kbagent project info --project NAME
536
+ kbagent project invite --project ALIAS --email EMAIL --role admin|guest|readOnly|share [--reason TEXT] [--dry-run]
537
+ kbagent project invite --from-csv FILE [--default-role ROLE] [--workers N] [--dry-run]
538
+ kbagent project member-list --project ALIAS [--include-pending]
539
+ kbagent project invitation-list --project ALIAS
540
+ kbagent project invitation-cancel --project ALIAS --email EMAIL [--invitation-id ID] [--yes]
541
+ kbagent project member-remove --project ALIAS --email EMAIL [--yes]
542
+ kbagent project member-set-role --project ALIAS --email EMAIL --role admin|guest|readOnly|share
543
+
544
+ kbagent config list [--project NAME | --all-projects] [--component-type TYPE] [--component-id ID] [--branch ID] [--include-rows]
545
+ kbagent config detail --project NAME [--project NAME ...] --component-id ID [--config-id ID] [--branch ID] [--with-state]
546
+ kbagent config search --query PATTERN [--project NAME | --all-projects] [--component-type TYPE] [--ignore-case] [--regex] [--branch ID]
547
+ 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]
548
+ kbagent config set-default-bucket --project NAME --component-id ID --config-id ID (--bucket BUCKET_ID | --clear) [--dry-run] [--branch ID]
549
+ kbagent config rename --project NAME --component-id ID --config-id ID --name "New Name" [--branch ID] [--directory DIR]
550
+ kbagent config delete --project NAME --component-id ID --config-id ID [--branch ID] [--dry-run]
551
+ kbagent config restore --project NAME --component-id ID --config-id ID [--branch ID]
552
+ kbagent config trash-list --project NAME [--component-id ID] [--branch ID]
553
+ # config delete (0.89.0+ safety): SOFT delete into the Storage trash, with a locate-first guard.
554
+ # The raw API purges PERMANENTLY when DELETE hits a config already in the trash -- the classic
555
+ # agent retry after a timeout. kbagent now looks the config up first: live -> trash it;
556
+ # already trashed -> status "already_in_trash", exit 0, NO second DELETE ever sent; absent
557
+ # from both -> NOT_FOUND. Undo with `config restore`; browse candidates with `config
558
+ # trash-list`. Before 0.89.0 the second delete destroyed the config permanently. CLAUDE.md
559
+ # did not list `config delete` at all until 0.89.0 (silent drift) -- the command itself has
560
+ # existed for a long time.
561
+ 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]
562
+ kbagent config variables-get --project NAME --component-id ID --config-id ID [--branch ID]
563
+ kbagent config variables-clear --project NAME --component-id ID --config-id ID [--branch ID] [--yes]
564
+ kbagent config metadata-list --project NAME --component-id ID --config-id ID [--branch ID]
565
+ kbagent config get-metadata --project NAME --component-id ID --config-id ID --key KEY [--branch ID]
566
+ kbagent config set-metadata --project NAME --component-id ID --config-id ID --key KEY --value VALUE [--branch ID]
567
+ kbagent config delete-metadata --project NAME --component-id ID --config-id ID --metadata-id ID [--branch ID] [--yes]
568
+ kbagent config set-folder --project NAME --component-id ID --config-id ID --name FOLDER [--branch ID]
569
+ 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]
570
+ 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]
571
+ kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
572
+ kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL] [--no-open]
573
+ # oauth-url: opens the link in the default browser (interactive human mode only; never with
574
+ # --json, over SSH, in a container or in WSL without wslview); --no-open only prints it.
575
+ # Version gate in gotchas.md.
576
+ kbagent config state-get --project NAME --component-id ID --config-id ID [--row-id ID] [--branch ID]
577
+ kbagent config state-set --project NAME --component-id ID --config-id ID [--row-id ID] --state JSON|@file|- [--branch ID] [--dry-run] [--yes]
578
+ # state-get/state-set (0.84.2+, #593): read/write a config's runtime state via the dedicated
579
+ # PUT .../state endpoint -- closes the gap where `config update --set 'state...'` looked
580
+ # successful but silently wrote to configuration.state.* instead (runtime state untouched).
581
+ # Since 0.84.2, `config update --set` / `config row-update --set` REJECT (exit 2) any path
582
+ # whose first segment is a top-level API field (state, rows, name, description, id, version,
583
+ # currentVersion, changeDescription, created, creatorToken, isDeleted, isDisabled) -- use
584
+ # state-set / --name / --description / row-update --is-disabled instead, or --configuration
585
+ # for a genuine configuration.<prefix> key.
586
+ kbagent config clone --project P --component-id ID --config-id ID --name NAME [--target-project P2] [--description D] [--set PATH=VALUE ...] [--secret PATH=VALUE ...] [--branch ID] [--target-branch ID] [--dry-run] [--allow-plaintext-on-encrypt-failure]
587
+ # clone (0.84.2+, #587): duplicates a configuration WHOLE. Hand-rebuilding a body from `config
588
+ # detail` drops siblings of `parameters` (`runtime`, `storage`, `authorization`) silently -- a
589
+ # lost `runtime.parallelism` makes Keboola fall back to parallelism 1 (a 65-row writer then ran
590
+ # sequentially, 140 min instead of ~60-90, with nothing reported).
591
+ # SAME project (default): server-side copy (`POST .../configs/{id}/versions/{v}/create`) --
592
+ # rows AND `KBC::` values come along (verified live). `--set` edits are applied as a follow-up
593
+ # update on the copy, so an override can never be why a key went missing.
594
+ # CROSS project (`--target-project`): reassembled client-side, rows recreated one by one.
595
+ # Encrypted values CANNOT travel (ciphertext is project-scoped), so the clone is REFUSED,
596
+ # listing every path, until each is re-supplied via `--secret PATH=VALUE`; those are encrypted
597
+ # in the TARGET project on write. `--dry-run` reports the paths instead of refusing -- that is
598
+ # how you discover what to gather. Storage bucket/table IDs are copied VERBATIM, never remapped
599
+ # (`sync clone` is the command that remaps).
600
+
601
+ # --all-projects (CLI-36): on the 18 fan-out reads that read all projects without --project; until 1.0.0 the
602
+ # same as an omitted --project, with --project USAGE_ERROR (exit 2). --json envelopes gain an optional
603
+ # top-level `warnings` list ({code, message, ...}), not the same as `data.warnings`. Details and version
604
+ # gate in gotchas.md.
605
+ kbagent search QUERY [--project NAME | --all-projects] [--type table|bucket|config|flow|data-app|transformation] [--search-type textual|config-based] [--regex] [--scope PATH ...] [--limit N]
606
+ # --regex (0.67.0+): opt-in regex mode (mode=regex). Case-insensitive whole-term match on ENTITY NAMES
607
+ # only ('report' != 'monthly_report'; use '.*report.*'). Textual only -- error with --search-type
608
+ # config-based. Regex does NOT match column names, so matched_columns is always empty under --regex.
609
+ # In textual mode, table results matched via a column name carry matched_columns (JSON) / a
610
+ # "Matched columns" table column.
611
+ # BOTH modes match case-insensitively (config-based was case-sensitive until #569, which made
612
+ # "is this referenced anywhere" miss a table spelled DCFAmount in one config and DCFAMOUNT in
613
+ # another). `kbagent config search --query` stays case-sensitive by default (it has --ignore-case).
614
+
615
+ kbagent job list [--project NAME | --all-projects] [--component-id ID] [--config-id ID] [--status STATUS] [--limit N] [--offset N] [--sort-by startTime|endTime|createdTime|durationSeconds|id] [--sort-order asc|desc]
616
+ # job list (0.90.1+, #675): without --project the multi-project fan-out is merged GLOBALLY by
617
+ # --sort-by/--sort-order (default startTime desc), missing values last in both directions,
618
+ # deterministic (project_alias, id) tiebreak. Before 0.90.1 rows came back grouped alias-then-id,
619
+ # which destroyed the chronological order the fan-out exists to produce. Same change applies to
620
+ # `kbagent serve`'s GET /jobs. Anything relying on per-project blocks must group them itself.
621
+ kbagent job detail --project NAME --job-id ID [--log-tail-lines N]
622
+ kbagent job run --project NAME --component-id ID --config-id ID [--row-id ID ...] [--wait] [--timeout N] [--branch ID] [--mode run|debug] [--variable-values-id ID] [--no-variables] [--poll-strategy exponential|fixed] [--log-tail-lines N] [--idempotency-key KEY] [--force-rerun]
623
+ kbagent job terminate --project NAME (--job-id ID [--job-id ID ...] | --status any|created|waiting|processing [--component-id ID] [--config-id ID] [--branch ID] [--limit N]) [--dry-run] [--yes]
624
+ # job terminate --status --branch 0 (CLI-21): matches only jobs whose branchId is the default branch
625
+ # ID (read from GET /v2/storage/dev-branches). Before, it matched no job. Version gate in gotchas.md.
626
+ # job run --idempotency-key: a pending entry is recorded BEFORE the create. A definite failure (4xx,
627
+ # refused connection, connect timeout) removes it; an unknown outcome (read timeout, 5xx, exhausted
628
+ # retries) keeps it, because the job may exist. A replay that finds the pending entry exits 1 (INVALID_ARGUMENT, HTTP 400 over serve) and
629
+ # creates nothing; check `job list`, then `--force-rerun`. Version gate lives in gotchas.md.
630
+
631
+ kbagent storage buckets [--project NAME | --all-projects] [--branch ID]
632
+ kbagent storage bucket-detail --project NAME --bucket-id ID [--branch ID]
633
+ kbagent storage tables [--project NAME ... | --all-projects] [--bucket-id ID] [--branch ID] [--include-usage]
634
+ kbagent storage table-detail --project NAME --table-id ID [--branch ID]
635
+ # table-detail (0.88.0+, #621): also returns the raw Storage API `definition`. On BigQuery
636
+ # that object (timePartitioning / rangePartitioning / clustering / requirePartitionFilter /
637
+ # partitions[]) is the ONLY readable record of the registered layout, so it is how a
638
+ # `create-table --source-table-id ...` + `swap-tables` repartition is VERIFIED -- the table
639
+ # ID is unchanged either way, and `create-table` only echoes the layout you REQUESTED (its
640
+ # --if-not-exists skip path nulls the layout keys outright). Human mode adds Time
641
+ # partitioning / Range partitioning / Clustering / Partition filter required / Partitions
642
+ # (a COUNT) and prints nothing new when there is no layout. The human
643
+ # Columns table also carries a Description column (0.89.0+, #642; NOT on 0.88.0), populated from
644
+ # `column_details[].description` and shown only when some column has one -- the one
645
+ # surface #624 left blank, so `describe-column` then `table-detail` now verifies
646
+ # itself (long text wraps, never truncates). --json passes `definition`
647
+ # through verbatim, including the unbounded `partitions[]` (one entry per physical
648
+ # partition from INFORMATION_SCHEMA.PARTITIONS). `definition` is present on EVERY response
649
+ # -- untyped tables get one too -- so null means the stack omitted the key, NOT "untyped".
650
+ # `storage tables` (the LIST endpoint) is unaffected: the API has no `definition` include.
651
+ # table-detail also returns `backend_path` (the owning bucket's Storage backendPath, verbatim)
652
+ # and `sql_path` (quoted, directly queryable path; null when Storage reports no location) --
653
+ # see the semantic-layer dataset fqn note (#761); version gate in gotchas.md.
654
+ kbagent storage create-bucket --project NAME --stage STAGE --name NAME [--description D] [--backend B] [--branch ID]
655
+ 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]
656
+ # --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).
657
+ 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]
658
+ # upload-table / file-upload cloud upload (#834): on AWS stacks a file above 64 MiB goes up as an S3
659
+ # MULTIPART upload -- 64 MiB parts (auto-scaled so the file fits in 10,000 parts), 4 in parallel,
660
+ # per-part retry on 429/5xx/transport errors, peak memory ~4 x part size. Before, the whole file was
661
+ # read into RAM and sent as one PutObject (hard 5 GiB ceiling). Also covers the SDK
662
+ # Client.upload_table. Azure/GCP stacks unchanged (they already stream; chunked upload there is a
663
+ # follow-up in #834). Limits: S3 federation credentials last 12 h (200 GB needs ~5 MB/s sustained);
664
+ # the source file must not change during the upload (size/mtime checked); no resume across runs; an
665
+ # aborted multipart upload may leave orphaned parts (the token cannot abort). A .csv.gz is uploaded
666
+ # byte-for-byte and imported by Storage; auto-create reads its header through gzip. Human mode shows
667
+ # a progress bar on stderr. `serve`'s upload route streams the body to a temp file (needs temp disk
668
+ # of the file size) instead of holding it in memory.
669
+ # upload-table / load-file async import (#834): --wait (default) waits --timeout SECONDS (default 600)
670
+ # for the Storage import job; --no-wait still waits for the cloud upload, then enqueues the import and
671
+ # returns file_id / job_id / job_status (imported_rows null while pending; keys are additive). A wait
672
+ # timeout is STORAGE_JOB_TIMEOUT, exit 4, retryable=false: the import KEEPS RUNNING server-side, the
673
+ # error names job_id + file_id and `storage job-detail --job-id ID --wait`. Never re-run the upload
674
+ # while that job is waiting/processing -- an incremental re-run duplicates rows. An enqueue failure
675
+ # after the upload carries file_id -> `storage load-file --file-id` instead of re-uploading.
676
+ # Workflow: plugins/kbagent/skills/kbagent/references/large-upload-workflow.md. Version gate for this
677
+ # entry lives in gotchas.md.
678
+ kbagent storage download-table --project NAME --table-id ID [--output FILE] [--columns COL ...] [--limit N] [--where-column COL --where-value VAL ... [--where-operator eq|neq]] [--changed-since WHEN] [--changed-until WHEN] [--branch ID] [--progress]
679
+ # --progress on upload-table / file-upload / download-table / file-download / unload-table (with
680
+ # --download): ALWAYS report transfer progress on stderr -- also with --json and with no terminal.
681
+ # A terminal gets a Rich bar (percent, transferred/total, speed, elapsed, ETA); otherwise one plain line
682
+ # every 10 s plus a final line, e.g. `upload big.csv: 42.0% 4.20/10.00 GiB, 67.30 MiB/s, elapsed
683
+ # 0:01:03, ETA 0:01:27` (last line: `avg` speed + `done`/`failed`). stdout (the JSON envelope) is
684
+ # untouched. Speed/ETA use a trailing 30 s window; downloads count network (compressed) bytes and start
685
+ # the clock when the download starts, not during the export job; a sliced download with no sizes in
686
+ # its manifest shows bytes + speed only. Without the flag nothing changes: a transient bar only in
687
+ # human mode on a terminal. Terminal-only: no serve / SDK surface. Version gate in gotchas.md.
688
+ kbagent storage add-column --project NAME --table-id ID --column COL:TYPE[(length)] [--not-null] [--default VALUE] [--branch ID]
689
+ kbagent storage delete-table --project NAME --table-id ID [--table-id ...] [--force] [--dry-run] [--yes] [--branch ID]
690
+ kbagent storage truncate-table --project NAME --table-id ID [--table-id ...] [--dry-run] [--yes] [--branch ID]
691
+ kbagent storage delete-column --project NAME --table-id ID --column COL [--column ...] [--force] [--dry-run] [--yes] [--branch ID]
692
+ kbagent storage delete-bucket --project NAME --bucket-id ID [--bucket-id ...] [--force] [--dry-run] [--yes] [--branch ID]
693
+ # delete-bucket / file-delete (CLI-30): both read --yes. Without it they ask on a terminal (stdin and
694
+ # stderr are a terminal, --json off). --json, --dry-run and a session without a terminal never ask.
695
+ # A declined prompt exits 0 and deletes nothing. delete-bucket --force cascade-deletes tables only:
696
+ # a shared bucket (`sharing` set in the bucket detail) is never deleted, also not with --force or
697
+ # over REST (DELETE /storage/buckets/{project}?force=true). It gets a failed[] entry that names
698
+ # `kbagent sharing unshare --project ALIAS --bucket-id ID`, the other buckets are still processed,
699
+ # and the run exits 1. Version gate lives in gotchas.md.
700
+ kbagent storage swap-tables --project NAME --table-id ID --target-table-id ID --branch ID [--dry-run] [--yes] [--timeout SECONDS]
701
+ # --timeout SECONDS on create-table and swap-tables (since 0.99.0, #713): both halves
702
+ # of the repartition path move real data yet used to inherit the 60s metadata-job
703
+ # budget, so a large BigQuery table reported STORAGE_JOB_TIMEOUT for a job that was
704
+ # still running and would succeed. Default is now 300s on both. A local timeout
705
+ # NEVER cancels the job -- it keeps running server-side. The error is
706
+ # STORAGE_JOB_TIMEOUT, exit 4, retryable=false, details.job_id, and the message
707
+ # names `storage job-detail --job-id ID --wait` (create-table also names
708
+ # `storage table-detail`). Never re-run: a repeated swap swaps the tables back,
709
+ # a repeated --source-table-id create starts a second copy.
710
+ kbagent storage clone-table --project NAME --table-id ID --branch ID [--dry-run]
711
+ # --branch 0 / --source-branch-id 0 (CLI-21): swap-tables --branch 0 swaps on the default branch ID it
712
+ # reads first (was: exit 5 "requires a branch"); clone-table --branch 0 is INVALID_ARGUMENT, exit 2, no
713
+ # API call (HTTP 400 over serve; the target must be a dev branch); create-table --source-branch-id 0
714
+ # omits source.branchId in a production request and sends the default branch ID in a dev-branch
715
+ # request (was: source.branchId 0). Version gate in gotchas.md.
716
+ kbagent storage snapshot-create --project NAME --table-id ID [--description D] [--branch ID]
717
+ kbagent storage snapshots --project NAME --table-id ID [--limit N] [--branch ID]
718
+ kbagent storage snapshot-detail --project NAME --snapshot-id ID
719
+ kbagent storage snapshot-delete --project NAME --snapshot-id ID [--snapshot-id ...] [--dry-run] [--yes]
720
+ kbagent storage table-from-snapshot --project NAME --snapshot-id ID --bucket-id ID --name NAME [--branch ID] [--dry-run]
721
+ # Snapshots (0.75.0+, #512): point-in-time table backup (data+columns+PK) and restore as a NEW table.
722
+ # table-from-snapshot goes through the classic tables-async endpoint (NOT tables-definition), --name is
723
+ # REQUIRED (API rejects empty), no overwrite -- restore under a new name, then swap/delete yourself.
724
+ kbagent storage describe-bucket --project NAME --bucket-id ID [--text STR | --file PATH | --stdin] [--branch ID]
725
+ kbagent storage describe-table --project NAME --table-id ID [--text STR | --file PATH | --stdin] [--branch ID]
726
+ kbagent storage describe-column --project NAME --table-id ID --column NAME=DESC [--column ...] [--branch ID]
727
+ kbagent storage describe-batch --project NAME --from-file YAML [--branch ID]
728
+ kbagent storage describe-migrate --project ALIAS [--table-id ID ...] [--bucket-id ID] [--prune-orphans] [--dry-run] [--yes] [--branch ID]
729
+ # Column descriptions (0.88.0+, #624): describe-column/describe-batch write through the native
730
+ # `PUT .../tables/{id}/definition` endpoint (async job) with `isDescriptionSystemManaged: false`
731
+ # (stops the next Output Mapping run from overwriting the text). The backend mirrors the value into
732
+ # `columnMetadata` `KBC.description`, so the UI, the MCP server and the Snowflake COMMENT /
733
+ # BigQuery description all see it. Before 0.88.0 kbagent wrote a flat `KBC.column.{name}.description`
734
+ # key on the TABLE's metadata -- read by nothing but kbagent, so documented columns looked blank
735
+ # everywhere else. Unknown column names now FAIL FAST before any write (behavior change; the flat
736
+ # write accepted typos silently). `table-detail` reads with precedence native definition ->
737
+ # columnMetadata KBC.description -> legacy flat key, always returns `legacy_column_descriptions`
738
+ # and warns in human mode when legacy keys remain; it never writes. `describe-migrate` converts
739
+ # legacy keys in bulk (scope: --table-id / --bucket-id / whole project; scan-then-confirm,
740
+ # --dry-run reports only; per-table errors accumulate). describe-column/describe-batch also migrate
741
+ # leftovers on the table they touch. Rules: a column whose visible description already differs is
742
+ # skipped as `conflict` (newer value wins), an entry for a dropped column is skipped as `orphan`
743
+ # unless --prune-orphans. Migrated flat entries are DELETED so a later clear cannot be resurrected
744
+ # by the read fallback.
745
+ # describe-batch --from-file shape check (0.89.0+, #645, issue #640): the WHOLE file is validated
746
+ # before the first write. A tables:/buckets:/columns: section given as a list instead of a mapping
747
+ # of ID to description, a column entry that is not a mapping, a null description, a non-mapping
748
+ # document, or two keys colliding after str() coercion (1 vs "1") -> structured INVALID_ARGUMENT,
749
+ # exit 2, naming the key and its actual type; nothing is half-applied. Behavior change: before
750
+ # 0.89.0 the same input raised an AttributeError traceback PARTWAY THROUGH the batch. Empty
751
+ # sections (absent, null, [], '', {}) stay silent no-ops; per-item API failures during
752
+ # application are still accumulated into errors[] (exit 1) -- shape is a usage error, an API
753
+ # refusal is not.
754
+ kbagent storage files --project NAME [--tag TAG ...] [--limit N] [--offset N] [--query Q] [--branch ID]
755
+ kbagent storage file-upload --project NAME --file PATH [--name NAME] [--tag TAG ...] [--permanent] [--branch ID] [--progress]
756
+ kbagent storage file-download --project NAME [--file-id ID | --tag TAG ...] [--output FILE] [--progress]
757
+ kbagent storage file-detail --project NAME --file-id ID
758
+ kbagent storage file-delete --project NAME --file-id ID [--file-id ...] [--dry-run] [--yes]
759
+ kbagent storage file-tag --project NAME --file-id ID [--add TAG ...] [--remove TAG ...]
760
+ kbagent storage load-file --project NAME --file-id ID --table-id ID [--incremental] [--delimiter D] [--enclosure E] [--wait/--no-wait] [--timeout SECONDS] [--branch ID]
761
+ kbagent storage job-detail --project NAME --job-id ID [--wait] [--timeout SECONDS]
762
+ # storage job-detail (#834): read-class; shows a Storage API job (status, operation_name, table_id,
763
+ # file_id, times, imported_rows, warnings, results, error). Exit 0 success/waiting/processing, exit 1
764
+ # STORAGE_JOB_FAILED when the job ended in error (details still returned), exit 4 on --wait timeout.
765
+ # Job ids are project-scoped, independent of the active branch (no --branch). Serve:
766
+ # GET /storage/jobs/{project}/{job_id}?wait=&timeout=. Version gate for this entry lives in gotchas.md.
767
+ kbagent storage unload-table --project NAME --table-id ID [--columns COL ...] [--limit N] [--tag TAG ...] [--download] [--output FILE|DIR] [--file-type csv|parquet] [--branch ID] [--progress]
768
+
769
+ # stream: Data Streams (OpenTelemetry/OTLP). Storage token from config (no manage token).
770
+ # Control plane = stream.<region> (derived from connection.<region>); the OTLP ingest URL
771
+ # (stream-in.<region>/otlp/<projectId>/<sourceName>/<secret>) is returned in source.otlp.url
772
+ # with the secret in the path -- MASKED by default, --reveal to print it. create-source --type otlp
773
+ # auto-provisions the logs/metrics/traces sinks (bucket in.c-otlp-<source>) so data lands; --no-sinks opts out.
774
+ kbagent stream list --project NAME [--branch ID]
775
+ kbagent stream create-source --project NAME --name NAME [--type otlp|http] [--branch ID] [--if-not-exists] [--no-sinks] [--reveal]
776
+ kbagent stream detail [SOURCE_ID | --name NAME] --project NAME [--branch ID] [--reveal]
777
+ kbagent stream delete SOURCE_ID --project NAME [--branch ID] [--dry-run] [--yes|--force]
778
+
779
+ kbagent lineage build --directory PATH --output PATH [--ai] [--refresh]
780
+ kbagent lineage show --load PATH [--upstream NODE] [--downstream NODE] [--column COL] [--columns] [--project ALIAS] [--depth N] [--format text|mermaid|html|er]
781
+ kbagent lineage info --load PATH
782
+ kbagent lineage server --load PATH [--port N] [--host HOST]
783
+
784
+ kbagent sharing list [--project NAME | --all-projects]
785
+ kbagent sharing share --project ALIAS --bucket-id ID --type TYPE [--target-project-ids IDs] [--target-users EMAILS]
786
+ kbagent sharing unshare --project ALIAS --bucket-id ID
787
+ kbagent sharing link --project ALIAS --source-project-id ID --bucket-id ID [--name NAME] [--stage in|out]
788
+ kbagent sharing unlink --project ALIAS --bucket-id ID
789
+ kbagent sharing edges [--project NAME | --all-projects]
790
+
791
+ kbagent org setup --org-id ID --url URL [--dry-run] [--yes] [--token-description PREFIX] [--refresh]
792
+ kbagent org setup --project-ids 1,2,3 --url URL [--dry-run] [--yes] [--token-description PREFIX] [--refresh]
793
+
794
+ kbagent billing credits [--project ALIAS ... | --all-projects]
795
+ # billing credits (0.84.2+, issue #594 secondary ask): read-only PAYG credit balance, fanned out
796
+ # across all registered projects in parallel by default (--project repeatable narrows). A project
797
+ # without the `pay-as-you-go` owner.features flag never touches the billing host (NXDOMAIN on some
798
+ # non-PAYG stacks) -- it gets a per-project error_code PAYG_NOT_AVAILABLE instead; per-project
799
+ # failures degrade individually, the run never aborts. Rows report the API's native unit (credits)
800
+ # AND derived minutes (1 credit = 60 min, matching the Keboola UI). Purchase history / Stripe
801
+ # invoice IDs are NOT available here -- that data lives on connection.{stack}
802
+ # /pay-as-you-go/billing/*, which does not accept a Storage token (issue #594 primary ask, open).
803
+
804
+ # feature: requires a super-admin Manage API token (inline hidden prompt; never persisted; --allow-env-manage-token for CI). --project resolves the stack URL (+ project_id for project ops) from config.
805
+ kbagent feature list --project ALIAS
806
+ kbagent feature project-show --project ALIAS
807
+ kbagent feature project-add --project ALIAS --feature NAME [--dry-run] [--yes]
808
+ kbagent feature project-remove --project ALIAS --feature NAME [--dry-run] [--yes]
809
+ kbagent feature user-show --project ALIAS --email EMAIL
810
+ kbagent feature user-add --project ALIAS --email EMAIL --feature NAME [--dry-run] [--yes]
811
+ kbagent feature user-remove --project ALIAS --email EMAIL --feature NAME [--dry-run] [--yes]
812
+
813
+ # token: scoped Storage tokens (Keboola single-bucket-write pattern; secret shown once).
814
+ # create REQUIRES a MASTER (admin) token -- pre-flight MISSING_MASTER_TOKEN guard (exit 3)
815
+ # since #599: a non-master token with canManageTokens is CreateTokenVoter's "impossible state"
816
+ # and the API answers a generic 500. That defect is CREATE-ONLY: list/delete/refresh need only
817
+ # canManageTokens and are deliberately NOT guarded (RefreshTokenVoter also lets any token
818
+ # rotate itself), so rotating a leaked device token from an org-setup token keeps working.
819
+ kbagent token list --project NAME [--with-last-used] [--columns NAME ...]
820
+ kbagent token create --project NAME --description DESC [--bucket-write BUCKET ...] [--bucket-read BUCKET ...] [--component-access ID ...] [--can-read-all-file-uploads] [--expires-in N]
821
+ kbagent token delete --project NAME --token-id ID [--yes]
822
+ kbagent token refresh --project NAME --token-id ID [--yes]
823
+ # `token list` (issue #599): GET /v2/storage/tokens -- the only way to see what already exists and to
824
+ # get the id `delete`/`refresh` need, without the web UI. Secrets are STRIPPED from every row: a
825
+ # project with the `force-decrypted-token` feature has the API embed live values in the listing, and
826
+ # echoing those would break the group's "revealed once, at mint" contract for every token at once.
827
+ # `--with-last-used` (0.88.0+, issue #622): answers which tokens are still IN USE -- the Storage API
828
+ # carries no `lastUsed` (only the Manage API's PAT response does), so it is DERIVED per token from
829
+ # GET /v2/storage/tokens/{id}/events, fanned out over max_parallel_workers. Opt-in: ONE EXTRA CALL
830
+ # PER TOKEN. Adds lastUsed / lastUsedEvent / lastUsedStatus + a top-level `errors`; the default
831
+ # shape is unchanged. Sorts dormant-first (reading order = cleanup order).
832
+ # The feed is narrowed SERVER-SIDE to `q=token.id:{id}` -- events the token PERFORMED. The raw feed
833
+ # also carries events performed ON the token, so a fresh token's newest raw event is its own
834
+ # storage.tokenCreated: `events[0]` reports never-used as "used today", exactly backwards. Filtering
835
+ # client-side instead breaks differently -- right after a rotation the one event a limit=1 fetch
836
+ # returns is that rotation, so the filter is left with nothing and calls an active token unused.
837
+ # lastUsedStatus separates `never` (minted INSIDE the ~6-month retention window, no activity =>
838
+ # proven) from `unknown` (older than retention => the API cannot say) from `error` (per-token lookup
839
+ # failed; row degrades, audit completes). Do not collapse never/unknown -- they lead to opposite
840
+ # decisions. DEV-BRANCH ACTIVITY IS INVISIBLE (the endpoint always resolves to the default branch:
841
+ # `idBranch == <production> OR NOT EXISTS idBranch`), so a branch-only token reads as dormant.
842
+ # `--columns` (0.88.0+, repeatable): selects/orders the human table; `Refreshed` is now a default
843
+ # column (--json always returned it). --json is deliberately NOT affected by --columns.
844
+ # `last_used` / `last_used_event` REQUIRE --with-last-used (exit 2 otherwise): nothing was
845
+ # derived, so any rendered value would assert something never checked.
846
+ # SDK (importable Client(url,token)) now exposes create_scoped_token / list_tokens / delete_token /
847
+ # refresh_token / create_stream_source / get_stream_source / list_stream_sources /
848
+ # delete_stream_source: dicts on .raw, typed ScopedTokenResult / TokenListEntryResult /
849
+ # StreamSourceResult on the facade. See docs/sdk.md.
850
+
851
+ # permissions: session write/destructive firewall. The top-level --deny-writes / --deny-destructive
852
+ # flags are the one-shot form; `permissions set` persists a policy (mode allow|deny + allow/deny patterns
853
+ # like cli:read, cli:write, cli:destructive). `tool:*` patterns are INERT since 0.85.0 (the MCP
854
+ # passthrough is gone): they load but match nothing, so a mode=deny policy whose only allowance was
855
+ # tool:read now denies everything. The agent guards rails against mistakes; not a sandbox.
856
+ # `permissions set` (since 0.91.0, issue #688) validates every --allow/--deny pattern BEFORE the
857
+ # interactive confirmation: each must be a cli:* category, an exact operation name (incl. a
858
+ # flag-escalated string like "auth.logout --remove-projects"), or a glob matching >=1 known
859
+ # operation -- an unknown pattern (typo, fabricated category) is rejected with VALIDATION_ERROR,
860
+ # exit 2, listing every offending pattern (--json: error.details.invalid_patterns), and nothing
861
+ # is persisted. `permissions show` / `kbagent doctor` also generalized: they now flag ANY
862
+ # persisted pattern matching zero known operations, not only the retired tool:* namespace.
863
+ # PermissionEngine itself stays lenient at evaluation time -- only `permissions set` is strict.
864
+ # (since 0.99.0, #655) The policy also firewalls the WHOLE `kbagent serve` REST surface: every
865
+ # route is classified in server/route_permissions.py and checked by one app-level dependency
866
+ # against the SERVED config dir's policy -> HTTP 403 error_code PERMISSION_DENIED, the same
867
+ # code the CLI exits on. On 0.98.0 and older only /auth/* (0.90.1+) and /merge-requests/*
868
+ # (0.94.0+) were checked and every other route executed unchecked. Routes that declare their
869
+ # own `require_permission(...)` (those two routers) are skipped by the table. An unclassified
870
+ # route is REFUSED, not exempted (a test keeps the table
871
+ # and the live app in sync both ways); bootstrap paths (/health/ping, /health/auth-info,
872
+ # /ui-config, /docs, /redoc, /openapi.json, SPA shell) are never checked. A path param
873
+ # that collapses CLI leaves is checked like the CLI: POST/PUT/DELETE
874
+ # /semantic-layer/items/{kind}[/{name}] check the parent key (`semantic-layer.add`) AND
875
+ # the leaf `semantic-layer.add.<kind>` (route_permissions.LEAF_PATH_PARAMS).
876
+ # A `--scope organization` semantic-layer write is destructive-class over REST too:
877
+ # the handlers of scope PUT, models, items/{kind} (per-kind leaf key), import, promote
878
+ # and build check `<key> --scope organization` (FLAG_ESCALATIONS) for a typed OR an
879
+ # inherited organization scope, like the CLI.
880
+ # `config variables-set --replace` is destructive-class (FLAG_ESCALATIONS); the CLI and
881
+ # PUT /configs/.../variables with `replace: true` both check it. `token refresh` and
882
+ # `workspace password` are destructive-class (the old secret stops working).
883
+ # `http get/post/patch/delete` (group callback, key `http.<verb>`) and `search` (top-level
884
+ # guarded set in cli.py) check the caller's own policy and --deny-* flags before any
885
+ # request. Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines).
886
+ # `GET /permissions/show` (serve, since 0.99.0) reports the EFFECTIVE policy (persisted block
887
+ # merged with the daemon's --deny-* flags); read-only by design -- no REST route can widen
888
+ # the policy that constrains it, so `permissions set|reset` stay terminal actions on the host.
889
+ kbagent permissions list [--category read|write|destructive|admin]
890
+ kbagent permissions show
891
+ kbagent permissions set --mode allow|deny [--allow PATTERN ...] [--deny PATTERN ...]
892
+ kbagent permissions reset
893
+ kbagent permissions check OPERATION
894
+
895
+ # The `tool` group is GONE (removed in 0.85.0, epic #390 phase 3) -- so are `agent --type
896
+ # mcp_tool` and the `/mcp/*` serve routes. Every catalog tool has a native command; the
897
+ # historical tool-to-command map is docs/mcp-migration.md. Persisted `mcp_tool` agent tasks
898
+ # are kept as inert tombstones (never run, flagged by `agent list`, FAIL in `doctor`) --
899
+ # recreate them as `--type cli_command`.
900
+
901
+ kbagent branch list [--project NAME | --all-projects]
902
+ kbagent branch create --project ALIAS --name "..." [--description "..."]
903
+ kbagent branch use --project ALIAS --branch ID
904
+ # branch use: every command that then picks a branch names it -- `Target:` on stderr, `targets` in
905
+ # --json (branch_source explicit|active_branch|git_mapping|manifest|merge_request|production). Version gate in gotchas.md (#766).
906
+ kbagent branch reset --project ALIAS
907
+ kbagent branch delete --project ALIAS --branch ID
908
+ kbagent branch merge --project ALIAS [--branch ID]
909
+ kbagent branch metadata-list --project NAME [--branch ID|default]
910
+ kbagent branch metadata-get --project NAME --key KEY [--branch ID|default]
911
+ kbagent branch metadata-set --project NAME --key KEY [--text STR | --file PATH | --stdin] [--branch ID|default]
912
+ kbagent branch metadata-delete --project NAME --metadata-id ID [--branch ID|default]
913
+ # branch merge is DEPRECATED (since 0.94.0): it only builds a UI URL and resets the active branch. On a
914
+ # project with `branches-merge-requests` use the merge-request group below; the command keeps working
915
+ # (it also serves projects without the feature) and now carries `deprecation` in --json.
916
+
917
+ # merge-request (since 0.94.0, DMD-1900): the non-SOX Branches 2.0 lifecycle. Hidden alias `mr`. Every
918
+ # command except list/create takes `[--merge-request-id N | --id N] [--branch B]`: omitted, the target is
919
+ # the merge request OF the active branch (`branch use`) -- a branch has at most one MR, ever. Both flags at
920
+ # once -> exit 2. `--project` is single-project (never fans out). Status is the DERIVED state the web UI
921
+ # shows (in_development|in_review|approved|in_merge|merged|closed|rejected), never the raw one.
922
+ kbagent merge-request list [--project A] [--state STATE] # derived (in_development|in_review|approved|in_merge|merged|closed|rejected) or raw (development|published|canceled) states; `--help` lists them
923
+ kbagent merge-request detail [--project A] [--merge-request-id N | --branch B] [--activity-log]
924
+ kbagent merge-request create --title T [--project A] [--branch B] [--description D] [--reviewer-id ID ...] [--external-id X]
925
+ kbagent merge-request update [--project A] [--merge-request-id N | --branch B] [--title T] [--description D] [--reviewer-id ID ...] [--external-id X]
926
+ kbagent merge-request request-review [--project A] [--merge-request-id N | --branch B]
927
+ kbagent merge-request approve [--project A] [--merge-request-id N | --branch B]
928
+ kbagent merge-request request-changes [--project A] [--merge-request-id N | --branch B] [--reason TEXT]
929
+ kbagent merge-request auto-merge --strategy immediately|scheduled|none [--at TS] [--project A] [--merge-request-id N | --branch B] [--yes]
930
+ kbagent merge-request merge [--project A] [--merge-request-id N | --branch B] [--yes]
931
+ kbagent merge-request conflicts [--project A] [--merge-request-id N | --branch B]
932
+ kbagent merge-request diff --component-id C --config-id I [--project A] [--merge-request-id N | --branch B] [--format short|full] [--output PATH]
933
+ kbagent merge-request resolve --component-id C --config-id I (--take ours|theirs|delete | --resolved JSON|@file|-) [--project A] [--merge-request-id N | --branch B] [--change-description TEXT]
934
+ # WHAT IS DESTRUCTIVE -- a property of the COMMAND, never of a flag or of the MR's state, so a policy is
935
+ # evaluated from the command name alone, before any network call. Destructive = anything that moves a
936
+ # merge request toward or into production: `merge` (deletes the source branch, rewrites production),
937
+ # `request-review` (on the non-SOX default of 0 approvals it lands the MR directly in `approved`),
938
+ # `approve` (the last approval is what a merge waits for), `resolve` (removes the blocker a merge waits
939
+ # on) and `auto-merge` (arms a backend scheduler that runs every `approved` MR whose strategy is
940
+ # immediately/scheduled through the same MergeProcessor, on its own, retrying every tick -- a DELAYED
941
+ # PRODUCTION MERGE with `merge` never called; `--strategy none` disarms and rides the same command, same
942
+ # class). Write = shapes the MR without moving it: `create`, `update` (title/description/reviewers/
943
+ # external id -- auto-merge is NOT a field here), `request-changes` (moves it AWAY from approved).
944
+ # So `--deny-destructive` yields an agent that can observe and shape merge requests but never move one.
945
+ # Under --json every destructive command REQUIRES an explicit target (--merge-request-id or --branch),
946
+ # checked before anything is resolved: every destructive kbagent command either prompts or is told its
947
+ # target, and --json has no prompt. In human mode the active-branch fallback stays; `merge` and arming
948
+ # `auto-merge` prompt (--yes skips), the other destructive commands do not. After request-review/
949
+ # approve/resolve on an MR that IS armed, human mode warns that the backend will now merge (read off the
950
+ # write's own result, no extra GET).
951
+ # On a non-SOX project with the default 0 required approvals: `merge` works straight from `development`;
952
+ # `request-review` lands directly in `approved` (in_review is unreachable); `approve` answers 422 in every
953
+ # state. There is NO `close`: `request-changes` by the creator is the UI's cancel and leaves the MR in
954
+ # `development` (the `closed`/`rejected` derivations depend on reviewer status a 0-approval project never
955
+ # populates -- same blind spot as the web UI, DMD-1988). Requesting review with no reviewers selected
956
+ # emails EVERY project member.
957
+ # Conflicts: `conflicts` lists what changed on both sides (isDeleted = the DEV side's flag); `diff`
958
+ # classifies per path (both / only you / only production) and, when a side deleted the config wholesale,
959
+ # recommends the --take; `diff --output FILE` writes `resolution_candidate` (your branch's content, all
960
+ # five keys: name/description/isDisabled/configuration/rows -- rebase REPLACES, a missing key wipes data,
961
+ # the service refuses a partial body) to edit and hand back via `resolve --resolved @FILE`. No `--all`.
962
+ # Errors: a project without the feature answers FEATURE_NOT_ENABLED (exit 5) from every command whose
963
+ # target was resolved implicitly, reads included -- two wordings, missing feature vs SOX project. A
964
+ # scoped Storage token 403s (ACCESS_DENIED) on everything but `list`. `MR_MERGE_CONFLICT` /
965
+ # `MR_NOT_READY_TO_MERGE` (exit 1; the latter retryable) come from the merge 409. After
966
+ # MR_NOT_READY_TO_MERGE, `merge` reads the MR: state `published` (an earlier call merged it) answers
967
+ # status "already_merged", exit 0. The four state-change PUTs are never repeated by the HTTP layer.
968
+ # Version gate lives in gotchas.md. A truncated conflict
969
+ # list in the error carries `details.api_error_params_truncated: true` -- run `conflicts` for the full set.
970
+ # `merge` blocks for up to 10 minutes (no --wait/--timeout). Every result may carry `warnings[]`
971
+ # (post-merge cleanup failures, a dropped --change-description on a delete resolution). A merge whose
972
+ # source branch id could not be read carries `cleanup_skipped: true` + `branch_from_id_raw` (the local
973
+ # active-branch reset / sync unlink did NOT run -- key on the flag, not on warning text). On a project
974
+ # where the feature was later switched OFF, `list` rows' `allowed_actions` still recommend writes that
975
+ # will fail FEATURE_NOT_ENABLED (state-derived, feature-blind); `detail` carries `feature_enabled` and
976
+ # its hint-next respects it.
977
+
978
+ kbagent workspace create --project ALIAS [--name NAME] [--backend TYPE] [--ui] [--read-only/--no-read-only]
979
+ # workspace create (#755): a failed create -- headless or --ui -- moves the keboola.sandboxes
980
+ # config it created to the trash and says so (--json error.details: sandbox_config_id,
981
+ # sandbox_config_rolled_back, branch_id, job_id for --ui) -- except when the outcome is
982
+ # unknown, where the config is kept (sandbox_config_kept_reason: outcome_unknown): a 5xx, a
983
+ # read/write TIMEOUT or RETRY_EXHAUSTED on the create POST, or any error after the --ui job was
984
+ # queued other than QUEUE_JOB_FAILED / WORKSPACE_NOT_FOUND; the --ui job is queued on the branch
985
+ # the config lives in (was: default branch -> Queue 400 on a pinned dev branch). --ui itself
986
+ # still ends in WORKSPACE_NOT_FOUND on current SaaS stacks: the keboola.sandboxes `create` task
987
+ # dropped Snowflake/BigQuery provisioning in 2026-03 (the UI uses SQL Editor sessions), so the
988
+ # green job attaches no Storage workspace. Not a race -- do not retry; use headless. Version
989
+ # gate for this entry lives in gotchas.md (these `# ` lines parse as ATX headings).
990
+ kbagent workspace list [--project NAME ... | --all-projects] [--orphaned] [--branch ID] [--qs-compatible]
991
+ kbagent workspace detail --project ALIAS --workspace-id ID [--branch ID]
992
+ kbagent workspace delete --project ALIAS --workspace-id ID
993
+ kbagent workspace password --project ALIAS --workspace-id ID
994
+ kbagent workspace load --project ALIAS --workspace-id ID --tables TABLE_ID [--tables ...] [--preserve] [--load-type clone|copy|view] [--force] [--timeout SECONDS]
995
+ # workspace load (since 0.91.0, #687): DEFAULT is now per-table AUTO-DECIDE, mirroring the
996
+ # server's LoadTypeDecider -- zero-copy CLONE when eligible (same backend as the workspace,
997
+ # backend snowflake/bigquery, full load -- kbagent never sends filters here, no
998
+ # external-schema bucket, alias only when column-auto-sync is ON and unfiltered, and on
999
+ # BigQuery not an Analytics-Hub-linked bucket), otherwise plain COPY with a per-table
1000
+ # `clone_ineligible_reason` in the JSON. Before this, kbagent always sent a bare COPY (the
1001
+ # API's own default when loadType is omitted) -- a 282 GB table load burned warehouse credits
1002
+ # for hours where CLONE is metadata-only and finishes in seconds.
1003
+ # --load-type clone|copy|view FORCES the type for every table; an ineligible explicit choice
1004
+ # fails loudly with the server's HTTP 400 message -- it never silently degrades to COPY.
1005
+ # `view` is a zero-storage read-only view (BigQuery: any same-backend bucket; Snowflake: only
1006
+ # external-schema buckets + the project feature `input-mapping-read-only-storage`).
1007
+ # Size guard: a table resolved/forced to COPY whose dataSizeBytes exceeds 1 GiB requires
1008
+ # interactive confirmation (TTY human mode) or --force (JSON/non-interactive) -- a huge copy
1009
+ # never starts silently. --timeout SECONDS (default 300 here; other storage-job commands keep
1010
+ # 60): on timeout the error now says the job CONTINUES RUNNING server-side and keeps consuming
1011
+ # resources, names the job id, and how to poll it (GET /v2/storage/jobs/{id});
1012
+ # STORAGE_JOB_TIMEOUT now maps to exit code 4 (network/retryable) instead of 1. JSON result
1013
+ # gains per-table `load_type` / `data_size_bytes` / `clone_ineligible_reason` plus a top-level
1014
+ # `load_type_requested` (`auto` when the flag was omitted); existing keys are unchanged.
1015
+ # Cheap alternative for analytics-only access: with the read-only input-mapping feature, a
1016
+ # workspace can query production data directly via the `KBC_<STACK>_<PROJECT>` shared
1017
+ # database (zero load, zero storage) -- `workspace query` works on it, no load needed.
1018
+ kbagent workspace query --project ALIAS --workspace-id ID --sql "SELECT ..." [--transactional] [--full] [--limit N]
1019
+ kbagent workspace query --project ALIAS --workspace-id ID --file query.sql
1020
+ # query: default reads results inline via Query Service `GET .../results` (fast, JSON columns+rows),
1021
+ # capped at --limit rows (default 500); pass --full for the complete CSV export (slower, uncapped).
1022
+ # Each statement carries structured columns+rows + a synthesized csv_data (back-compat) since 0.59.0.
1023
+ kbagent workspace gc (--project NAME ... | --all-projects) [--dry-run] [--yes]
1024
+ # gc (CLI-28): needs --project or --all-projects (neither or both = USAGE_ERROR, exit 2), also over
1025
+ # REST (`project=` or `all_projects=true`, else HTTP 400 INVALID_ARGUMENT). A project whose sandbox
1026
+ # configs cannot be listed goes to errors[] and nothing is deleted there. A NOT_FOUND listing counts as
1027
+ # "no sandbox configs" only when the branch component listing confirms it. Version gate lives in gotchas.md.
1028
+ kbagent workspace from-transformation --project ALIAS --component-id ID --config-id ID [--row-id ID]
1029
+
1030
+ kbagent data-app list [--project NAME ... | --all-projects] [--branch ID]
1031
+ kbagent data-app detail --project NAME --app-id ID [--branch ID]
1032
+ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL | --use-managed-git-repo) [--description STR | --description-file PATH] [--git-branch main] [--git-public/--no-git-public] [--git-username USER] [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...] [--auth password|public] [--size tiny|small|medium|large] [--auto-suspend SECONDS] [--type python-js|python|streamlit|r|...] [--workspace/--no-workspace] [--branch ID] [--no-deploy] [--wait] [--timeout SECONDS] [--keep-on-failure] [--dry-run] [--copy] [--reveal]
1033
+ # --workspace / --no-workspace (0.87.0+): DEFAULT ON. Writes runtime.workspace.enabled=true --
1034
+ # the ONLY switch that makes the platform provision the ephemeral workspace and inject WORKSPACE_ID,
1035
+ # QUERY_SERVICE_URL and KBC_WORKSPACE_MANIFEST_PATH. Every app that reads Storage needs it. Before
1036
+ # 0.87.0 kbagent never wrote it and offered no way to: such an app deploys, reports state=running and
1037
+ # passes its health probe while being unable to read a row, and the PLATFORM reports nothing -- verify
1038
+ # via `config detail` -> `configuration.runtime`, not by grepping `data-app logs` (a `Missing env vars:
1039
+ # WORKSPACE_ID` line is the app's own output, so its absence rules nothing out; an app that does not
1040
+ # check crash-loops behind the probe instead). It defaults ON because the opposite mistake -- an
1041
+ # unused workspace on an app that never reads Storage -- is the cheap one; pass --no-workspace there.
1042
+ # Omitting the flag writes NO `enabled: false` key: the body is byte-identical to pre-0.87.0.
1043
+ # Not gated on any project feature -- the config option is the sole control. Retrofit an existing app:
1044
+ # `config update --merge --set 'runtime.workspace.enabled=true'` then `data-app deploy` (pins latest).
1045
+ # Exactly one git source is required: --git-repo URL (external) OR --use-managed-git-repo (0.65.0+).
1046
+ # --use-managed-git-repo provisions an EMPTY Keboola-hosted repo (POST useManagedGitRepo:true), writes
1047
+ # NO parameters.dataApp.git block, and forces --no-deploy (nothing to run yet). Mutually exclusive with
1048
+ # --git-repo and all --git-*/PAT auth flags. Full flow to a RUNNING managed-repo app (0.65.0+):
1049
+ # (1) create --use-managed-git-repo -> (2) `git-credentials-create --type http_token --permissions
1050
+ # readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app deploy`.
1051
+ # The platform injects the clone credentials at deploy time, so no credential wiring is needed.
1052
+ # deploy pins the LATEST configVersion. For a PURE managed repo (no git block yet), it first
1053
+ # backfills parameters.dataApp.git from the managed repo's URL, then pins the resulting version
1054
+ # (CLI-15) -- omitting configVersion alone does NOT provision the app's workspace;
1055
+ # grant provisioning is gated on that block's presence, not on configVersion. The deploy result
1056
+ # reports it (`git_backfilled`, `git_branch`, `warnings[]`). The branch written is `--git-branch`;
1057
+ # without it, `main` for an app with no runs, and a VALIDATION_ERROR before any write for an app
1058
+ # with runs (branch unknown: pass `--git-branch` with the branch the code is on). It has no effect
1059
+ # on a deploy that does not backfill. Push the managed repo's code to that branch.
1060
+ # Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines). Use `data-app runs`
1061
+ # to debug a deploy that reverts to stopped (setup-phase failures produce no container logs).
1062
+ kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--git-branch BRANCH] [--copy] [--reveal]
1063
+ kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
1064
+ kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
1065
+ kbagent data-app delete --project NAME --app-id ID [--yes]
1066
+ kbagent data-app password --project NAME --app-id ID [--copy] [--reveal] [--open]
1067
+ # data-app password: never prints the password unless --reveal, so it does not go into an AI
1068
+ # agent's context. Project token only (static or session) -- the Manage token and its prompt are
1069
+ # gone. In a terminal (human mode) it waits for `c` to copy (Enter/Esc/q finishes, 120 s timeout);
1070
+ # without a terminal or with --json only --copy copies. Nothing copied -> exit 0,
1071
+ # password_delivered_to null, ui_url = the Keboola UI page that shows it. --reveal + --copy =
1072
+ # INVALID_ARGUMENT. Refuses a non-password app (VALIDATION_ERROR) and a null password (NOT_FOUND).
1073
+ # serve: GET /data-apps/{p}/{app}/password takes no X-Manage-Token; ?reveal=true adds `password`.
1074
+ # create --wait / deploy --wait deliver the password the same way once the app runs (shared
1075
+ # CopyOption / RevealOption + deliver_password in commands/_data_app_password.py); there
1076
+ # --copy / --reveal need --wait and a deploy (else INVALID_ARGUMENT, exit 2, no API call;
1077
+ # --dry-run applies the same rules and adds a `password_delivery` plan). Without a flag and
1078
+ # without the terminal prompt nothing is read (output as before). With a flag, JSON adds only
1079
+ # ui_url / password_delivered_to / password (--reveal); any failed read after the deploy is a
1080
+ # warnings[] entry, exit 0. The serve create / deploy routes are unchanged. BREAKING: scripts
1081
+ # reading `.data.password` from `data-app password` must add --reveal.
1082
+ # Version gate + agent rules: gotchas.md / AGENT_CONTEXT.
1083
+ kbagent data-app logs --project NAME --app-id ID [--lines N] [--since ISO8601]
1084
+ kbagent data-app runs --project NAME --app-id ID [--limit N]
1085
+ kbagent data-app secrets-set --project ALIAS --app-id ID --secret '#KEY=VALUE' [--secret ...] [--secrets-file PATH] [--branch ID] [--allow-plaintext-on-encrypt-failure] [--dry-run] [--no-hint-next]
1086
+ kbagent data-app secrets-list --project ALIAS --app-id ID [--branch ID] [--show-fingerprint]
1087
+ kbagent data-app secrets-get --project ALIAS --app-id ID --key 'KEY' [--branch ID] # '#' optional; plain values return their value, encrypted return metadata only
1088
+ kbagent data-app secrets-remove --project ALIAS --app-id ID --key 'KEY' [--key ...] [--branch ID] [--yes] [--dry-run] # '#' optional
1089
+ kbagent data-app validate-repo --git-repo URL [--git-branch BRANCH] [--git-public/--no-git-public] [--git-pat-env VAR | --git-pat-file PATH] [--type python-js] [--strict]
1090
+ kbagent data-app git-repo --project NAME --app-id ID
1091
+ kbagent data-app git-credentials --project NAME --app-id ID
1092
+ kbagent data-app git-credentials-create --project NAME --app-id ID --type ssh_key|http_token --permissions readOnly|readWrite [--public-key KEY | --public-key-file PATH] [--name LABEL] [--yes]
1093
+ # git-repo introspects the deployed-from git repo (sandboxes-service /apps/{id}/git-repo); it returns 409 "no Git repository configured" until the app has been DEPLOYED at least once (git config syncs Storage->DS record at deploy). git-credentials* manage credentials for a MANAGED repo only; apps from `data-app create --git-repo` are external => git-credentials-create returns 409. http_token mints a ONE-TIME secret (shown once); credentials endpoints need an admin storage token.
1094
+
1095
+ kbagent component list [--project NAME | --all-projects] [--type TYPE] [--query QUERY]
1096
+ kbagent component detail --component-id ID [--project NAME]
1097
+ # component detail (since 0.90.0): the AI Service indexes the PUBLIC catalog only, so a private/
1098
+ # deprecated component the project can run (keboola.mcp-server-tool, keboola.data-apps) 404'd
1099
+ # there while `component list` showed it -- over `serve` as an HTTP 502. A NOT_FOUND now falls
1100
+ # back to the project's Storage component catalog; `documentation_source` ("ai_service" vs
1101
+ # "storage_catalog") tells the two apart and is present on BOTH paths. The fallback has NO
1102
+ # configuration examples (examples_count/row_examples_count always 0, schema_summary counts 0
1103
+ # unless the catalog entry ships a configurationSchema) -- check documentation_source before
1104
+ # reading 0 as "this component has none". NOT_FOUND still raised when both sources miss; a
1105
+ # non-404 AI Service failure is never masked. Over `serve`, ErrorCode.NOT_FOUND now maps to
1106
+ # HTTP 404 (was 502) on EVERY route -- branch on error.code, not on the status alone.
1107
+ kbagent component sync-action ACTION_NAME --component-id ID --project ALIAS (--config-id ID [--row-id ID] | --config-data JSON|@file|-) [--branch ID] [--timeout N]
1108
+ # sync-action (0.73.0+): POST sync-actions.{stack}/actions; ACTION_NAME freeform (component-defined,
1109
+ # e.g. testConnection/getTables); --row-id shallow-merges row over root at TOP level only (row
1110
+ # parameters/storage keys replace root wholesale, MCP parity -- NOT deep merge); --config-data
1111
+ # sends explicit configData verbatim (skips fetch); branchId omitted from body for production.
1112
+ # sync-action (0.89.0+, #620): the ROOT configuration's `authorization` and `runtime` blocks are
1113
+ # forwarded into configData too (root only -- a --row-id never overrides them; only when
1114
+ # non-empty, so a component without them sends the pre-0.89.0 body). authorization.oauth_api.id
1115
+ # is the broker reference the sync-actions service resolves + decrypts, so before 0.89.0 every
1116
+ # sync action on an OAuth/Service-Account component (e.g. keboola.ex-linkedin-ads) failed with
1117
+ # an opaque empty-body 400. MCP run_sync_action parity.
1118
+ kbagent config examples --component-id ID [--project NAME] [--row]
1119
+ kbagent config new --component-id ID [--name NAME] [--project NAME] [--output-dir DIR] [--push --no-files --description D --configuration JSON|@file|- --configuration-file PATH --no-validate --branch ID --dry-run --allow-plaintext-on-encrypt-failure]
1120
+ # config new --push --output-dir (0.89.0+, #644): the written scaffold now records the created
1121
+ # config's ID (_keboola.config_id, quoted so numeric IDs stay strings) and is placed in the
1122
+ # subtree of the branch the config was ACTUALLY created in (--branch or active branch;
1123
+ # unregistered branches are added to the manifest like `sync pull --branch` would). Before,
1124
+ # the scaffold had no ID and always landed in the default branch tree, so the next
1125
+ # `sync push` created a DUPLICATE (34-config incident). With --configuration, the local file
1126
+ # mirrors the pushed encrypted body -- placeholders would overwrite the remote on next push.
1127
+ # The scaffold also records _keboola.base_config_hash (#792 E), the created config as the API
1128
+ # returned it, so `sync diff` compares it 3-way and push never overwrites an edit made in the UI.
1129
+ # Version gate in gotchas.md.
1130
+
1131
+ # sync: GitOps -- configs as local files. init/pull/push/diff are filesystem-local (no serve REST surface).
1132
+ kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing] [--with-workspaces]
1133
+ # `sync init --with-workspaces` (CLI-25) sets the manifest key `syncWorkspaces`: pull/diff/push/clone then also sync shared SQL workspaces (keboola.sandboxes with no parameters.id and runtime.shared true; Python/R and legacy SQL sandboxes stay skipped), config only (services/_sync_workspace.py). A `push --force` delete removes the workspace's SQL editor sessions (Editor service, client/editor.py) before the config, `push --dry-run --force` lists them, and a plain push holds the delete back under skipped_deletions; clone warns about workspace input tables missing in the target. With --adopt-existing it turns the key on in an existing manifest. Version gate for this entry lives in gotchas.md.
1134
+ kbagent sync pull --project ALIAS [--all-projects] [--force] [--theirs] [--dry-run] [--with-samples] [--no-storage] [--no-jobs] [--job-limit N] [--branch ID]
1135
+ # `sync pull` auto-inits: if the target directory has no `.keboola/manifest.json`, pull runs `init` first, so a separate `sync init` is NOT needed for a first checkout. `sync pull --project X -d ./dir` on an empty dir writes the manifest and fetches the configs in one step.
1136
+ # `sync pull --force` is conflict-aware (since 0.53.0): locally-modified config whose remote is UNCHANGED is preserved (delta stays pushable, never silently re-stamped); a true merge conflict (local AND remote both changed since last pull) aborts (exit 1, SYNC_CONFLICT, --json lists details.conflicts); local-untouched + remote-changed takes remote.
1137
+ # `sync pull --theirs` (0.72.0+) is the supported reconcile path for a drifted tree: remote wins everywhere -- overwrites locally-modified configs/rows, restores deleted/missing files, resolves conflicts by taking remote (no abort). Since 0.72.0 plain pull also re-materializes a tracked config whose local dir was deleted (manifest<->disk invariant), so delete-dir-then-pull refetches; config-level isDisabled round-trips as sparse `is_disabled: true` in _config.yml (pull/diff/push).
1138
+ kbagent sync status [--directory DIR]
1139
+ kbagent sync diff --project ALIAS [--all-projects] [--directory DIR] [--branch ID]
1140
+ kbagent sync push --project ALIAS [--all-projects] [--dry-run] [--force] [--allow-plaintext-on-encrypt-failure] [--branch ID] [--no-name-drift-warnings]
1141
+ # sync push --force (#792): push deletes remote configs and rows ONLY with --force; a plain push lists them
1142
+ # under skipped_deletions (+ skipped_deletions_reason), also in --dry-run, whose summary.deleted counts only
1143
+ # what push would delete. A config/row deleted on the remote since the last pull diffs as remote_deleted and
1144
+ # is never re-created (it lands in skipped). Version gate in gotchas.md.
1145
+ # sync diff/push/pull and adopted files (#792 E): an untracked _config.yml whose _keboola.config_id
1146
+ # exists on the target has no baseline unless it records _keboola.base_config_hash; without one a
1147
+ # difference is a conflict (push skips it), two files with one id are both conflicts, and pull keeps
1148
+ # such a file with local changes (skipped) -- only --theirs overwrites it. Version gate in gotchas.md.
1149
+ # sync push encryption (#792 F): every #-secret is encrypted before the first write, so an
1150
+ # ENCRYPTION_FAILED stops push before anything reaches the remote (the message ends with "Nothing
1151
+ # was pushed.") and a retry creates nothing twice. Version gate in gotchas.md.
1152
+ # 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.
1153
+ # Partial failures change the exit code (#745): commands that collect per-item failures
1154
+ # and keep going exit 1 (was 0) when at least one item failed:
1155
+ # `sync push`, `sync push/pull/diff --all-projects`, `sync clone` (also `bucket_errors`),
1156
+ # `org setup`, `project refresh`, `project invite --from-csv`, `workspace gc`,
1157
+ # `semantic-layer import/promote/build/edit metric`, `storage describe-batch --json`,
1158
+ # `flow schedule-remove` (new `errors[]` key, always present, empty when nothing
1159
+ # failed; a partial failure fills it and exits 1; when every schedule delete
1160
+ # fails it still raises `SCHEDULE_DELETE_FAILED`). Only `sync push`, `sync clone`,
1161
+ # `storage describe-batch`, `storage describe-migrate` and `flow schedule-remove` print
1162
+ # a `Failed:` headline instead of a green `Success:`; the others list the failed items
1163
+ # in a table or in summary lines, and the `--all-projects` variants state the count in
1164
+ # their summary line. `sync push --all-projects` counts a project
1165
+ # whose push returned `errors[]` in `summary.failed`. The --json payload is emitted
1166
+ # BEFORE the exit; the items that succeeded stay written. A `--dry-run` of these
1167
+ # exits 1 when it reports a failed item, like the real run. `sync diff --all-projects`
1168
+ # exits 1 when a project failed. Other read-only fan-outs (`billing credits`, `job list`,
1169
+ # `schedule list`, ...) still exit 0. The helper is `item_failure_exit_code()` in
1170
+ # commands/_helpers.py (returns the code, the caller raises). Version gate for this
1171
+ # entry lives in gotchas.md -- the placeholder cannot be written on these `# ` comment
1172
+ # lines (check_version_gates.py parses them as ATX markdown headings).
1173
+ # sync push (since 0.91.0, #686): the manifest baseline `pull_config_hash` is stamped from the API
1174
+ # response (or a read-back), never from disk -- push-deployed multi-statement SQL transformations
1175
+ # (and anything disabled in the UI whose local YAML lacks `is_disabled`) no longer show permanent
1176
+ # phantom `~ REMOTE MODIFIED` drift in `sync diff`. Unreadable-after-write leaves the baseline
1177
+ # UNTOUCHED + a `warnings[]` entry (never a disk-derived fallback). One canonical script[] shape now
1178
+ # (one element = one statement) and `transform.sql` gains `/* ===== STATEMENT ===== */` markers when
1179
+ # semicolons cannot recover the boundaries -- which also closes a SILENT pre-0.91.0 rewrite that
1180
+ # collapsed such scripts to one statement (MULTI_STATEMENT_COUNT=1) while diff said "in sync".
1181
+ # Migration: entries carry `metadata.config_hash_version`; unversioned ones match leniently (pre-0.91.0
1182
+ # hash of the SAME remote counts as in sync, nothing else), and ONE `sync pull` per project migrates.
1183
+ # A pre-markers tree whose only difference from the remote is the lost boundaries is REFUSED per-change
1184
+ # with SYNC_LEGACY_BOUNDARY telling you to pull first; genuine edits push normally.
1185
+ # sync diff/push (0.89.0+, #649): local side read from exactly ONE tree (target branch subtree, else main/); entries tracked on another branch's tree are excluded from the changeset and reported under orphaned[] + summary.orphaned (reasons + reconcile hints); fix with sync pull. Adopt-by-id is branch-aware.
1186
+ # Ignored components (since 0.91.0, #689): keboola.mcp-server-tool joins keboola.sandboxes on ALWAYS_IGNORED_COMPONENTS (the MCP server's auto-created empty mcp-workspace-<hex> configs); the manifest field ignoredComponents (.keboola/manifest.json) is now LIVE and unions with the hardcoded set, honored by pull/diff/push. pull drops manifest entries + local dirs for a newly-ignored component, reported with action "ignored" (distinct from "removed" = deleted on remote); diff filters the local side too, so a stale dir for an ignored component can never classify as DELETED -- closes the delete-dir-then-push trap that used to destroy production keboola.mcp-server-tool configs.
1187
+ # sync pull/diff/push refuse a directory of another project (CLI-31): the manifest project.id and apiHost must
1188
+ # match the --project project (also --all-projects), else CONFIG_ERROR (exit 5) naming both project IDs, before
1189
+ # any API call. A project without a stored project_id costs one token verification call. Copy configs between
1190
+ # projects with `sync clone`. Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines).
1191
+ kbagent sync clone --source DIR --target ALIAS --target-dir DIR [--bucket-map FILE] [--variable-values FILE] [--instance-rename FILE] [--no-create-buckets] [--dry-run] [--branch ID]
1192
+ # `sync clone` (0.63.0+) copies a reference synced tree into a fresh target project + parameterizes it: applies bucket_map / variable_values / instance_rename overrides (JSON/YAML files), then pushes so every config CREATEs fresh -- keboola.flow and keboola.orchestrator task configIds (and configRowIds), schedule targets, and transformation variable and shared-code links are remapped reference->ULID by push Phase C/D (`link_remaps` counts each kind; a link it cannot set is an `errors[]` entry, and a failed PUT is sent again by the next push). Schedules are never activated and data apps never deployed: `warnings[]` (also on --dry-run, human mode prints them) lists those, copied `KBC::` values the target cannot decrypt, and tasks that run a config not in the tree. Only the run that creates the configs reports them; a re-run returns `warnings: []`. Idempotent: re-run with an existing --target-dir reports no_changes. Fails fast if the target already contains the reference's configs (clone needs a fresh target). Override files must be flat {id: scalar} mappings (0.89.0+): a nested mapping/list/null value is rejected with CONFIG_ERROR naming the key + actual type, instead of being silently stringified into a bogus ID. `--branch` is optional on a fresh clone. It defaults to the target's production branch, resolved from the API like `sync init`. An active branch set with `branch use` on the target wins over production. Pass `--branch` only to target a dev branch of the target. Clone recreates the reference tree's storage buckets in the target from the `storage/buckets.json` pull export BY DEFAULT -- `--no-create-buckets` skips it. Idempotent: an existing bucket is skipped, a per-bucket failure is collected in `bucket_errors`, a linked (shared) bucket is linked to the same source as in the reference (listed in `linked_buckets`; the source's sharing settings decide, a refused link lands in `bucket_errors`). Only the buckets are created, never their tables or data (the export carries no table data). Version gate in gotchas.md.
1193
+ kbagent sync branch-link --project ALIAS (--branch-id ID | --branch-name NAME) [--directory DIR]
1194
+ kbagent sync branch-unlink [--directory DIR]
1195
+ kbagent sync branch-status [--directory DIR]
1196
+
1197
+ kbagent dev-portal identity add --alias A --username U [--password P | --password-stdin]
1198
+ [--role-hint vendor|admin] [--vendor V] [--portal-url URL]
1199
+ kbagent dev-portal identity list
1200
+ kbagent dev-portal identity remove --alias A
1201
+ kbagent dev-portal identity edit --alias A [--username U] [--password P|--password-stdin]
1202
+ [--role-hint H] [--vendor V] [--new-alias N]
1203
+ kbagent dev-portal identity use ALIAS
1204
+ kbagent dev-portal identity current
1205
+ kbagent dev-portal identity verify [--identity A]
1206
+
1207
+ kbagent dev-portal list --vendor V [--identity A]
1208
+ kbagent dev-portal get --app VENDOR.APP_ID [--identity A]
1209
+
1210
+ kbagent dev-portal create --vendor V --data FILE [--identity A] [--dry-run]
1211
+ kbagent dev-portal patch --app VENDOR.APP_ID (--data FILE | --property KEY (--value V | --value-file F))
1212
+ [--identity A] [--dry-run]
1213
+ kbagent dev-portal upload-icon --app VENDOR.APP_ID --file PATH [--identity A] [--dry-run]
1214
+ kbagent dev-portal publish --app VENDOR.APP_ID [--identity A] [--dry-run]
1215
+ kbagent dev-portal deprecate --app VENDOR.APP_ID [--identity A] [--dry-run]
1216
+ # All writes require an interactive random-code TTY confirm; no --yes / no env bypass.
1217
+ # Since v0.51.1: --role-hint is validated (vendor/admin) and load-bearing -- admin identities route
1218
+ # `patch` to PATCH /admin/apps/{app} (permissive schema). Vendor + admin-only field => fail-fast preflight.
1219
+ # --password-stdin works on TTY (hidden prompt) AND on a pipe (reads to EOF).
1220
+
1221
+ kbagent encrypt values --project ALIAS --component-id ID --input JSON|@file|- [--output-file PATH]
1222
+
1223
+ kbagent semantic-layer model list --project P
1224
+ kbagent semantic-layer model create --project P --name N [--description D] [--sql-dialect Snowflake] [--scope project|organization|targeted] [--target-project ALIAS|ID ...]
1225
+ kbagent semantic-layer model delete --project P --model M [--yes]
1226
+ kbagent semantic-layer show --project P [--model M] [--type dataset|metric|relationship|constraint|glossary]
1227
+ kbagent semantic-layer search-context --project P [--pattern G ...] [--type model|dataset|metric|relationship|constraint|glossary|all] [--limit N]
1228
+ kbagent semantic-layer schema --project P (--type model|dataset|metric|relationship|constraint|glossary[,TYPE...] | --all)
1229
+ kbagent semantic-layer get-context --project P --context-id ID
1230
+ kbagent semantic-layer validate --project P [--model M] [--deep]
1231
+ kbagent semantic-layer export --project P [--model M] [--output PATH]
1232
+ kbagent semantic-layer diff (--project-a A | --file-a PATH) (--project-b B | --file-b PATH) [--model-a M] [--model-b M]
1233
+ kbagent semantic-layer add metric --project P [--model M] --name N --sql SQL --dataset TABLE_ID [--description D] [--yes]
1234
+ kbagent semantic-layer add dataset --project P [--model M] --name N --table-id TABLE_ID [--description D] [--grain G] [--primary-key COL ...] [--deep-fields] [--fqn FQN]
1235
+ # dataset fqn (#761): `add dataset` and `build` read the fqn from the table's Storage location --
1236
+ # the owning bucket's backendPath, surfaced as `sql_path` / `backend_path` on `storage table-detail`.
1237
+ # They used to hardcode a "KEBOOLA" database that exists in no project, so every consumer pasting
1238
+ # the fqn into SQL failed. A LINKED bucket's path names the SOURCE project's database + schema;
1239
+ # swapping in the consuming project's database does not resolve either. `add dataset` now needs
1240
+ # the table to exist (one table-detail call) unless `--fqn` supplies the value verbatim; a table
1241
+ # whose location Storage does not report fails with VALIDATION_ERROR. `build --types-workspace`
1242
+ # queries INFORMATION_SCHEMA in that same database/schema. `validate --deep` warns FQN_MISMATCH
1243
+ # on stored fqns that differ (pre-fix models); repair via export -> fix fqn + metric sql -> import
1244
+ # --overwrite. Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines).
1245
+ kbagent semantic-layer add relationship --project P [--model M] --name N --from TABLE_ID --to TABLE_ID --on EXPR [--type left|inner]
1246
+ kbagent semantic-layer add constraint --project P [--model M] --name N --constraint-type inequality|equality|range|composition|exclusion|temporal|conditional --rule "EXPR" --metrics M1,M2 [--severity error|warning|info]
1247
+ kbagent semantic-layer add glossary --project P [--model M] --term TERM --definition D
1248
+ kbagent semantic-layer edit metric --project P [--model M] --name N [--new-name N2] [--new-sql SQL] [--new-dataset TABLE_ID] [--new-description D] [--yes]
1249
+ kbagent semantic-layer edit dataset --project P [--model M] --name N [--new-name N2] [--new-description D] [--new-grain G]
1250
+ kbagent semantic-layer edit constraint --project P [--model M] --name N [--new-name N2] [--new-rule "EXPR"] [--new-constraint-type T] [--new-severity error|warning|info] [--new-metrics M1,M2]
1251
+ kbagent semantic-layer edit relationship --project P [--model M] --name N [--new-name N2] [--new-from TABLE_ID] [--new-to TABLE_ID] [--new-on EXPR] [--new-type left|inner]
1252
+ kbagent semantic-layer edit glossary --project P [--model M] --term TERM [--new-term TERM2] [--new-definition D] [--yes]
1253
+ kbagent semantic-layer remove metric --project P [--model M] --name N [--yes]
1254
+ kbagent semantic-layer remove dataset --project P [--model M] --name N [--yes]
1255
+ kbagent semantic-layer remove constraint --project P [--model M] --name N [--yes]
1256
+ kbagent semantic-layer remove relationship --project P [--model M] --name N [--yes]
1257
+ kbagent semantic-layer remove glossary --project P [--model M] --term TERM [--yes]
1258
+ kbagent semantic-layer import --project P --file PATH [--model M] [--types T,T,...] [--dry-run] [--yes] [--overwrite] [--scope project|organization|targeted] [--target-project ALIAS|ID ...]
1259
+ kbagent semantic-layer promote --from-project A --to-project B [--from-model M] [--to-model M] [--types T,T,...] [--dry-run] [--yes] [--scope project|organization|targeted] [--target-project ALIAS|ID ...]
1260
+ kbagent semantic-layer build --project P [--model M] --tables T,T,... [--name N] [--dry-run] [--keep-on-failure] [--output PATH]
1261
+ kbagent semantic-layer token --encrypt --project P --component-id C
1262
+ # scope (PSGO-140, new): visibility scope for a semantic-layer item -- "project"
1263
+ # (owner only), "organization" (every project in the org), or "targeted" (owner +
1264
+ # explicit --target-project grants). --scope/--target-project are also accepted by `model
1265
+ # create` and every `add <kind>` above. --scope omitted: `model create` makes a "project"
1266
+ # item, `add <kind>` INHERITS its model's scope (an org-level model gets org-level children;
1267
+ # a targeted model, its target projects); an inherited organization scope is permission-gated
1268
+ # like a typed one, and a non-org-admin gets a 403 on it (pass --scope project). `import`,
1269
+ # `promote` and `build --model` create their NEW items at the target model's scope the same way
1270
+ # (same gate: FLAG_ESCALATIONS `semantic-layer.import|promote|build --scope organization`);
1271
+ # `import` / `promote --scope` (+ --target-project) override it, e.g. `--scope project` for a
1272
+ # non-org-admin under an org-level model; items they overwrite keep their own scope. Item names are unique per object type across ALL
1273
+ # models of a project (ALREADY_EXISTS says "in this project"), so a model cannot be copied into
1274
+ # a second model of the same project under the same item names. An item stored at schema version
1275
+ # 1.0.0 (created before 0.97.0) cannot be elevated: the error names the stored version and the
1276
+ # fix (export, delete, create again, import). --target-project takes a registered alias OR a
1277
+ # numeric project ID (repeatable or comma-separated; an alias must be on the owner's stack);
1278
+ # without --scope targeted it exits 2. With --scope targeted and no --target-project: a real
1279
+ # terminal launches an interactive picker over the other projects on the stack; --json fails
1280
+ # fast (exit 2). A bad alias/ID/--scope/--type is a usage error (exit 2), never a traceback.
1281
+ # Creating directly at --scope organization requires the organization-admin ROLE (403
1282
+ # otherwise) -- an ordinary token instead uses `scope request-create` + an org-admin's
1283
+ # `scope set --scope organization`. Elevation is ONE-WAY (no downgrade endpoint), which is why
1284
+ # every `--scope organization` (here and on `model create` / `add <kind>`) is destructive-class
1285
+ # (FLAG_ESCALATIONS). `edit`, `import --overwrite` and `promote` update in place (PUT): an item
1286
+ # keeps its id, scope, grants and pending elevation request. `scope add|remove` merge into the
1287
+ # grants client-side (not atomic; refused from a project that does not own the item, because
1288
+ # the server hides the grants from a non-owner -- use `scope set --target-project` there).
1289
+ # Verbs follow the CLI spec (#791): get / add / remove / set / request-create / request-delete /
1290
+ # request-list; `scope set` takes exactly ONE of --scope organization, --target-project (replace
1291
+ # the whole list) or --clear.
1292
+ kbagent semantic-layer scope get --project P --type model|dataset|metric|relationship|constraint|glossary --context-id ID
1293
+ kbagent semantic-layer scope add --project P --type T --context-id ID --target-project ALIAS|ID [--target-project ...]
1294
+ kbagent semantic-layer scope remove --project P --type T --context-id ID --target-project ALIAS|ID [--target-project ...]
1295
+ kbagent semantic-layer scope set --project P --type T --context-id ID (--scope organization | --target-project ALIAS|ID [...] | --clear) [--dry-run] [--yes]
1296
+ kbagent semantic-layer scope request-create --project P --type T --context-id ID
1297
+ kbagent semantic-layer scope request-delete --project P --type T --context-id ID
1298
+ kbagent semantic-layer scope request-list --project P --type T [--limit N] [--offset N]
1299
+ # scope over `kbagent serve`: GET/PUT /semantic-layer/scope/{context_id}, POST/DELETE
1300
+ # .../target-projects, PUT/DELETE .../elevation-request, GET /semantic-layer/scope/elevation-requests;
1301
+ # POST /semantic-layer/models and /items/{kind} take `scope` + `target_projects`.
1302
+ kbagent semantic-layer reference-data list --project P [--model M]
1303
+ kbagent semantic-layer reference-data get --project P (--id ID | --dimension D)
1304
+ kbagent semantic-layer reference-data set --project P [--model M] --dimension D --members-file PATH [--dataset-id T] [--description X]
1305
+ kbagent semantic-layer reference-data delete --project P --id ID [--yes]
1306
+ # Alias: `kbagent sl ...` (hidden) is equivalent to `kbagent semantic-layer ...`.
1307
+ # semantic-layer READS work with any valid, non-disabled, non-expired Storage token
1308
+ # (0.97.0, PSGO-282): the Metastore no longer requires a master token for GET/List. WRITES
1309
+ # (add/edit/remove/import/promote/build/scope add|remove|set) still need a project-admin token
1310
+ # (master token or any admin-role user token) -- a non-admin token 403s on the write. Before
1311
+ # PSGO-282 the Metastore's auth gate rejected EVERY valid non-master token, including reads,
1312
+ # with an opaque 401 "Failed to create project scope" (#711, MasterTokenRequiredError swallowed
1313
+ # server-side); kbagent still reclassifies exactly that 401 to MISSING_MASTER_TOKEN (exit 3) as
1314
+ # a safety net for a deployment that predates the fix. Other unexplained 401s anywhere map to
1315
+ # AUTH_REJECTED instead of the false "Invalid or expired token" (INVALID_TOKEN stays for 401s
1316
+ # that DO blame the credential). Version gate for this entry lives in gotchas.md -- `(since
1317
+ # 0.97.0)` cannot be written on these `# ` comment lines (check_version_gates.py parses them as
1318
+ # ATX headings).
1319
+
1320
+ kbagent http get PATH [--timeout SECONDS]
1321
+ kbagent http post PATH [--body JSON|@file|-] [--timeout SECONDS]
1322
+ kbagent http patch PATH [--body JSON|@file|-] [--timeout SECONDS]
1323
+ kbagent http delete PATH [--timeout SECONDS]
1324
+ # `http` talks to the running `kbagent serve`. Requires KBAGENT_SERVE_URL +
1325
+ # KBAGENT_SERVE_TOKEN env vars (auto-injected into AI-agent / cli_command
1326
+ # subprocesses by the scheduler). Use this from inside a scheduled agent
1327
+ # task instead of forking another `kbagent` CLI process tree.
1328
+
1329
+ kbagent agent list
1330
+ kbagent agent show TASK_ID
1331
+ kbagent agent create --name NAME [--description D] [--cron CRON] [--manual] [--enabled/--disabled] (--type ai_agent --cli CLI --prompt P [--extra-arg ARG ...] [--timeout SECONDS] | --type cli_command --argv ARG [--argv ARG ...] [--timeout SECONDS] | --from-file JSON|@path|-) [--trigger-task-id ID --trigger-on success|error|always]
1332
+ kbagent agent update TASK_ID [--name N] [--description D] [--cron C] [--enabled/--disabled] [--manual/--auto] [--clear-trigger] [--trigger-task-id ID --trigger-on success|error|always]
1333
+ kbagent agent delete TASK_ID [--yes]
1334
+ kbagent agent run TASK_ID [--stream] [--runtime-prompt TEXT | --runtime-input JSON|@file|-]
1335
+ kbagent agent runs TASK_ID [--limit N]
1336
+ kbagent agent run-detail TASK_ID RUN_ID
1337
+ kbagent agent run-events TASK_ID RUN_ID
1338
+ kbagent agent test (--type ai_agent --cli CLI --prompt P | --type cli_command --argv ARG ... | --from-file JSON|@path|-) [--name N] [--stream] [--timeout SECONDS]
1339
+ kbagent agent cron-preview --cron "0 6 * * 1" [--count N]
1340
+ kbagent agent prompt-improve --goal "..." [--draft "..."] [--cli claude|codex|gemini] [--project ALIAS] [--extra-arg X ...] [--stream/--no-stream]
1341
+ # `agent` reads/writes <config_dir>/agents.json directly (offline-first, no
1342
+ # serve required for CRUD + ad-hoc run). The cron loop that fires scheduled
1343
+ # tasks still requires `kbagent serve` running. Two action flavours
1344
+ # (ai_agent / cli_command) mirror the /agents REST surface
1345
+ # byte-for-byte. Every subcommand taking TASK_ID / RUN_ID accepts it
1346
+ # positionally OR via flag (--id / --task-id; --run-id for run-detail /
1347
+ # run-events) -- the flag form matches the rest of the CLI (--job-id, ...).
1348
+
1349
+ kbagent kai ping [--project NAME]
1350
+ kbagent kai preflight [--project NAME]
1351
+ kbagent kai ask --message "question" [--project NAME]
1352
+ kbagent kai chat --message "msg" [--chat-id ID] [--project NAME]
1353
+ kbagent kai chat-detail --chat-id ID [--project NAME]
1354
+ kbagent kai history [--project NAME] [--limit N]
1355
+ # Default-project resolution (since 0.93.0, #684): the `kai` group, `docs query`, `component detail`,
1356
+ # `component list --query`, `config examples`, and `config new` (scaffold mode) resolve an omitted
1357
+ # --project through the shared cascade (--project > KBAGENT_PROJECT env > `project use` pin > sole
1358
+ # project). Before 0.93.0 these paths used the FIRST REGISTERED project and ignored the pin.
1359
+ # Several projects with no pin now exit 5 (CONFIG_ERROR) instead of silently picking the first.
1360
+ # Same fix over `kbagent serve`: /kai/*, POST /documentation/query, GET /components?query=...
1361
+
1362
+ kbagent transformation create --project NAME --name NAME (--sql 'SELECT ...' | --sql-file PATH) [--created-table NAME ...] [--component-id ID] [--description D] [--branch ID] [--dry-run]
1363
+ kbagent transformation show --project NAME --config-id ID [--component-id ID] [--branch ID]
1364
+ kbagent transformation edit --project NAME --config-id ID --change-description TEXT (--op JSON ... | --op-file ops.json) [--storage JSON|@file|-] [--component-id ID] [--branch ID] [--dry-run]
1365
+ # transformation (0.73.0+): native SQL-transformation editing (port of MCP create/update_sql_transformation, #396).
1366
+ # create: component derived from the project default_backend (snowflake|bigquery; other backends need
1367
+ # --component-id); SQL split one-statement-per-script[] element; single block "Blocks"/code "Code";
1368
+ # each --created-table T maps to out.c-<cleaned-name>.<T>. show: synthetic positional ids b{i}/b{i}.c{j};
1369
+ # when --component-id omitted, all known SQL transformation components are tried. edit: 9 ops
1370
+ # (add/remove/rename block+code, set_code, add_script, str_replace) applied sequentially against
1371
+ # batch-start ids -- ALWAYS `transformation show` first, ids renumber after structural ops;
1372
+ # --storage REPLACES configuration.storage wholesale; --dry-run previews without PUT.
1373
+
1374
+ kbagent docs query "QUESTION" [--project NAME]
1375
+ # (0.73.0+) Documentation Q&A via the AI Service (server-side RAG). Unlike kai ask it does NOT
1376
+ # see project data; works with any token. --json emits {query, text, source_urls}.
1377
+
1378
+ kbagent flow list [--project NAME | --all-projects] [--branch ID] [--with-schedules]
1379
+ kbagent flow detail --project NAME --flow-id ID [--branch ID]
1380
+ kbagent flow schema [--full [--project NAME]]
1381
+ kbagent flow examples [--component-id keboola.flow|keboola.orchestrator]
1382
+ kbagent flow validate --file @flow.yaml|- [--project NAME]
1383
+ kbagent flow new --project NAME --name NAME [--description D] [--file @path.yaml|-|JSON] [--branch ID]
1384
+ kbagent flow update --project NAME --flow-id ID [--name N] [--description D] [--file @path.yaml|-|JSON] [--branch ID]
1385
+ kbagent flow delete --project NAME --flow-id ID [--branch ID] [--yes]
1386
+ # flow delete: the same locate-first soft delete as `config delete` -- a flow already in the trash
1387
+ # answers status "already_in_trash", exit 0, and no second DELETE (it would purge). Version gate
1388
+ # lives in gotchas.md.
1389
+ kbagent flow schedule --project NAME --flow-id ID --cron "0 6 * * *" [--timezone TZ] [--disabled] [--branch ID]
1390
+ kbagent flow schedule-remove --project NAME --flow-id ID [--branch ID] [--yes]
1391
+ kbagent flow triggers --project NAME --flow-id ID [--branch ID]
1392
+ # flow triggers (#714): the honest answer to "what starts this flow automatically". A flow has at
1393
+ # least three trigger mechanisms and kbagent used to see ONE: `schedule list` / `search` only ever
1394
+ # read `keboola.scheduler` configs, so a flow driven by a TABLE TRIGGER came back "nothing found"
1395
+ # and got reported as having no trigger -- twice in one investigation, for a flow that was already
1396
+ # live. Table triggers are a SEPARATE Storage API resource (`GET /v2/storage/triggers`), not a
1397
+ # component config, which is why nothing in kbagent saw them. This command returns cron_schedules
1398
+ # AND table_triggers in one call.
1399
+ # CROSS-PROJECT triggers (a trigger-queue app config in ANOTHER project) are NOT covered: the
1400
+ # result carries `cross_project_triggers_checked: false`, deliberately NOT an empty list -- an
1401
+ # empty list reads as "checked, found none", which is the exact false negative this exists to
1402
+ # prevent. Read that flag before concluding a flow has no trigger.
1403
+ # PRODUCTION ONLY: the Storage triggers route is declared `isAvailableInBranch: false`, so it has
1404
+ # no branch-scoped variant. `--branch` narrows the CRON half only; `table_triggers_branch_scoped`
1405
+ # is always false.
1406
+ # `lastRun: null` means the trigger exists but has NEVER FIRED -- not that it is disabled.
1407
+ # `schedule list` / `schedule find` now say "No cron schedules found. Table triggers and
1408
+ # cross-project triggers were NOT checked -- see `kbagent flow triggers`" instead of the old
1409
+ # "No schedules found".
1410
+ # `job detail` on a keboola.flow / keboola.orchestrator job carries `trigger_hint` (same over
1411
+ # `serve`): a run with no matching cron schedule is NOT necessarily manual -- check
1412
+ # `flow triggers` first. Human mode adds "Created by token" (job provenance).
1413
+ # Flows are conditional flows (keboola.flow). keboola.orchestrator is NOT supported (dropped 0.57.0).
1414
+ # IDs are strings; phases use next[].goto + conditions; tasks are typed (job/notification/variable).
1415
+ # flow new/update validate against the live CF schema fetched from the stack (AI Service
1416
+ # configurationSchema for keboola.flow; NOT bundled) -> INVALID_FLOW_DEFINITION on failure.
1417
+ # Schema-fetch failure (network/empty) does NOT block the write: structural check skipped,
1418
+ # semantic checks still run, a "structural schema validation skipped" warning is surfaced.
1419
+ # flow validate: with --project fetches the live schema (full validation; fetch failure ->
1420
+ # semantic-only + note); without --project runs semantic-only + a note. flow schema --full:
1421
+ # with --project fetches the live schema (source=live); without --project serves the bundled
1422
+ # authoritative snapshot (source=bundled, 0.73.0+). Plain flow schema is the offline YAML template.
1423
+ # flow examples (0.73.0+): bundled example flow configs (vendored from keboola-mcp-server), offline.
1424
+ # Default keboola.flow; keboola.orchestrator serves legacy examples informational-only (kbagent
1425
+ # cannot create/edit orchestrator flows). --json emits the bare list of configs.
1426
+ # flow schedule (0.66.1+) also activates the config on the Scheduler Service so the cron fires;
1427
+ # activation failure keeps the config written, sets activated=false + warning, exit stays 0.
1428
+ # flow schedule-remove deregisters from the service before deleting each config.
1429
+ # Execute a flow with: kbagent job run --project NAME --component-id keboola.flow --config-id ID
1430
+
1431
+ kbagent schedule list [--project NAME ... | --all-projects] [--enabled-only] [--branch ID]
1432
+ kbagent schedule detail --project NAME --schedule-id ID [--branch ID]
1433
+ kbagent schedule find [--cron-window START-END] [--not-run-since DAYS] [--project NAME ... | --all-projects] [--branch ID]
1434
+
1435
+ kbagent notification list [--project NAME ... | --all-projects] [--event NAME] [--component-id ID] [--config-id ID]
1436
+ kbagent notification detail --project NAME --subscription-id ID
1437
+ kbagent notification create --project ALIAS --event NAME --channel email|webhook --address ADDR [--component-id ID] [--config-id ID] [--branch ID] [--expires-at TS]
1438
+ kbagent notification delete --project ALIAS --subscription-id ID [--yes]
1439
+ kbagent notification replace-recipient --project ALIAS --subscription-id ID --address NEW_ADDR [--channel email|webhook] [--yes]
1440
+ # notification WRITE path (since 0.91.0, #690): the group is no longer read-only.
1441
+ # --address carries the email address (--channel email) OR the webhook URL (--channel webhook) --
1442
+ # channel-discriminated on the wire, same as the read path's single `address` column. An invalid
1443
+ # --channel is a structured INVALID_ARGUMENT, exit 2. `create` WITHOUT --branch writes NO branch.id
1444
+ # filter, unlike the UI which always writes one; an absent filter does not constrain matching, so
1445
+ # such a subscription fires for jobs on EVERY branch.
1446
+ # `replace-recipient` is delete+recreate -- the API has NO update primitive. It creates the NEW
1447
+ # subscription FIRST, then deletes the old one, so a NEW subscription_id is ALWAYS minted (scripts
1448
+ # must not cache the old one; the result carries old_subscription_id + new_subscription_id). A
1449
+ # failed delete leaves a recoverable DUPLICATE, surfaced as `old_deleted: false` + a warning --
1450
+ # never a lost subscription.
1451
+ # Permission classes: notification.create = write, notification.replace-recipient = write,
1452
+ # notification.delete = destructive. So --deny-writes blocks all three; --deny-destructive blocks
1453
+ # only `delete`. `delete` / `replace-recipient` prompt for confirmation unless --yes (or --json).
1454
+ # notification READ path (0.86.0+, #600): read-only audit of Notification Service subscriptions -- the
1455
+ # recipients behind the Flow Builder's Notifications tab (bell icon). They live in a SEPARATE
1456
+ # platform service (notification.{stack}, plain Storage token, no elevated scope), NOT in the
1457
+ # flow's configuration JSON, so `flow detail` / `config detail` never showed them. The in-flow
1458
+ # `type: "notification"` TASK is a different mechanism and stays visible there.
1459
+ # Event names are kebab-case (job-failed, job-succeeded, job-succeeded-with-warning,
1460
+ # job-processing-long + phase-job-* variants); --event is NOT validated (the API declares
1461
+ # EventName as an open string). The service ACCEPTS ?event= and then IGNORES it (200 + the
1462
+ # full list, verified live), so kbagent sends it AND narrows client-side -- a direct API
1463
+ # caller must do the same or get a superset. Filter fields are dotted paths into the event
1464
+ # payload (job.component.id, job.configuration.id, branch.id, phase.id) -- --component-id /
1465
+ # --config-id likewise match CLIENT-SIDE. A subscription with
1466
+ # NO filters is project-wide and fires for EVERY job; those are dropped by --component-id/
1467
+ # --config-id and counted in `project_wide_excluded` (plus a warning) so "who gets paged for
1468
+ # this flow" is never silently under-reported. Webhook recipients carry `url`, email carries
1469
+ # `address` -- both render in the single `address` column. The Branch column is populated on
1470
+ # EVERY row, production included: the UI always writes a branch.id filter, and for production
1471
+ # that value is the DEFAULT branch's numeric id -- compare against `branch list` to tell a
1472
+ # production alert from a dev-branch one; presence alone means nothing.
1473
+
1474
+ kbagent context
1475
+ kbagent init [--from-global] [--project ALIAS ...]
1476
+ # `--project ALIAS` (repeatable) copies only the named project(s) from the global config and implies --from-global.
1477
+ kbagent doctor
1478
+ # `doctor` includes an `mcp_tool_tasks` check: it FAILs on scheduled agent tasks still
1479
+ # using the removed `--type mcp_tool` (they are inert tombstones that never run again).
1480
+ # `agent list` marks those rows and adds a per-task `deprecation` key in --json. Recreate
1481
+ # each as `--type cli_command` using the map in docs/mcp-migration.md.
1482
+ # `doctor` has no `--fix` since 0.85.0 -- it only ever installed keboola-mcp-server.
1483
+ kbagent version [--beta]
1484
+ kbagent update [--beta] [--major]
1485
+ # Major gate (CLI-40, #791 section 4.3): the updater (startup hook, `update`, `version`) reads
1486
+ # /releases/latest (the list /releases?per_page=100 only for --beta or when latest names a higher
1487
+ # major) plus /releases/tags/v<N+1>.0.0 at most once per 24 h, and stays on the running major. It installs the next major only at M
1488
+ # (published_at of the GitHub release v<N+1>.0.0 + 28 days, "now" = the GitHub Date header) or
1489
+ # with `update --major`; `--beta` alone never crosses. A crossing always goes through the deferred
1490
+ # helper (update_runner.py; /bin/sh + pgrep on POSIX, PowerShell on Windows): the command finishes
1491
+ # on the old major, no re-exec, a running `serve` holds it (helper gives up after 900 s). While
1492
+ # v<N+1>.0.0 exists the DEPRECATED_VERSION notice shows: stderr once per 24 h and every run in the
1493
+ # last 72 h before M; always in version/update/doctor/context; under --json a top-level warnings[]
1494
+ # entry on every run (update_notice.py keeps it at module level, output.py adds it to both
1495
+ # envelopes). Cache keys next_major_version/_release_id/_published_at, checked_at,
1496
+ # notice_shown_at; a cached latest_version of a higher major is ignored; `version --beta` no
1497
+ # longer writes the cache. Version gate lives in gotchas.md.
1498
+ # `--beta` (or env `KBAGENT_INCLUDE_PRERELEASE=1`) opts into pre-release versions
1499
+ # (PEP 440 betas/rc, e.g. 0.43.0b1). Default (no flag) is stable-only -- auto-update
1500
+ # startup hook never silently lands on a beta.
1501
+ # Since 0.60.0 install + self-update prefer a prebuilt wheel Release asset (fast, no
1502
+ # source build; falls back to git+ when absent). Env `KBAGENT_UPDATE_TIMEOUT` (integer
1503
+ # seconds, default 300) raises the self-update subprocess timeout for the slow git+
1504
+ # fallback on WSL. Bootstrap install: `curl -LsSf .../main/install.sh | sh`.
1505
+ # Since 0.79.0 a STANDALONE (PyInstaller) binary (choco/winget/brew/apt/dnf/zip) refuses
1506
+ # the kbagent self-update stage and reports that channel's own command instead -- a uv/pip
1507
+ # reinstall would install a SECOND, unrelated kbagent that shadows it on PATH. `version
1508
+ # --json` gains additive `install_channel` + `upgrade_hint`; `upgrade_command` is empty for
1509
+ # a hand-unpacked archive. Since 0.88.0 `upgrade_command` is ALSO empty whenever `up_to_date`
1510
+ # is not `false` (i.e. `true` or `null`) -- it used to be built unconditionally, so a caller on
1511
+ # a pre-release got `up_to_date: true` beside a pinned `--force --reinstall` command for the
1512
+ # older STABLE wheel (a silent downgrade), and an unreachable feed got an unpinned `git+`
1513
+ # default-branch install. Gate on `up_to_date is False`, never on the string being present. Since 0.85.0 `update` handles kbagent ONLY -- keboola-mcp-server
1514
+ # is no longer installed or refreshed by kbagent (see docs/mcp-migration.md for the manual
1515
+ # `uv tool install --upgrade --prerelease=allow keboola-mcp-server` command). Self-update
1516
+ # completes discovery first, then does the terminal exact-version reinstall and immediately
1517
+ # re-executes; failures print a copy-paste recovery command.
1518
+ kbagent changelog [--limit N] [--full]
1519
+ # Default shows first sentences: every BREAKING note of a version, plus its first other notes until at least two show; --full / -v expands every note.
1520
+ kbagent serve [--host HOST] [--port PORT] [--ui] [--ui-dist PATH] [--reload] [--log-level LVL] [--cors-origin ORIGIN] [--config-dir DIR] [--no-banner]
1521
+ # serve dry_run (CLI-33): a POST/PUT/PATCH/DELETE route answers HTTP 422 (HTTP_ERROR) when the
1522
+ # request sends `dry_run` in the query string or as a top-level JSON body key, and the route does
1523
+ # not declare it there. Before, the route ignored it and ran the real write.
1524
+ # A false value (false/0/no/off/f/n in any case, or JSON false/0) is ignored and the real write runs.
1525
+ # Any other value (true, null, an unknown string) is refused.
1526
+ # One app-level dependency does this: reject_undeclared_dry_run in server/dependencies.py.
1527
+ # Not checked: GET routes, nested keys, multipart upload bodies, and a body above 1 MiB (or without
1528
+ # Content-Length) on a route that has no body parameter. Version gate lives in gotchas.md.
1529
+ # `--config-dir` on serve (since 0.91.0, #679): `serve` is the only subcommand with a --config-dir of
1530
+ # its own, and most specific wins -- `serve --config-dir X` beats a root `kbagent --config-dir Y`,
1531
+ # which in turn beats KBAGENT_CONFIG_DIR / the .kbagent walk-up / global. Passing both is NOT an
1532
+ # error. Up to 0.90.1 the ROOT flag was ignored by serve entirely, silently: `kbagent --config-dir A
1533
+ # serve` exposed a different project set than the caller named, and (since 0.90.1's /auth/*
1534
+ # enforcement) applied a different directory's `permissions` policy. On <=0.90.1 always pass
1535
+ # --config-dir to `serve` itself. Only an explicit root flag propagates -- an env-var/walk-up/global
1536
+ # resolution is left to the server, which reaches the identical directory on its own.
1537
+ # `--no-banner` (since 0.90.0): suppress the web UI's "What's new" popup. The UI shows a curated
1538
+ # per-version highlights modal once per version (localStorage `kbagent.whatsnew.seen`); this flag
1539
+ # turns the UNSOLICITED popup off fleet-wide. Surfaced to the SPA via `GET /ui-config`
1540
+ # ({"banner": bool}) -- NOT injected into index.html: that injection point was removed in favour of
1541
+ # the session cookie, and an injected copy would miss the StaticFiles fallback that serves the shell
1542
+ # for deep links, silently re-enabling the popup the operator suppressed. The command palette's
1543
+ # "What's new" action still opens it on request -- the flag governs what appears uninvited.
1544
+ ```