keboola-cli 0.64.0__tar.gz → 0.65.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 (380) hide show
  1. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/CLAUDE.md +15 -1
  2. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/PKG-INFO +1 -1
  3. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/pyproject.toml +1 -1
  4. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/changelog.py +42 -0
  5. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_data_app_git.py +67 -0
  6. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/context.py +25 -1
  7. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/data_app.py +100 -1
  8. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/data_science_client.py +39 -0
  9. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/permissions.py +2 -0
  10. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/data_apps.py +57 -1
  11. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/data_app_service.py +468 -59
  12. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_cli.py +185 -0
  13. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_git_repo.py +52 -0
  14. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_service.py +300 -0
  15. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_e2e.py +131 -0
  16. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_server_router_calls.py +59 -0
  17. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/.gitignore +0 -0
  18. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/CONTRIBUTING.md +0 -0
  19. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/Makefile +0 -0
  20. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/README.md +0 -0
  21. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/examples/README.md +0 -0
  22. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/examples/storage_tui/README.md +0 -0
  23. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
  24. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/benchmark.py +0 -0
  25. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/check_command_sync.py +0 -0
  26. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/check_error_codes.py +0 -0
  27. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/check_wheel_ui.py +0 -0
  28. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/debug_linkedby_type.sh +0 -0
  29. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/generate_changelog.py +0 -0
  30. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/generate_skill.py +0 -0
  31. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/hatch_build.py +0 -0
  32. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/lineage_deep.py +0 -0
  33. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/post-edit-quality.sh +0 -0
  34. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/pre-commit +0 -0
  35. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/sync_version.py +0 -0
  36. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/web-dev.sh +0 -0
  37. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/__init__.py +0 -0
  38. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/__main__.py +0 -0
  39. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/ai_client.py +0 -0
  40. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/auto_update.py +0 -0
  41. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/cli.py +0 -0
  42. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/client.py +0 -0
  43. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
  44. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
  45. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_helpers.py +0 -0
  46. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
  47. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
  48. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
  49. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
  50. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/agent.py +0 -0
  51. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/branch.py +0 -0
  52. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/changelog.py +0 -0
  53. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/component.py +0 -0
  54. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/config.py +0 -0
  55. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
  56. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
  57. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
  58. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/feature.py +0 -0
  59. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/flow.py +0 -0
  60. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
  61. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/init.py +0 -0
  62. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/job.py +0 -0
  63. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/kai.py +0 -0
  64. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/lineage.py +0 -0
  65. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/org.py +0 -0
  66. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/permissions.py +0 -0
  67. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/project.py +0 -0
  68. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/repl.py +0 -0
  69. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/schedule.py +0 -0
  70. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/search.py +0 -0
  71. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
  72. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/serve.py +0 -0
  73. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
  74. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/storage.py +0 -0
  75. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/stream.py +0 -0
  76. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/sync.py +0 -0
  77. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/tool.py +0 -0
  78. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/version.py +0 -0
  79. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/workspace.py +0 -0
  80. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/config_store.py +0 -0
  81. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/constants.py +0 -0
  82. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
  83. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/errors.py +0 -0
  84. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/http_base.py +0 -0
  85. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/json_utils.py +0 -0
  86. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/lib.py +0 -0
  87. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/manage_client.py +0 -0
  88. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/metastore_client.py +0 -0
  89. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/models.py +0 -0
  90. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/output.py +0 -0
  91. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/py.typed +0 -0
  92. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/result_models.py +0 -0
  93. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/__init__.py +0 -0
  94. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
  95. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
  96. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/app.py +0 -0
  97. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/auth.py +0 -0
  98. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/dependencies.py +0 -0
  99. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/pricing.py +0 -0
  100. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
  101. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
  102. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
  103. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
  104. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
  105. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/configs.py +0 -0
  106. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
  107. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
  108. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
  109. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
  110. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
  111. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
  112. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
  113. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
  114. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/mcp.py +0 -0
  115. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
  116. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
  117. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/projects.py +0 -0
  118. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
  119. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
  120. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
  121. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
  122. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/storage.py +0 -0
  123. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
  124. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
  125. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
  126. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/sse.py +0 -0
  127. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/__init__.py +0 -0
  128. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_encryption.py +0 -0
  129. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
  130. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
  131. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
  132. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
  133. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
  134. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
  135. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
  136. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
  137. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
  138. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_models.py +0 -0
  139. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
  140. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
  141. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
  142. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
  143. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/base.py +0 -0
  144. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/branch_service.py +0 -0
  145. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/component_service.py +0 -0
  146. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/config_service.py +0 -0
  147. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
  148. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
  149. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
  150. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
  151. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
  152. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/feature_service.py +0 -0
  153. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/flow_service.py +0 -0
  154. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
  155. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
  156. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
  157. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/job_service.py +0 -0
  158. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
  159. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
  160. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/mcp_service.py +0 -0
  161. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/mcp_transport.py +0 -0
  162. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/member_service.py +0 -0
  163. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/org_service.py +0 -0
  164. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/project_service.py +0 -0
  165. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
  166. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/schedule_service.py +0 -0
  167. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/search_service.py +0 -0
  168. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
  169. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
  170. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/storage_service.py +0 -0
  171. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
  172. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/sync_service.py +0 -0
  173. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
  174. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/version_service.py +0 -0
  175. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/workspace_service.py +0 -0
  176. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/stream_client.py +0 -0
  177. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
  178. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
  179. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/clone.py +0 -0
  180. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
  181. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/config_format.py +0 -0
  182. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
  183. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
  184. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/manifest.py +0 -0
  185. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/naming.py +0 -0
  186. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
  187. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
  188. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/__init__.py +0 -0
  189. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/conftest.py +0 -0
  190. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/helpers.py +0 -0
  191. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_cli.py +0 -0
  192. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_prompt.py +0 -0
  193. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_prompt_helper.py +0 -0
  194. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_runner.py +0 -0
  195. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_service.py +0 -0
  196. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agents_store_events.py +0 -0
  197. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_ai_client.py +0 -0
  198. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_auto_update.py +0 -0
  199. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_base_service.py +0 -0
  200. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_branch_metadata_cli.py +0 -0
  201. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_branch_metadata_service.py +0 -0
  202. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_branch_service.py +0 -0
  203. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_build_hook.py +0 -0
  204. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_changelog_check.py +0 -0
  205. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_changelog_render.py +0 -0
  206. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_check_command_sync.py +0 -0
  207. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_choice_enums.py +0 -0
  208. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_cli.py +0 -0
  209. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_client.py +0 -0
  210. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_component_cli.py +0 -0
  211. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_component_service.py +0 -0
  212. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_create_cli.py +0 -0
  213. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_create_service.py +0 -0
  214. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_encryption.py +0 -0
  215. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_metadata.py +0 -0
  216. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_rename.py +0 -0
  217. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_rename_cli.py +0 -0
  218. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_resolution.py +0 -0
  219. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_row_cli.py +0 -0
  220. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_row_service.py +0 -0
  221. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_search.py +0 -0
  222. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_search_cli.py +0 -0
  223. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_set_default_bucket.py +0 -0
  224. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_store.py +0 -0
  225. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_update.py +0 -0
  226. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_plain_env_keys.py +0 -0
  227. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_secrets_cli.py +0 -0
  228. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_secrets_service.py +0 -0
  229. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_validate_repo_service.py +0 -0
  230. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_deep_lineage_service.py +0 -0
  231. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_dev_portal_cli.py +0 -0
  232. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_dev_portal_client.py +0 -0
  233. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_dev_portal_service.py +0 -0
  234. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_doctor_service.py +0 -0
  235. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_e2e_config_dir_mode.py +0 -0
  236. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_e2e_lineage_deep.py +0 -0
  237. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_encrypt_cli.py +0 -0
  238. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_encrypt_service.py +0 -0
  239. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_encryption.py +0 -0
  240. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_errors.py +0 -0
  241. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_feature_cli.py +0 -0
  242. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_feature_service.py +0 -0
  243. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_file_locking.py +0 -0
  244. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_flow_cli.py +0 -0
  245. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_flow_service.py +0 -0
  246. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_flow_validation.py +0 -0
  247. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_helpers.py +0 -0
  248. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_http_base.py +0 -0
  249. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_http_client_cmd.py +0 -0
  250. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_http_forwarder_service.py +0 -0
  251. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_integration.py +0 -0
  252. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_job_idempotency_store.py +0 -0
  253. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_json_utils.py +0 -0
  254. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_kai_cli.py +0 -0
  255. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_kai_service.py +0 -0
  256. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_lib.py +0 -0
  257. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_lineage_service.py +0 -0
  258. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_local_ai_chat.py +0 -0
  259. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_manage_client.py +0 -0
  260. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_manage_token_bulk.py +0 -0
  261. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_manage_token_cli.py +0 -0
  262. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_mcp_service.py +0 -0
  263. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_mcp_transport.py +0 -0
  264. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_member_cli.py +0 -0
  265. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_member_service.py +0 -0
  266. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_metastore_client.py +0 -0
  267. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_models.py +0 -0
  268. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_normalize_script.py +0 -0
  269. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_org_service.py +0 -0
  270. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_output.py +0 -0
  271. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_permissions.py +0 -0
  272. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_permissions_cli.py +0 -0
  273. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_pricing.py +0 -0
  274. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_edit.py +0 -0
  275. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_edit_cli.py +0 -0
  276. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_info_cli.py +0 -0
  277. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_info_service.py +0 -0
  278. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_repl.py +0 -0
  279. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_result_models.py +0 -0
  280. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_run_broadcaster.py +0 -0
  281. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_schedule_cli.py +0 -0
  282. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_schedule_service.py +0 -0
  283. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_search_cli.py +0 -0
  284. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_search_service.py +0 -0
  285. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_semantic_layer_cli.py +0 -0
  286. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_semantic_layer_service.py +0 -0
  287. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_serve_conversation_id.py +0 -0
  288. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_serve_ui.py +0 -0
  289. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
  290. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_server_smoke.py +0 -0
  291. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_services.py +0 -0
  292. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sharing_service.py +0 -0
  293. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sql_split.py +0 -0
  294. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_clone.py +0 -0
  295. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_delete.py +0 -0
  296. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_describe_cli.py +0 -0
  297. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_describe_service.py +0 -0
  298. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_empty_definition.py +0 -0
  299. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_export_filters.py +0 -0
  300. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_files.py +0 -0
  301. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_swap.py +0 -0
  302. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_tables.py +0 -0
  303. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_truncate.py +0 -0
  304. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_write.py +0 -0
  305. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_stream_cli.py +0 -0
  306. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_stream_client.py +0 -0
  307. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_stream_service.py +0 -0
  308. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_branch_mapping.py +0 -0
  309. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_cli.py +0 -0
  310. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_clone.py +0 -0
  311. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_code_extraction.py +0 -0
  312. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_config_format.py +0 -0
  313. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_diff_engine.py +0 -0
  314. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_e2e.py +0 -0
  315. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_encrypt.py +0 -0
  316. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_force_pull_baseline.py +0 -0
  317. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_manifest.py +0 -0
  318. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_naming.py +0 -0
  319. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_plaintext_audit.py +0 -0
  320. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_secrets.py +0 -0
  321. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_service.py +0 -0
  322. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_storage_jobs.py +0 -0
  323. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_version_script.py +0 -0
  324. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_variables_cli.py +0 -0
  325. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_variables_service.py +0 -0
  326. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_version_service.py +0 -0
  327. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_cli.py +0 -0
  328. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_gc.py +0 -0
  329. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_service.py +0 -0
  330. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_sql_helper.py +0 -0
  331. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/README.md +0 -0
  332. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/index.html +0 -0
  333. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/package-lock.json +0 -0
  334. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/package.json +0 -0
  335. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/postcss.config.js +0 -0
  336. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/App.tsx +0 -0
  337. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/api/client.ts +0 -0
  338. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
  339. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/Drawer.tsx +0 -0
  340. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/Empty.tsx +0 -0
  341. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/JsonView.tsx +0 -0
  342. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
  343. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/Table.tsx +0 -0
  344. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/index.css +0 -0
  345. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/Shell.tsx +0 -0
  346. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
  347. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
  348. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/TopBar.tsx +0 -0
  349. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/main.tsx +0 -0
  350. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Agents.tsx +0 -0
  351. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Branches.tsx +0 -0
  352. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Changelog.tsx +0 -0
  353. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Components.tsx +0 -0
  354. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Configs.tsx +0 -0
  355. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
  356. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/DataApps.tsx +0 -0
  357. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Doctor.tsx +0 -0
  358. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
  359. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Flows.tsx +0 -0
  360. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Jobs.tsx +0 -0
  361. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Lineage.tsx +0 -0
  362. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
  363. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Mcp.tsx +0 -0
  364. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Members.tsx +0 -0
  365. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Org.tsx +0 -0
  366. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Projects.tsx +0 -0
  367. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Schedules.tsx +0 -0
  368. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Search.tsx +0 -0
  369. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
  370. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
  371. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Sharing.tsx +0 -0
  372. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Storage.tsx +0 -0
  373. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Streams.tsx +0 -0
  374. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
  375. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/state.tsx +0 -0
  376. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/theme.tsx +0 -0
  377. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/types.ts +0 -0
  378. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/tailwind.config.ts +0 -0
  379. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/tsconfig.json +0 -0
  380. {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/vite.config.ts +0 -0
@@ -424,13 +424,26 @@ kbagent workspace from-transformation --project ALIAS --component-id ID --config
424
424
 
425
425
  kbagent data-app list [--project NAME ...] [--branch ID]
426
426
  kbagent data-app detail --project NAME --app-id ID [--branch ID]
427
- kbagent data-app create --project ALIAS --name NAME --slug SLUG --git-repo URL [--description STR | --description-file PATH] [--git-branch main] [--git-public/--no-git-public] [--git-username USER] [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...] [--auth password|public] [--size tiny|small|medium|large] [--auto-suspend SECONDS] [--type python-js|python|streamlit|r|...] [--branch ID] [--no-deploy] [--wait] [--timeout SECONDS] [--keep-on-failure] [--dry-run]
427
+ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL | --use-managed-git-repo) [--description STR | --description-file PATH] [--git-branch main] [--git-public/--no-git-public] [--git-username USER] [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...] [--auth password|public] [--size tiny|small|medium|large] [--auto-suspend SECONDS] [--type python-js|python|streamlit|r|...] [--branch ID] [--no-deploy] [--wait] [--timeout SECONDS] [--keep-on-failure] [--dry-run]
428
+ # Exactly one git source is required: --git-repo URL (external) OR --use-managed-git-repo (0.65.0+).
429
+ # --use-managed-git-repo provisions an EMPTY Keboola-hosted repo (POST useManagedGitRepo:true), writes
430
+ # NO parameters.dataApp.git block, and forces --no-deploy (nothing to run yet). Mutually exclusive with
431
+ # --git-repo and all --git-*/PAT auth flags. Full flow to a RUNNING managed-repo app (0.65.0+):
432
+ # (1) create --use-managed-git-repo -> (2) `git-credentials-create --type http_token --permissions
433
+ # readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app
434
+ # git-bind-credential` (mints an http_token ON the app, encrypts it under the project KMS, and writes
435
+ # parameters.dataApp.git so the runtime's `git clone` can authenticate -- required on stacks that do NOT
436
+ # inject managed-repo creds at deploy time) -> (4) `data-app deploy`. deploy pins the LATEST
437
+ # configVersion when a git block is present and omits it for a PURE managed repo (deploys from
438
+ # managedGitRepoId). Use `data-app runs` to debug a deploy that reverts to stopped (setup-phase
439
+ # failures, e.g. git-clone "could not read Username", produce no container logs).
428
440
  kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID]
429
441
  kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
430
442
  kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
431
443
  kbagent data-app delete --project NAME --app-id ID [--yes]
432
444
  kbagent data-app password --project NAME --app-id ID
433
445
  kbagent data-app logs --project NAME --app-id ID [--lines N] [--since ISO8601]
446
+ kbagent data-app runs --project NAME --app-id ID [--limit N]
434
447
  kbagent data-app secrets-set --project ALIAS --app-id ID --secret '#KEY=VALUE' [--secret ...] [--secrets-file PATH] [--branch ID] [--allow-plaintext-on-encrypt-failure] [--dry-run] [--no-hint-next]
435
448
  kbagent data-app secrets-list --project ALIAS --app-id ID [--branch ID] [--show-fingerprint]
436
449
  kbagent data-app secrets-get --project ALIAS --app-id ID --key 'KEY' [--branch ID] # '#' optional; plain values return their value, encrypted return metadata only
@@ -441,6 +454,7 @@ kbagent data-app git-branches --project NAME --app-id ID
441
454
  kbagent data-app git-entrypoints --project NAME --app-id ID
442
455
  kbagent data-app git-credentials --project NAME --app-id ID
443
456
  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]
457
+ kbagent data-app git-bind-credential --project NAME --app-id ID [--branch-name main] [--permissions readOnly|readWrite] [--dry-run]
444
458
  # git-repo/git-branches/git-entrypoints introspect the deployed-from git repo (sandboxes-service /apps/{id}/git-repo/*); they return 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.
445
459
 
446
460
  kbagent component list [--project NAME] [--type TYPE] [--query QUERY]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: keboola-cli
3
- Version: 0.64.0
3
+ Version: 0.65.0
4
4
  Summary: AI-friendly CLI for managing Keboola projects
5
5
  Author-email: Keboola <dev@keboola.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "keboola-cli"
3
- version = "0.64.0"
3
+ version = "0.65.0"
4
4
  description = "AI-friendly CLI for managing Keboola projects"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -24,6 +24,48 @@ from .constants import CHANGELOG_HEADLINE_MAX_CHARS
24
24
 
25
25
  # Ordered newest-first. Each value is a list of brief one-line descriptions.
26
26
  CHANGELOG: dict[str, list[str]] = {
27
+ "0.65.0": [
28
+ "New: deploy a data app from a Keboola-MANAGED git repository end-to-end. "
29
+ "`data-app create --use-managed-git-repo` provisions an EMPTY Keboola-hosted repo (POST "
30
+ "`useManagedGitRepo:true`, no `parameters.dataApp.git` block, forces `--no-deploy`; "
31
+ "mutually exclusive with `--git-repo` and every `--git-*`/PAT flag). The full flow to a "
32
+ "running app: create -> `git-credentials-create --type http_token --permissions readWrite` "
33
+ "+ `git push` to the managed URL -> `data-app git-bind-credential` -> `data-app deploy`. "
34
+ "Verified live (tic-tac-toe serving from a managed repo).",
35
+ "New: `data-app git-bind-credential --project P --app-id ID [--branch-name main] "
36
+ "[--permissions readOnly|readWrite]` mints an `http_token` ON the app, encrypts it under "
37
+ "the project KMS, and writes `parameters.dataApp.git` (repository + placeholder username + "
38
+ "encrypted `#password` + branch). Required on stacks that do not inject managed-repo "
39
+ "credentials at deploy time -- without it the runtime's `git clone` of the managed repo "
40
+ "fails `could not read Username` and the deploy reverts to stopped. The token is encrypted "
41
+ "in place and never printed; `--dry-run` previews what would be wired without minting the "
42
+ "one-time credential or touching the config.",
43
+ "New: `data-app runs --project P --app-id ID [--limit N]` lists a data app's recent "
44
+ "deployment attempts with `failure_reason` + `startup_logs`, including setup-phase failures "
45
+ "(e.g. a git-clone error during `app_setup`) that produce no container logs. It works on "
46
+ "never-started / failed apps where `data-app logs` returns HTTP 400 -- the canonical way to "
47
+ "find out why a deploy reverted to `stopped` without the app ever serving.",
48
+ "Fix: `data-app deploy` now resolves the deployed `configVersion` by source location -- it "
49
+ "pins the latest Storage version when a git block is present (external repos AND a "
50
+ "credential-wired managed repo) so the operator reads the current source, and omits "
51
+ "`configVersion` only for a pure managed repo (deploys from `app.managedGitRepoId`). "
52
+ "Previously it always pinned, which pointed managed-repo deploys at a config snapshot with "
53
+ "no git source and made them silently revert to stopped.",
54
+ "UX: when `data-app deploy --wait` times out or the app reaches state=error, the error now "
55
+ "auto-fetches the latest run's `failure_reason` (via /apps/{id}/runs) and includes it inline "
56
+ '-- including setup-phase failures with no container logs -- instead of a bare "timed out" '
57
+ "message. A managed-repo clone-auth failure (`could not read Username`) adds an actionable "
58
+ "hint to run `data-app git-bind-credential`. The diagnostic is best-effort and never masks "
59
+ "the original error.",
60
+ "All of the above are mirrored 1:1 on the `kbagent serve` REST API "
61
+ "(`/data-app/.../runs`, `/data-app/.../git-repo/bind-credential`, and the "
62
+ "`use_managed_git_repo` field on create).",
63
+ "New (#446): the `install.sh` bootstrap got a first-run onboarding pass -- it "
64
+ "auto-installs `uv` when it is missing (opt out with `KBAGENT_NO_UV_BOOTSTRAP=1`), quiets "
65
+ "the install output behind tidy step lines, and finishes with a Keboola banner plus a "
66
+ "'next steps' footer (`kbagent project add`, `kbagent --help`) so first-time users know "
67
+ "what to run next.",
68
+ ],
27
69
  "0.64.0": [
28
70
  "New: data-app git-repo introspection + managed-repo credentials -- five `data-app "
29
71
  "git-*` commands over the sandboxes-service `/apps/{id}/git-repo/*` endpoints. "
@@ -341,3 +341,70 @@ def register_git_commands(app: typer.Typer) -> None:
341
341
  )
342
342
 
343
343
  formatter.output(result, _human)
344
+
345
+ @app.command("git-bind-credential")
346
+ def data_app_git_bind_credential(
347
+ ctx: typer.Context,
348
+ project: str = typer.Option(..., "--project", help="Project alias"),
349
+ app_id: str = typer.Option(..., "--app-id", help="Data Science numeric app id"),
350
+ branch: str = typer.Option(
351
+ "main", "--branch-name", help="Managed-repo branch to deploy from (default main)."
352
+ ),
353
+ permissions: str = typer.Option(
354
+ "readOnly",
355
+ "--permissions",
356
+ help="Credential access level: readOnly (default) | readWrite.",
357
+ ),
358
+ dry_run: bool = typer.Option(
359
+ False,
360
+ "--dry-run",
361
+ help="Preview what would be wired (repo/branch/permissions) WITHOUT minting a credential or editing the config.",
362
+ ),
363
+ ) -> None:
364
+ """Make a MANAGED-repo app deployable by wiring a credential into its config.
365
+
366
+ A `--use-managed-git-repo` app owns an empty Keboola-hosted repo but its
367
+ Storage config has no git block. On stacks that do NOT inject managed-repo
368
+ credentials at deploy time, the runtime's `git clone` of the managed repo
369
+ fails ("could not read Username") and the deploy reverts to stopped. This
370
+ command mints a fresh `http_token` ON the app, encrypts it under the
371
+ project KMS, and writes `parameters.dataApp.git` (repository + placeholder
372
+ username + encrypted `#password` + branch) so the next `data-app deploy`
373
+ can clone. The token is encrypted in-place and never printed.
374
+
375
+ `--dry-run` validates the app + resolves the managed repo URL but mints
376
+ nothing and leaves the config untouched -- the http_token is one-time, so
377
+ a real run that you abort would orphan it.
378
+ """
379
+ formatter = get_formatter(ctx)
380
+ service = get_service(ctx, "data_app_service")
381
+ try:
382
+ result = service.bind_managed_credential(
383
+ project, app_id, branch=branch, permissions=permissions, dry_run=dry_run
384
+ )
385
+ except KeboolaApiError as exc:
386
+ formatter.error(
387
+ message=exc.message,
388
+ error_code=exc.error_code,
389
+ retryable=exc.retryable,
390
+ details=exc.details,
391
+ )
392
+ raise typer.Exit(code=map_error_to_exit_code(exc)) from None
393
+ except ConfigError as exc:
394
+ formatter.error(message=exc.message, error_code=ErrorCode.CONFIG_ERROR)
395
+ raise typer.Exit(code=5) from None
396
+
397
+ def _human(c: Console, d: dict) -> None:
398
+ if d.get("dry_run"):
399
+ c.print("[bold]DRY RUN -- no credential minted, config unchanged.[/bold]")
400
+ c.print(f" [bold]Repository:[/bold] {d.get('repository', '')}")
401
+ c.print(f" [bold]Branch:[/bold] {d.get('branch', '')}")
402
+ c.print(f" [bold]Permissions:[/bold] {d.get('permissions', '')}")
403
+ return
404
+ c.print(f"[bold green]Success:[/bold green] {d['message']}")
405
+ c.print(f" [bold]Repository:[/bold] {d.get('repository', '')}")
406
+ c.print(f" [bold]Branch:[/bold] {d.get('branch', '')}")
407
+ c.print(f" [bold]Permissions:[/bold] {d.get('permissions', '')}")
408
+ c.print(f" [bold]Config version:[/bold] {d.get('config_version', '')}")
409
+
410
+ formatter.output(result, _human)
@@ -727,7 +727,8 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
727
727
  Full merged view: state, desiredState, url, deployed configVersion, slug,
728
728
  runtime size, git settings (PAT redacted as <encrypted>).
729
729
 
730
- kbagent data-app create --project ALIAS --name NAME --slug SLUG --git-repo URL
730
+ kbagent data-app create --project ALIAS --name NAME --slug SLUG
731
+ (--git-repo URL | --use-managed-git-repo)
731
732
  [--description STR | --description-file PATH] [--git-branch main]
732
733
  [--git-public/--no-git-public] [--git-username USER]
733
734
  [--git-pat-env VAR | --git-pat-file PATH | --git-pat-encrypted KBC::Project...]
@@ -740,6 +741,13 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
740
741
  Pre-encrypted PATs MUST start with KBC::Project (project-scoped KMS).
741
742
  Cleanup-in-finally if PUT or initial deploy fails (orphan shell deleted
742
743
  by default; --keep-on-failure preserves it for forensics).
744
+ --use-managed-git-repo (0.65.0+) provisions an EMPTY Keboola-hosted repo
745
+ instead of cloning an external one; writes no git block, forces --no-deploy,
746
+ mutually exclusive with --git-repo and all --git-*/PAT flags. Managed deploy
747
+ works via: create --use-managed-git-repo -> git-credentials-create
748
+ --type http_token + push code to the managed repo URL ->
749
+ `data-app git-bind-credential` (wires an encrypted credential into the
750
+ config) -> deploy.
743
751
 
744
752
  kbagent data-app deploy --project NAME --app-id ID [--config-version N]
745
753
  [--wait] [--timeout SECONDS] [--branch ID]
@@ -783,6 +791,13 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
783
791
  the app printed to stdout/stderr -- consider hygiene before piping
784
792
  --json output into AI agent context.
785
793
 
794
+ kbagent data-app runs --project NAME --app-id ID [--limit N]
795
+ List deployment attempts (runs) newest-first with failure_reason +
796
+ startup_logs, including setup-phase failures (e.g. git-clone errors)
797
+ that produce no container logs. Works on never-started/failed apps
798
+ where 'data-app logs' returns HTTP 400 -- the canonical way to find
799
+ WHY a deploy reverted to stopped. Project storage token only.
800
+
786
801
  kbagent data-app secrets-set --project ALIAS --app-id ID --secret '#KEY=VALUE'
787
802
  [--secret '#KEY2=VALUE2' ...] [--secrets-file PATH] [--branch ID]
788
803
  [--allow-plaintext-on-encrypt-failure] [--dry-run] [--no-hint-next]
@@ -866,6 +881,15 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
866
881
  are EXTERNAL (not managed) -> 409 "no managed Git repository".
867
882
  Confirmation prompt unless --yes or --json.
868
883
 
884
+ kbagent data-app git-bind-credential --project NAME --app-id ID
885
+ [--branch-name main] [--permissions readOnly|readWrite] [--dry-run]
886
+ Mint an http_token ON the app's MANAGED repo, encrypt it under the
887
+ project KMS, and wire it into parameters.dataApp.git (repository +
888
+ placeholder username + encrypted #password + branch) so the runtime can
889
+ `git clone` the managed repo at deploy time. Needed on stacks that do
890
+ NOT inject managed-repo credentials at deploy (clone fails with "could
891
+ not read Username"). The token is encrypted in-place and never printed.
892
+
869
893
  ### Project Sync
870
894
 
871
895
  kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing]
@@ -211,7 +211,24 @@ def data_app_create(
211
211
  slug: str = typer.Option(
212
212
  ..., "--slug", help="URL slug (lowercase alphanumeric, hyphens; 2-64 chars)"
213
213
  ),
214
- git_repo: str = typer.Option(..., "--git-repo", help="GitHub repository URL"),
214
+ git_repo: str = typer.Option(
215
+ "",
216
+ "--git-repo",
217
+ help=(
218
+ "External git repository URL to deploy from. Required unless "
219
+ "--use-managed-git-repo is set (mutually exclusive with it)."
220
+ ),
221
+ ),
222
+ use_managed_git_repo: bool = typer.Option(
223
+ False,
224
+ "--use-managed-git-repo",
225
+ help=(
226
+ "Provision an empty Keboola-managed git repository for the app "
227
+ "instead of cloning an external one. Mints code via "
228
+ "`data-app git-credentials-create`, then push + deploy. "
229
+ "Mutually exclusive with --git-repo and all --git-* auth flags."
230
+ ),
231
+ ),
215
232
  git_branch: str = typer.Option("main", "--git-branch", help="Git branch to clone"),
216
233
  git_public: bool = typer.Option(
217
234
  False,
@@ -310,6 +327,23 @@ def data_app_create(
310
327
  )
311
328
  raise typer.Exit(code=2) from None
312
329
 
330
+ # Source-of-code selection: exactly one of an external --git-repo or a
331
+ # Keboola --use-managed-git-repo. Catch the two obvious mistakes at the CLI
332
+ # boundary with a clean usage error (the service re-checks the full flag
333
+ # matrix defensively for non-CLI callers).
334
+ if use_managed_git_repo and git_repo:
335
+ formatter.error(
336
+ message="--use-managed-git-repo is mutually exclusive with --git-repo.",
337
+ error_code=ErrorCode.USAGE_ERROR,
338
+ )
339
+ raise typer.Exit(code=2)
340
+ if not use_managed_git_repo and not git_repo:
341
+ formatter.error(
342
+ message="One of --git-repo or --use-managed-git-repo is required.",
343
+ error_code=ErrorCode.USAGE_ERROR,
344
+ )
345
+ raise typer.Exit(code=2)
346
+
313
347
  # Mutual exclusion of git PAT input modes (CLI layer).
314
348
  pat_inputs_set = sum(1 for v in (git_pat_env, git_pat_file, git_pat_encrypted) if v is not None)
315
349
  if pat_inputs_set > 1:
@@ -342,6 +376,7 @@ def data_app_create(
342
376
  git_username=git_username,
343
377
  git_pat_plaintext=pat_plaintext,
344
378
  git_pat_encrypted=git_pat_encrypted,
379
+ use_managed_git_repo=use_managed_git_repo,
345
380
  auth=auth,
346
381
  size=size,
347
382
  auto_suspend_after_seconds=auto_suspend,
@@ -377,6 +412,9 @@ def data_app_create(
377
412
  )
378
413
  formatter.console.print(f" [bold]App ID:[/bold] {result['app_id']}")
379
414
  formatter.console.print(f" [bold]Config ID:[/bold] {result['config_id']}")
415
+ if result.get("use_managed_git_repo"):
416
+ repo_id = result.get("managed_git_repo_id") or "(provisioning)"
417
+ formatter.console.print(f" [bold]Managed git repo:[/bold] {repo_id}")
380
418
  if result.get("url"):
381
419
  formatter.console.print(f" [bold]URL:[/bold] {result['url']}")
382
420
  formatter.console.print(
@@ -726,6 +764,67 @@ def data_app_logs(
726
764
  formatter.output(result, _print_logs)
727
765
 
728
766
 
767
+ @data_app_app.command("runs")
768
+ def data_app_runs(
769
+ ctx: typer.Context,
770
+ project: str = typer.Option(..., "--project", help="Project alias"),
771
+ app_id: str = typer.Option(..., "--app-id", help="Data Science numeric app id"),
772
+ limit: int = typer.Option(5, "--limit", help="Max runs to return (newest first)."),
773
+ ) -> None:
774
+ """List a data app's recent deployment attempts (runs), newest first.
775
+
776
+ Unlike ``data-app logs`` (which needs a running container), ``runs`` works on
777
+ never-started / failed apps and surfaces the ``failure_reason`` +
778
+ ``startup_logs`` the platform records for each attempt -- including
779
+ setup-phase failures (e.g. a git-clone error during ``app_setup``) that
780
+ produce no container logs. This is the way to find out *why* a deploy
781
+ reverted to ``stopped`` without the app ever serving.
782
+
783
+ Auth: project Storage token only.
784
+ """
785
+ formatter = get_formatter(ctx)
786
+ service = get_service(ctx, "data_app_service")
787
+ try:
788
+ result = service.list_app_runs(project, app_id, limit=limit)
789
+ except KeboolaApiError as exc:
790
+ formatter.error(
791
+ message=exc.message,
792
+ error_code=exc.error_code,
793
+ retryable=exc.retryable,
794
+ details=exc.details,
795
+ )
796
+ raise typer.Exit(code=map_error_to_exit_code(exc)) from None
797
+ except ConfigError as exc:
798
+ formatter.error(message=exc.message, error_code=ErrorCode.CONFIG_ERROR)
799
+ raise typer.Exit(code=5) from None
800
+
801
+ def _human(c: Console, d: dict) -> None:
802
+ runs = d.get("runs", [])
803
+ if not runs:
804
+ c.print("[dim]No runs found.[/dim]")
805
+ return
806
+ c.print(
807
+ f"\n[bold]{d['count']} run(s)[/bold] for data app "
808
+ f"[cyan]{escape(str(d['app_id']))}[/cyan] in "
809
+ f"[magenta]{escape(d['project_alias'])}[/magenta]"
810
+ )
811
+ for r in runs:
812
+ state = r.get("state", "")
813
+ color = "green" if state in ("running", "finished") else "red"
814
+ c.print(
815
+ f" [{color}]{state}[/{color}] {r.get('id', '')} (created {r.get('created_at')})"
816
+ )
817
+ fr = r.get("failure_reason")
818
+ if fr:
819
+ reason = fr.get("reason", "") if isinstance(fr, dict) else str(fr)
820
+ message = fr.get("message", "") if isinstance(fr, dict) else ""
821
+ c.print(f" [red]reason:[/red] {escape(reason)}")
822
+ if message:
823
+ c.print(f" [dim]{escape(message)}[/dim]", markup=True, highlight=False)
824
+
825
+ formatter.output(result, _human)
826
+
827
+
729
828
  # ---------------------------------------------------------------------------
730
829
  # data-app validate-repo
731
830
  # ---------------------------------------------------------------------------
@@ -89,6 +89,26 @@ class DataScienceClient(BaseHttpClient):
89
89
  response = self._do_request("GET", f"/apps/{quote(str(app_id), safe='')}")
90
90
  return response.json()
91
91
 
92
+ def list_app_runs(
93
+ self, app_id: str, *, limit: int = 5, offset: int = 0
94
+ ) -> list[dict[str, Any]]:
95
+ """List deployment attempts (runs) of a data app, newest first.
96
+
97
+ Each run carries ``state`` (starting/running/finished/failed) plus a
98
+ ``failureReason`` and ``startupLogs`` for unsuccessful attempts --
99
+ including setup-phase failures (e.g. a clone/build error) that never
100
+ produce container logs and so are invisible to ``/apps/{id}/logs/tail``.
101
+ This is the canonical way to find out *why* a deploy reverted to
102
+ ``stopped`` without the app ever serving.
103
+ """
104
+ response = self._do_request(
105
+ "GET",
106
+ f"/apps/{quote(str(app_id), safe='')}/runs",
107
+ params={"limit": limit, "offset": offset},
108
+ )
109
+ payload = response.json()
110
+ return payload if isinstance(payload, list) else payload.get("runs", [])
111
+
92
112
  def create_app(
93
113
  self,
94
114
  *,
@@ -97,6 +117,7 @@ class DataScienceClient(BaseHttpClient):
97
117
  description: str,
98
118
  config: dict[str, Any],
99
119
  branch_id: int | None = None,
120
+ use_managed_git_repo: bool = False,
100
121
  ) -> dict[str, Any]:
101
122
  """Create the deployment shell + linked Storage config in one call.
102
123
 
@@ -111,6 +132,14 @@ class DataScienceClient(BaseHttpClient):
111
132
  possible but the encryption step depends on knowing
112
133
  ``config_id`` first, so the canonical flow is:
113
134
  ``create_app`` -> encrypt secrets -> ``update_config``.
135
+
136
+ ``use_managed_git_repo`` -> POST ``useManagedGitRepo: true`` so the
137
+ sandboxes-service provisions a *managed* git repository on the Git
138
+ Service and links it to the app (``managedGitRepoId``). The repo
139
+ starts empty -- the caller mints a credential
140
+ (``create_git_credential``), pushes code, then deploys. Repo
141
+ creation failure aborts app creation server-side; the repo is
142
+ deleted when the app is deleted.
114
143
  """
115
144
  payload: dict[str, Any] = {
116
145
  "branchId": branch_id,
@@ -119,6 +148,8 @@ class DataScienceClient(BaseHttpClient):
119
148
  "description": description,
120
149
  "config": config,
121
150
  }
151
+ if use_managed_git_repo:
152
+ payload["useManagedGitRepo"] = True
122
153
  response = self._do_request(
123
154
  "POST",
124
155
  "/apps",
@@ -146,6 +177,14 @@ class DataScienceClient(BaseHttpClient):
146
177
  ``desired_state="running"`` + ``config_version=<N>``
147
178
  + ``restart_if_running=True`` together when bumping the deployed
148
179
  config version; sending ``config_version`` alone yields HTTP 422.
180
+
181
+ EXCEPTION (python-js managed repos): a *pure* managed-repo app
182
+ (``useManagedGitRepo``, no ``parameters.dataApp.git`` block) deploys its
183
+ source from ``app.managedGitRepoId``, not from a Storage configVersion,
184
+ so the caller passes ``config_version=None`` and this PATCH omits the
185
+ field entirely -- payload ``{desiredState, restartIfRunning}``. This
186
+ matches keboola-mcp-server / Kai behavior; see
187
+ ``DataAppService.deploy_data_app`` for the source-location branch.
149
188
  """
150
189
  payload: dict[str, Any] = {}
151
190
  if desired_state is not None:
@@ -154,6 +154,7 @@ OPERATION_REGISTRY: dict[str, str] = {
154
154
  "data-app.detail": "read",
155
155
  "data-app.password": "read",
156
156
  "data-app.logs": "read",
157
+ "data-app.runs": "read",
157
158
  "data-app.create": "write",
158
159
  "data-app.deploy": "write",
159
160
  "data-app.start": "write",
@@ -171,6 +172,7 @@ OPERATION_REGISTRY: dict[str, str] = {
171
172
  "data-app.git-entrypoints": "read",
172
173
  "data-app.git-credentials": "read",
173
174
  "data-app.git-credentials-create": "write",
175
+ "data-app.git-bind-credential": "write",
174
176
  # Developer Portal — identity sub-app leaves (composed by the
175
177
  # identity_app callback as "dev-portal.identity.<subcommand>")
176
178
  "dev-portal.identity.add": "write",
@@ -39,7 +39,10 @@ class DataAppCreate(BaseModel):
39
39
  name: str
40
40
  description: str = ""
41
41
  slug: str
42
- git_repo: str
42
+ # Exactly one git source: an external git_repo URL OR use_managed_git_repo.
43
+ # The service validates the mutex (and the rest of the flag matrix).
44
+ git_repo: str = ""
45
+ use_managed_git_repo: bool = False
43
46
  git_branch: str = "main"
44
47
  git_public: bool = False
45
48
  git_username: str | None = None
@@ -87,6 +90,13 @@ class GitCredentialCreate(BaseModel):
87
90
  name: str | None = None
88
91
 
89
92
 
93
+ class GitBindCredential(BaseModel):
94
+ branch: str = "main"
95
+ permissions: str = "readOnly"
96
+ branch_id: int | None = None
97
+ dry_run: bool = False
98
+
99
+
90
100
  @router.get("", summary="List data apps across projects")
91
101
  def list_apps(
92
102
  project: list[str] | None = Query(None),
@@ -124,6 +134,7 @@ def create(
124
134
  git_username=body.git_username,
125
135
  git_pat_plaintext=body.git_pat_plaintext,
126
136
  git_pat_encrypted=body.git_pat_encrypted,
137
+ use_managed_git_repo=body.use_managed_git_repo,
127
138
  auth=body.auth,
128
139
  size=body.size,
129
140
  auto_suspend_after_seconds=body.auto_suspend_after_seconds,
@@ -382,3 +393,48 @@ def git_credentials_create(
382
393
  public_key=body.public_key,
383
394
  name=body.name,
384
395
  )
396
+
397
+
398
+ @router.get("/{project}/{app_id}/runs", summary="List a data app's deployment attempts")
399
+ def runs(
400
+ project: str,
401
+ app_id: str,
402
+ limit: int = 5,
403
+ registry: ServiceRegistry = Depends(get_registry),
404
+ ) -> dict[str, Any]:
405
+ """List recent deployment attempts (runs) with failure reasons.
406
+
407
+ Mirrors `kbagent data-app runs`. Each run carries `failure_reason` +
408
+ `startup_logs`, including setup-phase failures (e.g. a git-clone error) that
409
+ produce no container logs; works on never-started / failed apps where the
410
+ logs endpoint returns HTTP 400.
411
+ """
412
+ return registry.data_app.list_app_runs(project, app_id, limit=limit)
413
+
414
+
415
+ @router.post(
416
+ "/{project}/{app_id}/git-repo/bind-credential",
417
+ summary="Wire a managed-repo credential into a data app's config",
418
+ )
419
+ def git_bind_credential(
420
+ project: str,
421
+ app_id: str,
422
+ body: GitBindCredential,
423
+ registry: ServiceRegistry = Depends(get_registry),
424
+ ) -> dict[str, Any]:
425
+ """Make a MANAGED-repo app deployable by wiring a credential into its config.
426
+
427
+ Mirrors `kbagent data-app git-bind-credential`. Mints an `http_token` on the
428
+ app, encrypts it under the project KMS, and writes `parameters.dataApp.git`
429
+ so the runtime can clone the managed repo at deploy. The token is encrypted
430
+ in place and never returned. Needs an admin storage token; non-managed apps
431
+ are rejected.
432
+ """
433
+ return registry.data_app.bind_managed_credential(
434
+ project,
435
+ app_id,
436
+ branch=body.branch,
437
+ permissions=body.permissions,
438
+ branch_id=body.branch_id,
439
+ dry_run=body.dry_run,
440
+ )