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.
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/CLAUDE.md +15 -1
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/PKG-INFO +1 -1
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/pyproject.toml +1 -1
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/changelog.py +42 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_data_app_git.py +67 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/context.py +25 -1
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/data_app.py +100 -1
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/data_science_client.py +39 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/permissions.py +2 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/data_apps.py +57 -1
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/data_app_service.py +468 -59
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_cli.py +185 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_git_repo.py +52 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_service.py +300 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_e2e.py +131 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_server_router_calls.py +59 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/.gitignore +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/CONTRIBUTING.md +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/Makefile +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/README.md +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/examples/README.md +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/examples/storage_tui/README.md +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/benchmark.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/check_command_sync.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/check_error_codes.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/check_wheel_ui.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/debug_linkedby_type.sh +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/generate_changelog.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/generate_skill.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/hatch_build.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/lineage_deep.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/post-edit-quality.sh +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/pre-commit +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/sync_version.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/scripts/web-dev.sh +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/__main__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/ai_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/auto_update.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_helpers.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/agent.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/branch.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/changelog.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/component.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/config.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/feature.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/flow.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/init.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/job.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/kai.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/lineage.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/org.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/permissions.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/project.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/repl.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/schedule.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/search.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/serve.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/storage.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/stream.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/sync.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/tool.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/version.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/commands/workspace.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/config_store.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/constants.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/errors.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/http_base.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/json_utils.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/lib.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/manage_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/metastore_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/models.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/output.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/py.typed +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/result_models.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/app.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/auth.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/dependencies.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/pricing.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/configs.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/mcp.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/projects.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/storage.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/server/sse.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_encryption.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_models.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/base.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/branch_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/component_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/config_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/feature_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/flow_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/job_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/mcp_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/mcp_transport.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/member_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/org_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/project_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/schedule_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/search_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/storage_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/sync_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/version_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/services/workspace_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/stream_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/clone.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/config_format.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/manifest.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/naming.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/__init__.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/conftest.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/helpers.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_prompt.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_prompt_helper.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_runner.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agent_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_agents_store_events.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_ai_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_auto_update.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_base_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_branch_metadata_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_branch_metadata_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_branch_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_build_hook.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_changelog_check.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_changelog_render.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_check_command_sync.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_choice_enums.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_component_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_component_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_create_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_create_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_encryption.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_metadata.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_rename.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_rename_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_resolution.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_row_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_row_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_search.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_search_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_set_default_bucket.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_store.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_config_update.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_plain_env_keys.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_secrets_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_secrets_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_data_app_validate_repo_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_deep_lineage_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_dev_portal_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_dev_portal_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_dev_portal_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_doctor_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_e2e_config_dir_mode.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_e2e_lineage_deep.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_encrypt_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_encrypt_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_encryption.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_errors.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_feature_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_feature_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_file_locking.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_flow_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_flow_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_flow_validation.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_helpers.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_http_base.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_http_client_cmd.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_http_forwarder_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_integration.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_job_idempotency_store.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_json_utils.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_kai_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_kai_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_lib.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_lineage_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_local_ai_chat.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_manage_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_manage_token_bulk.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_manage_token_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_mcp_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_mcp_transport.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_member_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_member_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_metastore_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_models.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_normalize_script.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_org_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_output.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_permissions.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_permissions_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_pricing.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_edit.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_edit_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_info_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_project_info_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_repl.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_result_models.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_run_broadcaster.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_schedule_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_schedule_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_search_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_search_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_semantic_layer_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_semantic_layer_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_serve_conversation_id.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_serve_ui.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_server_smoke.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_services.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sharing_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sql_split.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_clone.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_delete.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_describe_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_describe_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_empty_definition.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_export_filters.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_files.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_swap.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_tables.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_truncate.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_storage_write.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_stream_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_stream_client.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_stream_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_branch_mapping.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_clone.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_code_extraction.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_config_format.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_diff_engine.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_e2e.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_encrypt.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_force_pull_baseline.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_manifest.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_naming.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_plaintext_audit.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_secrets.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_storage_jobs.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_sync_version_script.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_variables_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_variables_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_version_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_cli.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_gc.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_service.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/tests/test_workspace_sql_helper.py +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/README.md +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/index.html +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/package-lock.json +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/package.json +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/postcss.config.js +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/App.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/api/client.ts +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/Drawer.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/Empty.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/JsonView.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/components/Table.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/index.css +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/Shell.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/layout/TopBar.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/main.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Agents.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Branches.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Changelog.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Components.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Configs.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/DataApps.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Doctor.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Flows.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Jobs.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Lineage.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Mcp.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Members.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Org.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Projects.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Schedules.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Search.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Sharing.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Storage.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Streams.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/state.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/theme.tsx +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/src/types.ts +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/tailwind.config.ts +0 -0
- {keboola_cli-0.64.0 → keboola_cli-0.65.0}/web/frontend/tsconfig.json +0 -0
- {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]
|
|
@@ -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
|
|
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(
|
|
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
|
-
|
|
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
|
+
)
|