keboola-cli 0.100.4__tar.gz → 1.0.0__tar.gz

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