keboola-cli 0.98.0__tar.gz → 0.99.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.98.0 → keboola_cli-0.99.0}/CLAUDE.md +70 -11
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/PKG-INFO +32 -6
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/README.md +31 -5
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/formal/sync/README.md +8 -8
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/pyproject.toml +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/file_size_baseline.json +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/auth_client.py +3 -3
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/environment.py +39 -6
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auto_update.py +54 -17
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/changelog.py +50 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/storage_tables.py +101 -37
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_config_oauth.py +60 -7
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_helpers.py +277 -9
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/config.py +10 -2
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/context.py +107 -27
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/data_app.py +10 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/lineage.py +6 -3
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/permissions.py +21 -6
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/project.py +58 -43
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/storage.py +37 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/token.py +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/workspace.py +19 -8
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/config_store.py +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/constants.py +24 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/data_science_client.py +4 -7
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/errors.py +21 -2
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/metastore_client.py +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/permissions.py +37 -5
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/_serve_command_map.py +1 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/app.py +44 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/dependencies.py +16 -0
- keboola_cli-0.99.0/src/keboola_agent_cli/server/route_permissions.py +532 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/data_apps.py +2 -0
- keboola_cli-0.99.0/src/keboola_agent_cli/server/routers/permissions.py +63 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/semantic_layer.py +96 -7
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/storage.py +8 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/workspaces.py +2 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_data_app_bodies.py +270 -5
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_encryption.py +15 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_storage_jobs.py +58 -12
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_baseline.py +44 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_push_ops.py +113 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_writeback.py +5 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/auth_service.py +22 -2
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/component_service.py +27 -6
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/config_service.py +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/data_app_service.py +28 -79
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/deep_lineage_service.py +2 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/storage_service.py +33 -4
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/sync_service.py +22 -41
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/token_service.py +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/version_service.py +12 -2
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/workspace_service.py +180 -55
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/branch_registry.py +26 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/config_format.py +7 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/diff_engine.py +18 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_environment.py +133 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_sentinel_guards.py +1 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_service.py +82 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auto_update.py +170 -16
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_registry.py +79 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_cli.py +129 -3
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_cli_auth.py +74 -4
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_component_service.py +40 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_create_cli.py +24 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_row_cli.py +219 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_cli.py +45 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_service.py +323 -6
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_deep_lineage_service.py +37 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e.py +16 -3
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_effective_branch.py +20 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_helpers.py +324 -2
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_permissions_cli.py +33 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_edit_cli.py +209 -2
- keboola_cli-0.99.0/tests/test_project_token_stdin_no_leak.py +289 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_telemetry.py +11 -1
- keboola_cli-0.99.0/tests/test_server_route_permissions.py +828 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_router_calls.py +126 -4
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_smoke.py +2 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_create_table.py +62 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_import_jobs.py +21 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_swap.py +315 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_write.py +200 -0
- keboola_cli-0.99.0/tests/test_sync_adopted_files.py +275 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_diff_engine.py +51 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_formal_counterexamples.py +23 -44
- keboola_cli-0.99.0/tests/test_sync_push_encrypt_first.py +261 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_reconcile.py +18 -12
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_service.py +10 -9
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_version_service.py +18 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_cli.py +51 -3
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_service.py +422 -10
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/package-lock.json +6 -6
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/package.json +2 -1
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/.gitignore +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/CONTRIBUTING.md +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/LICENSE +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/Makefile +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/examples/README.md +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/examples/storage_tui/README.md +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/plugins/kbagent/skills/kbagent-cicd-migration/scripts/migrate_cicd.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_command_sync.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_error_codes.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_file_size.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_release_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_sentinel_guards.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_version_gates.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/check_wheel_ui.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/debug_linkedby_type.sh +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/gen_command_reference.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/gen_endpoint_reference.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/gen_release_notes.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/generate_changelog.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/generate_skill.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/hatch_build.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/lineage_deep.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/post-edit-quality.sh +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/pre-commit +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/sync_version.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/scripts/web-dev.sh +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/__main__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/ai_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/device.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/pkce.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/sentinel.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/state_store.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/token_provider.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/auth/totp.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_core.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_s3_multipart.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/_transfer.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/billing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/branches.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/configs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/editor.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/merge_requests.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/misc.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/notifications.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/query.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/queue.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/storage_files.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/stream.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/tokens.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/triggers.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/client/workspaces.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_auth_picker.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_checkbox_select.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_config_clone_cmd.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_config_trash_cmd.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_data_app_password.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_flow_triggers.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_merge_request_common.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_merge_request_render.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_merge_request_writes.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_progress.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_project_create.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_project_ref.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_semantic_layer_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_describe.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_jobs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_table_detail.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_storage_tables_render.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_sync_clone_render.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_sync_push_render.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/_url_copy.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/agent.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/auth.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/billing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/branch.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/changelog.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/component.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/config_state.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/docs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/doctor.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/encrypt.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/feature.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/flow.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/http_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/init.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/job.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/kai.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/merge_request.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/notification.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/org.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/repl.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/schedule.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/search.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/serve.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/sharing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/stream.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/sync.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/transformation.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/commands/version.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/dev_portal_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/effective_branch.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/frozen_dist.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/http_base.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/json_utils.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/lib.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/manage_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/output.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/project_ref.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/py.typed +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/result_models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/scheduler_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/agent_runner.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/agents_store.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/auth.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/pricing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/agents.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/auth.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/billing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/branches.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/components.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/configs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/docs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/feature.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/flows.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/health.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/kai.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/members.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/merge_requests.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/notifications.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/org.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/projects.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/search.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/stream.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/token.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/server/sse.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_auth_registration.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_column_descriptions.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_config_clone.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_config_set_guard.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_config_trash.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_data_app_password.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_describe_batch_input.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_fqn.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_semantic_layer_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_storage_downloads.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_storage_tables.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_clone_warnings.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_data_app.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_stale.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_sync_workspace.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_table_detail.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_token_last_used.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/_workspace_load_plan.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/agent_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/base.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/billing_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/branch_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/docs_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/doctor_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/feature_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/flow_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/flow_validation.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/job_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/kai_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/lineage_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/member_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/merge_request_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/notification_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/org_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/project_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/schedule_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/search_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/sharing_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/stream_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/table_usage.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/transformation_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/services/variables_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/stream_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/branch_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/clone.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/git_utils.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/manifest.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/naming.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/secrets.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/sync/sql_split.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/telemetry.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/update_runner.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/src/keboola_agent_cli/yaml_input.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/__init__.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/conftest.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/helpers.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_prompt.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_prompt_helper.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_runner.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agent_tombstone.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_agents_store_events.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_ai_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_api_call_counts.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_device.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_picker.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_pkce.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_register_projects.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_sentinel.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_state_store.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_auth_totp.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_base_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_billing_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_billing_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_billing_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_metadata_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_metadata_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_branch_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_build_hook.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_changelog_check.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_changelog_render.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_command_sync.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_file_size.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_release_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_sentinel_guards.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_check_version_gates.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_checkbox_select.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_choice_enums.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_client_device_enrollment.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_client_token_events.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_component_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_component_sync_action.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_clone_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_clone_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_create_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_encryption.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_examples.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_metadata.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_rename.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_rename_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_resolution.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_row_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_search.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_search_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_set_default_bucket.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_set_guard.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_state.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_store.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_trash.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_config_update.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_git_repo.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_password.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_plain_env_keys.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_secrets_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_secrets_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_data_app_validate_repo_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_dev_portal_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_dev_portal_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_dev_portal_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_docs_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_doctor_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e_auth.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e_config_dir_mode.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_e2e_lineage_deep.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_encrypt_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_encrypt_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_encryption.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_errors.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_feature_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_feature_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_file_locking.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_examples.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_flow_validation.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_frozen_dist.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_gen_command_reference.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_gen_endpoint_reference.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_gen_release_notes.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_generate_promotion_pipeline.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_base.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_base_auth.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_client_cmd.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_http_forwarder_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_integration.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_job_idempotency_store.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_job_options.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_json_utils.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_kai_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_kai_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_lib.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_lib_device_enrollment.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_license_consistency.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_lineage_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_local_ai_chat.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_manage_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_manage_token_bulk.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_manage_token_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_mcp_migration_recipe.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_member_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_member_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_merge_request_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_merge_request_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_merge_request_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_metastore_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_migrate_cicd.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_normalize_script.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_notification_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_notification_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_notification_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_org_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_output.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_partial_failure_exit_code.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_permissions.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_pricing.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_create_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_edit.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_info_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_info_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_project_ref.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_release_kbagent_ai_kit_sync.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_repl.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_result_models.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_run_broadcaster.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_s3_multipart.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_schedule_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_schedule_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_scheduler_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_search_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_search_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_schema.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_scope_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_semantic_layer_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_banner_encoding.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_conversation_id.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_serve_ui.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_auth.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_permissions.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_project_ref.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_services.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sharing_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sharing_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_skill_frontmatter.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sql_split.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_clone.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_delete.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_describe_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_describe_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_empty_definition.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_export_filters.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_files.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_snapshots.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_table_definition.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_tables.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_storage_truncate.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_stream_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_stream_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_stream_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_baseline_stamping.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_branch_mapping.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_branch_scope.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_cli_behavior.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_clone.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_clone_links.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_code_extraction.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_config_format.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_data_app_type.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_e2e.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_encrypt.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_force_pull_baseline.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_manifest.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_naming.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_plaintext_audit.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_pull_companion_files.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_push_script_guard.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_secrets.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_storage_jobs.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_version_script.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_sync_workspaces.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_table_usage.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_telemetry.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_token_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_token_provider.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_token_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_transfer_progress.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_transformation_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_transformation_ops.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_triggers_client.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_update_runner.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_url_copy.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_variables_cli.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_variables_service.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_gc.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_workspace_sql_helper.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/tests/test_yaml_input.py +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/README.md +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/index.html +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/postcss.config.js +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/App.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/api/client.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/api/client.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/changelogNotes.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/changelogNotes.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/AgentRunView.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/CommandPalette.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/ConfirmModal.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/DetailTabs.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/Drawer.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/Empty.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/JsonView.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/KeyValueGrid.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/PillList.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/RawDetail.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/SessionExpiredBanner.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/Table.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/components/WhatsNew.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/config/credits.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/config/credits.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/index.css +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/Shell.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/Sidebar.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/StatusBar.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/layout/TopBar.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/lib/time.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/lib/time.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/main.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Agents.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Branches.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Changelog.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Components.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Configs.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Dashboard.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/DataApps.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Doctor.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Encrypt.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Flows.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Jobs.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/JobsAll.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Lineage.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/LocalAi.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Members.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Org.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Projects.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Schedules.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Search.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Sharing.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Storage.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Streams.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Tokens.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/TokensAll.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/Workspaces.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/jobsShared.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/storageSel.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/tokensShared.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/pages/tokensShared.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/router.test.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/router.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/state.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/theme.tsx +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/types.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/useHashSelection.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/src/whatsnew.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/tailwind.config.ts +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/tsconfig.json +0 -0
- {keboola_cli-0.98.0 → keboola_cli-0.99.0}/web/frontend/vite.config.ts +0 -0
|
@@ -467,7 +467,7 @@ kbagent auth register-projects [--stack URL|alias] [--all] [--project-id ID ...]
|
|
|
467
467
|
# bearer token, and revoking the session is a host-operator action, not a remote one. `/auth/*`
|
|
468
468
|
# is also the FIRST router to enforce the `permissions` policy: every route declares
|
|
469
469
|
# `Depends(require_permission(...))`, so a denial answers HTTP 403 `PERMISSION_DENIED` over REST
|
|
470
|
-
# exactly as on the CLI.
|
|
470
|
+
# exactly as on the CLI. Every other route is checked too since #655 (see `permissions` below).
|
|
471
471
|
# The policy comes from the config dir `serve` RESOLVES (its own `--config-dir`, then -- since
|
|
472
472
|
# 0.91.0, #679 -- an explicit root `kbagent --config-dir`, then KBAGENT_CONFIG_DIR, then the
|
|
473
473
|
# local/global chain) plus the session flags of the invocation. On 0.90.1 the root-level
|
|
@@ -479,7 +479,7 @@ kbagent auth register-projects [--stack URL|alias] [--all] [--project-id ID ...]
|
|
|
479
479
|
# the allow list. `kbagent --deny-writes serve` does NOT work: `serve` is admin-class and
|
|
480
480
|
# `--deny-writes` appends `cli:write`, which spans write+destructive+admin, so the CLI callback
|
|
481
481
|
# blocks the `serve` command itself (exit 6) and no server ever starts. `--deny-destructive`
|
|
482
|
-
# starts the server
|
|
482
|
+
# starts the server and blocks every destructive route (none of them under `/auth/*`).
|
|
483
483
|
# See docs/web-server.md.
|
|
484
484
|
|
|
485
485
|
kbagent project create --url URL [--project ALIAS] [--name NAME] [--backend snowflake|bigquery] [--sync-backend-init]
|
|
@@ -507,10 +507,10 @@ kbagent project create --url URL [--project ALIAS] [--name NAME] [--backend snow
|
|
|
507
507
|
# delivered and may have succeeded (retryable:false, message says not to repeat -- check
|
|
508
508
|
# `auth status`, whose stored session + claim link is the evidence). `--sync-backend-init`
|
|
509
509
|
# raises that call's read timeout to 300s, which can outlast an agent's foreground shell.
|
|
510
|
-
kbagent project add --project NAME --url URL --token TOKEN
|
|
510
|
+
kbagent project add --project NAME --url URL [--token-stdin | --token-file PATH [--keep-token-file] | --token-env NAME | --token TOKEN]
|
|
511
511
|
kbagent project list
|
|
512
512
|
kbagent project remove --project NAME
|
|
513
|
-
kbagent project edit --project NAME [--url URL] [--token TOKEN] [--new-alias NEW]
|
|
513
|
+
kbagent project edit --project NAME [--url URL] [--token-stdin | --token-file PATH [--keep-token-file] | --token-env NAME | --token TOKEN] [--new-alias NEW]
|
|
514
514
|
kbagent project status [--project NAME]
|
|
515
515
|
kbagent project refresh --project ALIAS [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
|
|
516
516
|
kbagent project refresh --all [--dry-run] [--force] [--yes] [--token-description DESC] [--token-expires-in N]
|
|
@@ -555,7 +555,10 @@ kbagent config set-folder --project NAME --component-id ID --config-id ID --name
|
|
|
555
555
|
kbagent config row-create --project NAME --component-id ID --config-id ID --name ROW_NAME [--description D] [--configuration JSON|@file|-] [--is-disabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
556
556
|
kbagent config row-update --project NAME --component-id ID --config-id ID --row-id ID [--name N] [--description D] [--configuration JSON|@file|-] [--change-description TEXT] [--is-disabled | --is-enabled] [--branch ID] [--allow-plaintext-on-encrypt-failure]
|
|
557
557
|
kbagent config row-delete --project NAME --component-id ID --config-id ID --row-id ID [--branch ID] [--yes]
|
|
558
|
-
kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL]
|
|
558
|
+
kbagent config oauth-url --project NAME --component-id ID --config-id ID [--redirect-url URL] [--no-open]
|
|
559
|
+
# oauth-url: opens the link in the default browser (interactive human mode only; never with
|
|
560
|
+
# --json, over SSH, in a container or in WSL without wslview); --no-open only prints it.
|
|
561
|
+
# Version gate in gotchas.md.
|
|
559
562
|
kbagent config state-get --project NAME --component-id ID --config-id ID [--row-id ID] [--branch ID]
|
|
560
563
|
kbagent config state-set --project NAME --component-id ID --config-id ID [--row-id ID] --state JSON|@file|- [--branch ID] [--dry-run] [--yes]
|
|
561
564
|
# state-get/state-set (0.84.2+, #593): read/write a config's runtime state via the dedicated
|
|
@@ -625,7 +628,7 @@ kbagent storage table-detail --project NAME --table-id ID [--branch ID]
|
|
|
625
628
|
# and `sql_path` (quoted, directly queryable path; null when Storage reports no location) --
|
|
626
629
|
# see the semantic-layer dataset fqn note (#761); version gate in gotchas.md.
|
|
627
630
|
kbagent storage create-bucket --project NAME --stage STAGE --name NAME [--description D] [--backend B] [--branch ID]
|
|
628
|
-
kbagent storage create-table --project NAME --bucket-id ID --name NAME [--column COL:TYPE[(length)] ...] [--primary-key COL] [--not-null COL ...] [--default NAME=VALUE ...] [--source-table-id ID] [--source-branch-id N] [--time-partitioning-type DAY|HOUR|MONTH|YEAR] [--time-partitioning-field COL] [--time-partitioning-expiration-ms MS] [--range-partitioning-field COL --range-partitioning-start S --range-partitioning-end E --range-partitioning-interval I] [--clustering-field COL ...] [--branch ID] [--if-not-exists]
|
|
631
|
+
kbagent storage create-table --project NAME --bucket-id ID --name NAME [--column COL:TYPE[(length)] ...] [--primary-key COL] [--not-null COL ...] [--default NAME=VALUE ...] [--source-table-id ID] [--source-branch-id N] [--time-partitioning-type DAY|HOUR|MONTH|YEAR] [--time-partitioning-field COL] [--time-partitioning-expiration-ms MS] [--range-partitioning-field COL --range-partitioning-start S --range-partitioning-end E --range-partitioning-interval I] [--clustering-field COL ...] [--branch ID] [--if-not-exists] [--timeout SECONDS]
|
|
629
632
|
# --column XOR --source-table-id (0.66.0+, BigQuery only): --source-table-id copies an existing table's data into the requested partition/clustering layout (schema derived from source) -> swap into place with swap-tables. Partition/clustering flags work in both modes (BigQuery only); time vs range partitioning are mutually exclusive. A non-BigQuery project fails fast (pre-flight backend check).
|
|
630
633
|
kbagent storage upload-table --project NAME --table-id ID --file PATH [--incremental] [--delimiter D] [--enclosure E] [--no-auto-create] [--wait/--no-wait] [--timeout SECONDS] [--branch ID] [--progress]
|
|
631
634
|
# upload-table / file-upload cloud upload (#834): on AWS stacks a file above 64 MiB goes up as an S3
|
|
@@ -663,7 +666,16 @@ kbagent storage delete-table --project NAME --table-id ID [--table-id ...] [--fo
|
|
|
663
666
|
kbagent storage truncate-table --project NAME --table-id ID [--table-id ...] [--dry-run] [--yes] [--branch ID]
|
|
664
667
|
kbagent storage delete-column --project NAME --table-id ID --column COL [--column ...] [--force] [--dry-run] [--yes] [--branch ID]
|
|
665
668
|
kbagent storage delete-bucket --project NAME --bucket-id ID [--bucket-id ...] [--force] [--dry-run] [--yes] [--branch ID]
|
|
666
|
-
kbagent storage swap-tables --project NAME --table-id ID --target-table-id ID --branch ID [--dry-run] [--yes]
|
|
669
|
+
kbagent storage swap-tables --project NAME --table-id ID --target-table-id ID --branch ID [--dry-run] [--yes] [--timeout SECONDS]
|
|
670
|
+
# --timeout SECONDS on create-table and swap-tables (since 0.99.0, #713): both halves
|
|
671
|
+
# of the repartition path move real data yet used to inherit the 60s metadata-job
|
|
672
|
+
# budget, so a large BigQuery table reported STORAGE_JOB_TIMEOUT for a job that was
|
|
673
|
+
# still running and would succeed. Default is now 300s on both. A local timeout
|
|
674
|
+
# NEVER cancels the job -- it keeps running server-side. The error is
|
|
675
|
+
# STORAGE_JOB_TIMEOUT, exit 4, retryable=false, details.job_id, and the message
|
|
676
|
+
# names `storage job-detail --job-id ID --wait` (create-table also names
|
|
677
|
+
# `storage table-detail`). Never re-run: a repeated swap swaps the tables back,
|
|
678
|
+
# a repeated --source-table-id create starts a second copy.
|
|
667
679
|
kbagent storage clone-table --project NAME --table-id ID --branch ID [--dry-run]
|
|
668
680
|
kbagent storage snapshot-create --project NAME --table-id ID [--description D] [--branch ID]
|
|
669
681
|
kbagent storage snapshots --project NAME --table-id ID [--limit N] [--branch ID]
|
|
@@ -813,6 +825,25 @@ kbagent token refresh --project NAME --token-id ID [--yes]
|
|
|
813
825
|
# is persisted. `permissions show` / `kbagent doctor` also generalized: they now flag ANY
|
|
814
826
|
# persisted pattern matching zero known operations, not only the retired tool:* namespace.
|
|
815
827
|
# PermissionEngine itself stays lenient at evaluation time -- only `permissions set` is strict.
|
|
828
|
+
# (since 0.99.0, #655) The policy also firewalls the WHOLE `kbagent serve` REST surface: every
|
|
829
|
+
# route is classified in server/route_permissions.py and checked by one app-level dependency
|
|
830
|
+
# against the SERVED config dir's policy -> HTTP 403 error_code PERMISSION_DENIED, the same
|
|
831
|
+
# code the CLI exits on. On 0.98.0 and older only /auth/* (0.90.1+) and /merge-requests/*
|
|
832
|
+
# (0.94.0+) were checked and every other route executed unchecked. Routes that declare their
|
|
833
|
+
# own `require_permission(...)` (those two routers) are skipped by the table. An unclassified
|
|
834
|
+
# route is REFUSED, not exempted (a test keeps the table
|
|
835
|
+
# and the live app in sync both ways); bootstrap paths (/health/ping, /health/auth-info,
|
|
836
|
+
# /ui-config, /docs, /redoc, /openapi.json, SPA shell) are never checked. A path param
|
|
837
|
+
# that collapses CLI leaves is checked like the CLI: POST/PUT/DELETE
|
|
838
|
+
# /semantic-layer/items/{kind}[/{name}] check the parent key (`semantic-layer.add`) AND
|
|
839
|
+
# the leaf `semantic-layer.add.<kind>` (route_permissions.LEAF_PATH_PARAMS).
|
|
840
|
+
# A `--scope organization` semantic-layer write is destructive-class over REST too:
|
|
841
|
+
# the handlers of scope PUT, models, items/{kind} (per-kind leaf key), import, promote
|
|
842
|
+
# and build check `<key> --scope organization` (FLAG_ESCALATIONS) for a typed OR an
|
|
843
|
+
# inherited organization scope, like the CLI.
|
|
844
|
+
# `GET /permissions/show` (serve, since 0.99.0) reports the EFFECTIVE policy (persisted block
|
|
845
|
+
# merged with the daemon's --deny-* flags); read-only by design -- no REST route can widen
|
|
846
|
+
# the policy that constrains it, so `permissions set|reset` stay terminal actions on the host.
|
|
816
847
|
kbagent permissions list [--category read|write|destructive|admin]
|
|
817
848
|
kbagent permissions show
|
|
818
849
|
kbagent permissions set --mode allow|deny [--allow PATTERN ...] [--deny PATTERN ...]
|
|
@@ -900,6 +931,17 @@ kbagent merge-request resolve --component-id C --config-id I (--take ours|theirs
|
|
|
900
931
|
# its hint-next respects it.
|
|
901
932
|
|
|
902
933
|
kbagent workspace create --project ALIAS [--name NAME] [--backend TYPE] [--ui] [--read-only/--no-read-only]
|
|
934
|
+
# workspace create (#755): a failed create -- headless or --ui -- moves the keboola.sandboxes
|
|
935
|
+
# config it created to the trash and says so (--json error.details: sandbox_config_id,
|
|
936
|
+
# sandbox_config_rolled_back, branch_id, job_id for --ui) -- except when the outcome is
|
|
937
|
+
# unknown, where the config is kept (sandbox_config_kept_reason: outcome_unknown): a 5xx, a
|
|
938
|
+
# read/write TIMEOUT or RETRY_EXHAUSTED on the create POST, or any error after the --ui job was
|
|
939
|
+
# queued other than QUEUE_JOB_FAILED / WORKSPACE_NOT_FOUND; the --ui job is queued on the branch
|
|
940
|
+
# the config lives in (was: default branch -> Queue 400 on a pinned dev branch). --ui itself
|
|
941
|
+
# still ends in WORKSPACE_NOT_FOUND on current SaaS stacks: the keboola.sandboxes `create` task
|
|
942
|
+
# dropped Snowflake/BigQuery provisioning in 2026-03 (the UI uses SQL Editor sessions), so the
|
|
943
|
+
# green job attaches no Storage workspace. Not a race -- do not retry; use headless. Version
|
|
944
|
+
# gate for this entry lives in gotchas.md (these `# ` lines parse as ATX headings).
|
|
903
945
|
kbagent workspace list [--project NAME ...] [--orphaned] [--branch ID] [--qs-compatible]
|
|
904
946
|
kbagent workspace detail --project ALIAS --workspace-id ID [--branch ID]
|
|
905
947
|
kbagent workspace delete --project ALIAS --workspace-id ID
|
|
@@ -958,10 +1000,17 @@ kbagent data-app create --project ALIAS --name NAME --slug SLUG (--git-repo URL
|
|
|
958
1000
|
# (1) create --use-managed-git-repo -> (2) `git-credentials-create --type http_token --permissions
|
|
959
1001
|
# readWrite` + `git push` code to the managed repo URL (from `git-repo`) -> (3) `data-app deploy`.
|
|
960
1002
|
# The platform injects the clone credentials at deploy time, so no credential wiring is needed.
|
|
961
|
-
# deploy pins the LATEST configVersion
|
|
962
|
-
#
|
|
963
|
-
#
|
|
964
|
-
|
|
1003
|
+
# deploy pins the LATEST configVersion. For a PURE managed repo (no git block yet), it first
|
|
1004
|
+
# backfills parameters.dataApp.git from the managed repo's URL, then pins the resulting version
|
|
1005
|
+
# (CLI-15) -- omitting configVersion alone does NOT provision the app's workspace;
|
|
1006
|
+
# grant provisioning is gated on that block's presence, not on configVersion. The deploy result
|
|
1007
|
+
# reports it (`git_backfilled`, `git_branch`, `warnings[]`). The branch written is `--git-branch`;
|
|
1008
|
+
# without it, `main` for an app with no runs, and a VALIDATION_ERROR before any write for an app
|
|
1009
|
+
# with runs (branch unknown: pass `--git-branch` with the branch the code is on). It has no effect
|
|
1010
|
+
# on a deploy that does not backfill. Push the managed repo's code to that branch.
|
|
1011
|
+
# Version gate lives in gotchas.md (no `(since vNEXT)` on `# ` lines). Use `data-app runs`
|
|
1012
|
+
# to debug a deploy that reverts to stopped (setup-phase failures produce no container logs).
|
|
1013
|
+
kbagent data-app deploy --project NAME --app-id ID [--config-version N] [--wait] [--timeout SECONDS] [--branch ID] [--git-branch BRANCH] [--copy] [--reveal]
|
|
965
1014
|
kbagent data-app start --project NAME --app-id ID [--wait] [--timeout SECONDS]
|
|
966
1015
|
kbagent data-app stop --project NAME --app-id ID [--wait] [--timeout SECONDS]
|
|
967
1016
|
kbagent data-app delete --project NAME --app-id ID [--yes]
|
|
@@ -1026,6 +1075,9 @@ kbagent config new --component-id ID [--name NAME] [--project NAME] [--output-di
|
|
|
1026
1075
|
# the scaffold had no ID and always landed in the default branch tree, so the next
|
|
1027
1076
|
# `sync push` created a DUPLICATE (34-config incident). With --configuration, the local file
|
|
1028
1077
|
# mirrors the pushed encrypted body -- placeholders would overwrite the remote on next push.
|
|
1078
|
+
# The scaffold also records _keboola.base_config_hash (#792 E), the created config as the API
|
|
1079
|
+
# returned it, so `sync diff` compares it 3-way and push never overwrites an edit made in the UI.
|
|
1080
|
+
# Version gate in gotchas.md.
|
|
1029
1081
|
|
|
1030
1082
|
# sync: GitOps -- configs as local files. init/pull/push/diff are filesystem-local (no serve REST surface).
|
|
1031
1083
|
kbagent sync init --project ALIAS [--directory DIR] [--git-branching] [--adopt-existing] [--with-workspaces]
|
|
@@ -1041,6 +1093,13 @@ kbagent sync push --project ALIAS [--all-projects] [--dry-run] [--force] [--allo
|
|
|
1041
1093
|
# under skipped_deletions (+ skipped_deletions_reason), also in --dry-run, whose summary.deleted counts only
|
|
1042
1094
|
# what push would delete. A config/row deleted on the remote since the last pull diffs as remote_deleted and
|
|
1043
1095
|
# is never re-created (it lands in skipped). Version gate in gotchas.md.
|
|
1096
|
+
# sync diff/push/pull and adopted files (#792 E): an untracked _config.yml whose _keboola.config_id
|
|
1097
|
+
# exists on the target has no baseline unless it records _keboola.base_config_hash; without one a
|
|
1098
|
+
# difference is a conflict (push skips it), two files with one id are both conflicts, and pull keeps
|
|
1099
|
+
# such a file with local changes (skipped) -- only --theirs overwrites it. Version gate in gotchas.md.
|
|
1100
|
+
# sync push encryption (#792 F): every #-secret is encrypted before the first write, so an
|
|
1101
|
+
# ENCRYPTION_FAILED stops push before anything reaches the remote (the message ends with "Nothing
|
|
1102
|
+
# was pushed.") and a retry creates nothing twice. Version gate in gotchas.md.
|
|
1044
1103
|
# sync push workspace delete (CLI-25): in a `syncWorkspaces` tree, a `push --force` that deletes a shared SQL workspace also deletes its SQL editor sessions (every user's, push branch) and their backend workspaces, which `config restore` does not bring back; `push --dry-run --force` lists them (warnings[] workspace_sessions), a plain push lists the workspace under skipped_deletions and touches no session. `--force` is destructive-class (FLAG_ESCALATIONS `sync.push --force`), so `--deny-destructive` / a cli:destructive deny blocks it while a plain push stays write-class. Version gate for this entry lives in gotchas.md.
|
|
1045
1104
|
# Partial failures change the exit code (#745): commands that collect per-item failures
|
|
1046
1105
|
# and keep going exit 1 (was 0) when at least one item failed:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: keboola-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.99.0
|
|
4
4
|
Summary: AI-friendly CLI for managing Keboola projects
|
|
5
5
|
Author-email: Keboola <dev@keboola.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -84,6 +84,29 @@ A fresh Windows install has no real Python either: `python` resolves to a Micros
|
|
|
84
84
|
|
|
85
85
|
Auto-updates kbagent on every launch; the self-update prefers the prebuilt wheel when available. Run `kbagent changelog` to see what changed. (Since 0.85.0 kbagent updates itself only -- if you also run `keboola-mcp-server` in Claude Desktop / Cursor, refresh it yourself with `uv tool install --upgrade --prerelease=allow keboola-mcp-server`.)
|
|
86
86
|
|
|
87
|
+
### Installed under the old package name
|
|
88
|
+
|
|
89
|
+
The package was named `keboola-agent-cli` up to 0.62.0. It is named `keboola-cli` from 0.63.0. Both packages install the `kbagent` executable. uv treats an update to `keboola-cli` as a new tool and does not overwrite the executable that the old tool owns.
|
|
90
|
+
|
|
91
|
+
To check which name you have, run `uv tool list`. An old install is listed as `keboola-agent-cli`.
|
|
92
|
+
|
|
93
|
+
- kbagent 0.59.x and older cannot update itself. Every command prints `Auto-update failed; continuing with current version.` and the version does not change. Without the `[server]` extras, the uv error behind it is ``error: Executable already exists: kbagent (use `--force` to overwrite)``. No release can change this, because the update code runs from the old install.
|
|
94
|
+
- kbagent 0.60.0 to 0.62.x updates through a compatibility wheel and stays on the old name.
|
|
95
|
+
- kbagent 0.63.1 and newer installs a second tool, `keboola-cli`, when it updates. The new tool takes over the `kbagent` executable and the old `keboola-agent-cli` entry stays in `uv tool list`.
|
|
96
|
+
|
|
97
|
+
To move to `keboola-cli`, run these two commands in this order, in a shell where no kbagent is running:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
uv tool uninstall keboola-agent-cli
|
|
101
|
+
curl -LsSf https://raw.githubusercontent.com/keboola/cli/main/install.sh | sh
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
On Windows, run the PowerShell install from the Windows section above as the second step. Your configuration is not touched: the configuration folder keeps the name `keboola-agent-cli` on purpose.
|
|
105
|
+
|
|
106
|
+
If `uv tool list` shows `keboola-cli` next to `keboola-agent-cli`, the update already worked. kbagent runs from `keboola-cli` and the old entry does no harm. Do not remove the old entry on its own: `uv tool uninstall keboola-agent-cli` also deletes the `kbagent` executable that `keboola-cli` uses, and the shell then reports `command not found`. To restore the executable, run `uv tool install --force --reinstall "keboola-cli[server] @ https://github.com/keboola/cli/releases/download/v<version>/keboola_cli-<version>-py3-none-any.whl"` with the latest version number from the [releases page](https://github.com/keboola/cli/releases/latest).
|
|
107
|
+
|
|
108
|
+
A failed startup update prints the last line of the uv output as `Cause:` (since 0.99.0), then the recovery command.
|
|
109
|
+
|
|
87
110
|
## Web UI (optional)
|
|
88
111
|
|
|
89
112
|
Want a browser dashboard? One command:
|
|
@@ -155,7 +178,7 @@ Then either let the `kbagent` skill auto-trigger from natural prompts, or delega
|
|
|
155
178
|
kbagent init --from-global --read-only
|
|
156
179
|
```
|
|
157
180
|
|
|
158
|
-
Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules)
|
|
181
|
+
Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules) stop the agent from writing, deleting, or changing the restrictions by mistake. They are guard rails, not a sandbox: a process that runs as the same OS user can get around them. For a hard lockout, run the agent as a different OS user ([ADR 0002](docs/adr/0002-sec-09-config-privilege-separation.md)). See [Permissions Guide](docs/guide.md#permissions) for details.
|
|
159
182
|
|
|
160
183
|
## Use as a library
|
|
161
184
|
|
|
@@ -182,9 +205,9 @@ with Client(url=os.environ["KBC_URL"], token=os.environ["KBC_TOKEN"]) as kbc:
|
|
|
182
205
|

|
|
183
206
|
|
|
184
207
|
```bash
|
|
185
|
-
# Connect a project (Storage API token from Keboola UI)
|
|
208
|
+
# Connect a project (Storage API token from Keboola UI, typed at a hidden prompt)
|
|
186
209
|
kbagent project add --project prod \
|
|
187
|
-
--url https://connection.keboola.com --token
|
|
210
|
+
--url https://connection.keboola.com --token-stdin
|
|
188
211
|
|
|
189
212
|
# Find anything (table / config / flow / data app) across ALL projects in one call
|
|
190
213
|
kbagent search "customer_id"
|
|
@@ -233,9 +256,12 @@ Four ways to register projects, depending on what you have. If you are a human
|
|
|
233
256
|
at a terminal with a browser, start with **browser login** (last one below);
|
|
234
257
|
the token-based options are the ones to use for CI and anything unattended.
|
|
235
258
|
|
|
236
|
-
**Single project** — you have a Storage API token from the UI:
|
|
259
|
+
**Single project** — you have a Storage API token from the UI. `--token-stdin` shows a hidden prompt on a terminal and reads a pipe otherwise, so the token stays out of your shell history:
|
|
237
260
|
```bash
|
|
238
|
-
kbagent project add --project prod --url https://connection.keboola.com --token
|
|
261
|
+
kbagent project add --project prod --url https://connection.keboola.com --token-stdin
|
|
262
|
+
|
|
263
|
+
# CI / non-interactive: pipe the token in
|
|
264
|
+
printf '%s' "$KBC_TOKEN" | kbagent project add --project prod --url https://connection.keboola.com --token-stdin
|
|
239
265
|
```
|
|
240
266
|
|
|
241
267
|
**Many projects by ID** — you have a Manage API or Personal Access Token + the project IDs:
|
|
@@ -56,6 +56,29 @@ A fresh Windows install has no real Python either: `python` resolves to a Micros
|
|
|
56
56
|
|
|
57
57
|
Auto-updates kbagent on every launch; the self-update prefers the prebuilt wheel when available. Run `kbagent changelog` to see what changed. (Since 0.85.0 kbagent updates itself only -- if you also run `keboola-mcp-server` in Claude Desktop / Cursor, refresh it yourself with `uv tool install --upgrade --prerelease=allow keboola-mcp-server`.)
|
|
58
58
|
|
|
59
|
+
### Installed under the old package name
|
|
60
|
+
|
|
61
|
+
The package was named `keboola-agent-cli` up to 0.62.0. It is named `keboola-cli` from 0.63.0. Both packages install the `kbagent` executable. uv treats an update to `keboola-cli` as a new tool and does not overwrite the executable that the old tool owns.
|
|
62
|
+
|
|
63
|
+
To check which name you have, run `uv tool list`. An old install is listed as `keboola-agent-cli`.
|
|
64
|
+
|
|
65
|
+
- kbagent 0.59.x and older cannot update itself. Every command prints `Auto-update failed; continuing with current version.` and the version does not change. Without the `[server]` extras, the uv error behind it is ``error: Executable already exists: kbagent (use `--force` to overwrite)``. No release can change this, because the update code runs from the old install.
|
|
66
|
+
- kbagent 0.60.0 to 0.62.x updates through a compatibility wheel and stays on the old name.
|
|
67
|
+
- kbagent 0.63.1 and newer installs a second tool, `keboola-cli`, when it updates. The new tool takes over the `kbagent` executable and the old `keboola-agent-cli` entry stays in `uv tool list`.
|
|
68
|
+
|
|
69
|
+
To move to `keboola-cli`, run these two commands in this order, in a shell where no kbagent is running:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
uv tool uninstall keboola-agent-cli
|
|
73
|
+
curl -LsSf https://raw.githubusercontent.com/keboola/cli/main/install.sh | sh
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
On Windows, run the PowerShell install from the Windows section above as the second step. Your configuration is not touched: the configuration folder keeps the name `keboola-agent-cli` on purpose.
|
|
77
|
+
|
|
78
|
+
If `uv tool list` shows `keboola-cli` next to `keboola-agent-cli`, the update already worked. kbagent runs from `keboola-cli` and the old entry does no harm. Do not remove the old entry on its own: `uv tool uninstall keboola-agent-cli` also deletes the `kbagent` executable that `keboola-cli` uses, and the shell then reports `command not found`. To restore the executable, run `uv tool install --force --reinstall "keboola-cli[server] @ https://github.com/keboola/cli/releases/download/v<version>/keboola_cli-<version>-py3-none-any.whl"` with the latest version number from the [releases page](https://github.com/keboola/cli/releases/latest).
|
|
79
|
+
|
|
80
|
+
A failed startup update prints the last line of the uv output as `Cause:` (since 0.99.0), then the recovery command.
|
|
81
|
+
|
|
59
82
|
## Web UI (optional)
|
|
60
83
|
|
|
61
84
|
Want a browser dashboard? One command:
|
|
@@ -127,7 +150,7 @@ Then either let the `kbagent` skill auto-trigger from natural prompts, or delega
|
|
|
127
150
|
kbagent init --from-global --read-only
|
|
128
151
|
```
|
|
129
152
|
|
|
130
|
-
Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules)
|
|
153
|
+
Three protection layers (kbagent policy + filesystem chmod + Claude Code deny rules) stop the agent from writing, deleting, or changing the restrictions by mistake. They are guard rails, not a sandbox: a process that runs as the same OS user can get around them. For a hard lockout, run the agent as a different OS user ([ADR 0002](docs/adr/0002-sec-09-config-privilege-separation.md)). See [Permissions Guide](docs/guide.md#permissions) for details.
|
|
131
154
|
|
|
132
155
|
## Use as a library
|
|
133
156
|
|
|
@@ -154,9 +177,9 @@ with Client(url=os.environ["KBC_URL"], token=os.environ["KBC_TOKEN"]) as kbc:
|
|
|
154
177
|

|
|
155
178
|
|
|
156
179
|
```bash
|
|
157
|
-
# Connect a project (Storage API token from Keboola UI)
|
|
180
|
+
# Connect a project (Storage API token from Keboola UI, typed at a hidden prompt)
|
|
158
181
|
kbagent project add --project prod \
|
|
159
|
-
--url https://connection.keboola.com --token
|
|
182
|
+
--url https://connection.keboola.com --token-stdin
|
|
160
183
|
|
|
161
184
|
# Find anything (table / config / flow / data app) across ALL projects in one call
|
|
162
185
|
kbagent search "customer_id"
|
|
@@ -205,9 +228,12 @@ Four ways to register projects, depending on what you have. If you are a human
|
|
|
205
228
|
at a terminal with a browser, start with **browser login** (last one below);
|
|
206
229
|
the token-based options are the ones to use for CI and anything unattended.
|
|
207
230
|
|
|
208
|
-
**Single project** — you have a Storage API token from the UI:
|
|
231
|
+
**Single project** — you have a Storage API token from the UI. `--token-stdin` shows a hidden prompt on a terminal and reads a pipe otherwise, so the token stays out of your shell history:
|
|
209
232
|
```bash
|
|
210
|
-
kbagent project add --project prod --url https://connection.keboola.com --token
|
|
233
|
+
kbagent project add --project prod --url https://connection.keboola.com --token-stdin
|
|
234
|
+
|
|
235
|
+
# CI / non-interactive: pipe the token in
|
|
236
|
+
printf '%s' "$KBC_TOKEN" | kbagent project add --project prod --url https://connection.keboola.com --token-stdin
|
|
211
237
|
```
|
|
212
238
|
|
|
213
239
|
**Many projects by ID** — you have a Manage API or Personal Access Token + the project IDs:
|
|
@@ -81,8 +81,8 @@ explores traces of up to 5 actions. BFS returns the shortest counterexample.
|
|
|
81
81
|
| I5 pull keeps local work | violated: a remote delete plus a local edit ends with plain or `--force` pull deleting the edited directory silently |
|
|
82
82
|
| I6 push then diff is clean | violated on `--branch` promote (finding D, since fixed in the engine; the TLA model is unchanged). Holds on production only (30,334 states) |
|
|
83
83
|
| I8 manifest matches disk | violated: the stale sweep, and a promote write-back that records a `devt/` entry for a file in `main/` |
|
|
84
|
-
| I9 an aborted push is atomic | violated (strong reading): the changes before the failing one reached the API and the manifest was never saved |
|
|
85
|
-
| I11 no lost remote update | violated: an adopted file with a config id is diffed 2-way, so push reverts a UI edit |
|
|
84
|
+
| I9 an aborted push is atomic | violated (strong reading): the changes before the failing one reached the API and the manifest was never saved. Fixed in the code (F: push encrypts before its first write); the model is unchanged |
|
|
85
|
+
| I11 no lost remote update | violated: an adopted file with a config id is diffed 2-way, so push reverts a UI edit. Fixed in the code (E); the model is unchanged |
|
|
86
86
|
| I11b no silent resurrect | violated: a remote delete followed by any push re-creates the config, even with no local edit (S2). Fixed in the code (H); the model is unchanged |
|
|
87
87
|
| I12 a pull resolves REMOTE MODIFIED | violated: after a cosmetic edit, plain pull skips the file forever and `--force` raises a conflict (S3) |
|
|
88
88
|
|
|
@@ -103,8 +103,8 @@ the regression test for each in `tests/test_sync_formal_counterexamples.py`.
|
|
|
103
103
|
| B | Pull compares only `_config.yml`: local edits in `transform.sql`/`code.py`/`_description.md` are silently overwritten when the remote changed, no SYNC_CONFLICT | Lean F6 | HIGH -- **FIXED** (pull's local-modification check now covers every `pull_extra_hashes` companion file) | `test_b_pull_never_overwrites_local_sql_edit` (unmarked regression guard) + `tests/test_sync_pull_companion_files.py` |
|
|
104
104
|
| C | Remote delete + local edit: pull (plain/`--force`) deletes the locally-edited directory with no conflict | Lean F7, TLA I5 | HIGH -- **fixed** (#792 A/C PR) | `test_c_pull_never_deletes_locally_edited_dir_on_remote_delete` |
|
|
105
105
|
| D | `sync push --branch dev` (promote) creates another dev copy of a prod-only config on every push. **Fixed** (fix/792-dev-promote-duplicates): on the promote path the target-branch entry shadows the production entry for the same `main/` dir (`sync/branch_scope.py::_promoted_paths`) | TLA I6/I1 | HIGH | `test_d_promote_push_is_idempotent`, `test_d_promote_push_diff_is_clean_and_edits_update_the_dev_copy` (regression guards) |
|
|
106
|
-
| E | An untracked file carrying a config id (`config new --push --output-dir` scaffold / adopted orphan) is diffed 2-way: push overwrites a UI edit made after the scaffold was written | TLA I11 | MED | `test_e_adopted_scaffold_push_does_not_overwrite_remote_edit` |
|
|
107
|
-
| F | A push aborted by `ENCRYPTION_FAILED` leaves the manifest unsaved; the retry duplicates the change(s) the aborted push already applied | TLA I1b (model trace only; replayed live for this pilot) | MED | `test_f_aborted_push_does_not_duplicate_already_created_config` |
|
|
106
|
+
| E | An untracked file carrying a config id (`config new --push --output-dir` scaffold / adopted orphan) is diffed 2-way: push overwrites a UI edit made after the scaffold was written | TLA I11, Lean F4/F5 | MED -- **fixed** (without a baseline a difference is a `conflict`; the scaffold records `_keboola.base_config_hash`; pull keeps such a file) | `test_e_adopted_scaffold_push_does_not_overwrite_remote_edit` + `tests/test_sync_adopted_files.py` |
|
|
107
|
+
| F | A push aborted by `ENCRYPTION_FAILED` leaves the manifest unsaved; the retry duplicates the change(s) the aborted push already applied | TLA I1b (model trace only; replayed live for this pilot) | MED -- **fixed** (push encrypts every secret before its first write, so the abort writes nothing) | `test_f_aborted_push_does_not_duplicate_already_created_config` + `tests/test_sync_push_encrypt_first.py` |
|
|
108
108
|
| G | `sync push` deletes remote configs with no `--force`; the CLI help text says `--force` gates deletion (soft delete to trash since 0.89.0, restorable) | Spec S1, Lean F1, TLA I2b | MED -- **fixed** (push deletes only with `--force`) | `test_g_push_without_force_does_not_delete_remote_config` |
|
|
109
109
|
| H | A config deleted remotely by another actor is silently re-created by the next push, no warning | Spec S2, Lean F2, TLA I11b | MED -- **fixed** (diff reports `remote_deleted`, push skips it) | `test_h_push_does_not_silently_resurrect_deleted_config` |
|
|
110
110
|
| I | Moving a config's directory by hand (`mv`/`git mv`) is seen as remote DELETE + CREATE under a new id | Lean F3 | LOW-MED | `test_i_moving_config_dir_is_not_delete_plus_create` |
|
|
@@ -120,11 +120,11 @@ and is deleted only by `--theirs`. That is what the I2 (sweep half), I5 and I8
|
|
|
120
120
|
TLC/Lean rerun still reports them until the model's `Pull` is updated to match.
|
|
121
121
|
Their tests are ordinary regression guards now.
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
I reproduces on current code and is `xfail(strict=True)` (D, E, F, G and H
|
|
124
124
|
are fixed) -- flipping to a hard failure the moment a fix lands is the point:
|
|
125
|
-
delete the `xfail` marker to adopt the fix. F's test
|
|
125
|
+
delete the `xfail` marker to adopt the fix. F's test reaches the aborted
|
|
126
126
|
create through a promote push, because push no longer re-creates the
|
|
127
|
-
remote-deleted config its first version used
|
|
128
|
-
is `xfail`. K is deliberate, documented behavior, so it is an ordinary
|
|
127
|
+
remote-deleted config its first version used; since the F fix the aborted
|
|
128
|
+
push creates nothing. J reproduces and is `xfail`. K is deliberate, documented behavior, so it is an ordinary
|
|
129
129
|
(unmarked) regression guard instead. B is fixed: its marker was removed
|
|
130
130
|
and the test is now an ordinary regression guard.
|
|
@@ -792,7 +792,7 @@ class AuthClient(BaseHttpClient):
|
|
|
792
792
|
f"project that already exists: create one at {self._base_url} in a "
|
|
793
793
|
f"browser, then connect it with `kbagent auth login --stack "
|
|
794
794
|
f"{self._base_url}` or `kbagent project add --project <alias> --url "
|
|
795
|
-
f"{self._base_url} --token
|
|
795
|
+
f"{self._base_url} --token-stdin`."
|
|
796
796
|
),
|
|
797
797
|
status_code=404,
|
|
798
798
|
error_code=ErrorCode.AUTH_NOT_SUPPORTED_ON_STACK,
|
|
@@ -969,7 +969,7 @@ class AuthClient(BaseHttpClient):
|
|
|
969
969
|
message=(
|
|
970
970
|
f"Browser login is not enabled on this Keboola stack yet "
|
|
971
971
|
f"({self._base_url}). Use a static Storage token instead: "
|
|
972
|
-
"kbagent project add --project <alias> --url <stack> --token
|
|
972
|
+
"kbagent project add --project <alias> --url <stack> --token-stdin."
|
|
973
973
|
),
|
|
974
974
|
status_code=404,
|
|
975
975
|
error_code=ErrorCode.AUTH_NOT_SUPPORTED_ON_STACK,
|
|
@@ -1042,7 +1042,7 @@ class AuthClient(BaseHttpClient):
|
|
|
1042
1042
|
message=(
|
|
1043
1043
|
f"Programmatic auth is not enabled on this Keboola stack yet "
|
|
1044
1044
|
f"({self._base_url}). Use a static Storage token instead: "
|
|
1045
|
-
"kbagent project add --project <alias> --url <stack> --token
|
|
1045
|
+
"kbagent project add --project <alias> --url <stack> --token-stdin."
|
|
1046
1046
|
),
|
|
1047
1047
|
status_code=404,
|
|
1048
1048
|
error_code=ErrorCode.AUTH_NOT_SUPPORTED_ON_STACK,
|
|
@@ -28,6 +28,10 @@ from dataclasses import dataclass
|
|
|
28
28
|
# wslview from stalling the login flow.
|
|
29
29
|
_WSLVIEW_PROBE_TIMEOUT_SECONDS = 2.0
|
|
30
30
|
|
|
31
|
+
# Timeout for handing a URL to `wslview`: it returns as soon as the Windows side
|
|
32
|
+
# has accepted the request, so anything longer means the shim is wedged.
|
|
33
|
+
_WSLVIEW_OPEN_TIMEOUT_SECONDS = 10.0
|
|
34
|
+
|
|
31
35
|
|
|
32
36
|
@dataclass(frozen=True)
|
|
33
37
|
class BrowserEnvironment:
|
|
@@ -168,6 +172,24 @@ def detect_browser_environment() -> BrowserEnvironment:
|
|
|
168
172
|
return BrowserEnvironment(loopback_browser_usable=True, reason="", opener=opener)
|
|
169
173
|
|
|
170
174
|
|
|
175
|
+
def _open_via_wslview(url: str) -> None:
|
|
176
|
+
"""Thread target for `open_browser` under WSL: hand ``url`` to `wslview`.
|
|
177
|
+
|
|
178
|
+
`wslview` passes the URL to the Windows-side default browser. Output is
|
|
179
|
+
captured, never logged, and every error is swallowed -- the URL must not
|
|
180
|
+
reach stderr (see `_open_silently`).
|
|
181
|
+
"""
|
|
182
|
+
try:
|
|
183
|
+
subprocess.run(
|
|
184
|
+
["wslview", url],
|
|
185
|
+
capture_output=True,
|
|
186
|
+
timeout=_WSLVIEW_OPEN_TIMEOUT_SECONDS,
|
|
187
|
+
check=False,
|
|
188
|
+
)
|
|
189
|
+
except Exception:
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
|
|
171
193
|
def open_browser(url: str, *, wait_seconds: float = 0.0) -> bool:
|
|
172
194
|
"""Best-effort `webbrowser.open` on a daemon thread.
|
|
173
195
|
|
|
@@ -182,13 +204,24 @@ def open_browser(url: str, *, wait_seconds: float = 0.0) -> bool:
|
|
|
182
204
|
right after the call (``data-app password --open``) passes it, because a
|
|
183
205
|
daemon thread dies with the process -- possibly before the opener starts.
|
|
184
206
|
The login flow keeps polling afterwards, so it leaves the default 0.
|
|
185
|
-
"""
|
|
186
|
-
try:
|
|
187
|
-
webbrowser.get()
|
|
188
|
-
except webbrowser.Error:
|
|
189
|
-
return False
|
|
190
207
|
|
|
191
|
-
|
|
208
|
+
Under WSL the URL goes to `wslview` first: `webbrowser` keys its Windows
|
|
209
|
+
handling off ``sys.platform == "win32"``, which is ``linux`` inside WSL, so
|
|
210
|
+
it would either find no handler at all or open a browser in the Linux
|
|
211
|
+
session -- a separate profile that shares none of the logins the URL needs.
|
|
212
|
+
It runs on the same daemon thread and honors ``wait_seconds`` the same way;
|
|
213
|
+
a working `wslview` (probed synchronously) counts as the available handler.
|
|
214
|
+
"""
|
|
215
|
+
if _env_flag_set("WSL_INTEROP") and _wslview_is_working():
|
|
216
|
+
target = _open_via_wslview
|
|
217
|
+
else:
|
|
218
|
+
try:
|
|
219
|
+
webbrowser.get()
|
|
220
|
+
except webbrowser.Error:
|
|
221
|
+
return False
|
|
222
|
+
target = _open_silently
|
|
223
|
+
|
|
224
|
+
thread = threading.Thread(target=target, args=(url,), daemon=True)
|
|
192
225
|
thread.start()
|
|
193
226
|
if wait_seconds > 0:
|
|
194
227
|
thread.join(timeout=wait_seconds)
|
|
@@ -14,7 +14,9 @@ import logging
|
|
|
14
14
|
import os
|
|
15
15
|
import shutil
|
|
16
16
|
import sys
|
|
17
|
+
import tempfile
|
|
17
18
|
import time
|
|
19
|
+
from dataclasses import dataclass
|
|
18
20
|
from importlib.metadata import distribution
|
|
19
21
|
from pathlib import Path
|
|
20
22
|
|
|
@@ -39,6 +41,7 @@ from .services.version_service import (
|
|
|
39
41
|
get_update_timeout,
|
|
40
42
|
prepare_kbagent_update_plan,
|
|
41
43
|
resolve_kbagent_wheel_url,
|
|
44
|
+
summarize_install_failure,
|
|
42
45
|
)
|
|
43
46
|
from .update_runner import (
|
|
44
47
|
DeferredUpdateReport,
|
|
@@ -68,6 +71,14 @@ class UpdateOutcome(enum.Enum):
|
|
|
68
71
|
FAILED = "failed"
|
|
69
72
|
|
|
70
73
|
|
|
74
|
+
@dataclass(frozen=True)
|
|
75
|
+
class UpdateResult:
|
|
76
|
+
"""An :class:`UpdateOutcome` plus what the installer printed when it failed (issue #771)."""
|
|
77
|
+
|
|
78
|
+
outcome: UpdateOutcome
|
|
79
|
+
output: str = ""
|
|
80
|
+
|
|
81
|
+
|
|
71
82
|
# Process-level sentinel for the auto-update flow.
|
|
72
83
|
#
|
|
73
84
|
# Bug D fix from issue #263: ``kbagent repl`` re-enters the entire CLI
|
|
@@ -135,7 +146,22 @@ def _write_cache(latest_version: str | None) -> None:
|
|
|
135
146
|
"last_check": time.time(),
|
|
136
147
|
"latest_version": latest_version,
|
|
137
148
|
}
|
|
138
|
-
|
|
149
|
+
# Atomic replace (issue #271 sec-12): write a temp file next to the
|
|
150
|
+
# cache, then rename it over the cache in one step. A reader never sees
|
|
151
|
+
# a partial file, and a failed write keeps the previous cache. Each
|
|
152
|
+
# writer has its own temp file, so parallel kbagent starts need no
|
|
153
|
+
# lock: the last rename wins, and each value is a complete check result.
|
|
154
|
+
fd, tmp_name = tempfile.mkstemp(
|
|
155
|
+
dir=cache_path.parent, prefix=f".{cache_path.name}.", suffix=".tmp"
|
|
156
|
+
)
|
|
157
|
+
tmp_path = Path(tmp_name)
|
|
158
|
+
try:
|
|
159
|
+
with os.fdopen(fd, "w", encoding="utf-8") as tmp_file:
|
|
160
|
+
tmp_file.write(json.dumps(payload))
|
|
161
|
+
os.replace(tmp_path, cache_path)
|
|
162
|
+
except OSError:
|
|
163
|
+
tmp_path.unlink(missing_ok=True)
|
|
164
|
+
raise
|
|
139
165
|
except OSError:
|
|
140
166
|
pass # Non-critical; next run will re-fetch
|
|
141
167
|
|
|
@@ -273,9 +299,7 @@ def _should_skip() -> bool:
|
|
|
273
299
|
return _should_skip_kbagent_stage() or _should_skip_all()
|
|
274
300
|
|
|
275
301
|
|
|
276
|
-
def _perform_update(
|
|
277
|
-
latest_version: str, *, command: tuple[str, ...] | None = None
|
|
278
|
-
) -> UpdateOutcome:
|
|
302
|
+
def _perform_update(latest_version: str, *, command: tuple[str, ...] | None = None) -> UpdateResult:
|
|
279
303
|
"""Download and install the latest version.
|
|
280
304
|
|
|
281
305
|
Delegates to :func:`build_kbagent_upgrade_command` so this path stays
|
|
@@ -290,10 +314,10 @@ def _perform_update(
|
|
|
290
314
|
latest_version: The version being updated to (for logging).
|
|
291
315
|
|
|
292
316
|
Returns:
|
|
293
|
-
:class:`
|
|
294
|
-
the install outran :func:`get_update_timeout` -- it is
|
|
295
|
-
will finish on its own, so the next launch picks it up --
|
|
296
|
-
otherwise
|
|
317
|
+
:class:`UpdateResult` whose ``outcome`` is ``SUCCESS`` on a clean install,
|
|
318
|
+
``TIMEOUT`` when the install outran :func:`get_update_timeout` -- it is
|
|
319
|
+
still running and will finish on its own, so the next launch picks it up --
|
|
320
|
+
and ``FAILED`` otherwise, with the installer's output in ``output``.
|
|
297
321
|
"""
|
|
298
322
|
# ``command`` is supplied by the startup planner. Keep the fallback only
|
|
299
323
|
# for direct legacy callers; it must never be used after another stage has
|
|
@@ -304,17 +328,32 @@ def _perform_update(
|
|
|
304
328
|
else:
|
|
305
329
|
cmd = list(command)
|
|
306
330
|
if cmd is None:
|
|
307
|
-
return UpdateOutcome.FAILED
|
|
331
|
+
return UpdateResult(UpdateOutcome.FAILED)
|
|
308
332
|
|
|
309
333
|
# Deliberately does NOT kill the installer when the deadline passes -- see
|
|
310
334
|
# ``update_runner.run_install``. A terminated uv leaves the same
|
|
311
335
|
# half-removed venv a Windows file lock does (issue #528).
|
|
312
336
|
run = run_install(tuple(cmd), timeout=get_update_timeout())
|
|
313
337
|
if run.status is InstallStatus.SUCCEEDED:
|
|
314
|
-
return UpdateOutcome.SUCCESS
|
|
338
|
+
return UpdateResult(UpdateOutcome.SUCCESS)
|
|
315
339
|
if run.status is InstallStatus.STILL_RUNNING:
|
|
316
|
-
return UpdateOutcome.TIMEOUT
|
|
317
|
-
return UpdateOutcome.FAILED
|
|
340
|
+
return UpdateResult(UpdateOutcome.TIMEOUT)
|
|
341
|
+
return UpdateResult(UpdateOutcome.FAILED, run.output)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _format_update_failure(output: str, recovery_command: str | None) -> str:
|
|
345
|
+
"""Render the startup banner for a failed install (issue #771).
|
|
346
|
+
|
|
347
|
+
Names the line the installer ended with, so the user can tell a network
|
|
348
|
+
error from a permanent one.
|
|
349
|
+
"""
|
|
350
|
+
lines = ["Auto-update failed; continuing with current version."]
|
|
351
|
+
cause = summarize_install_failure(output)
|
|
352
|
+
if cause:
|
|
353
|
+
lines.append(f"Cause: {cause}")
|
|
354
|
+
if recovery_command:
|
|
355
|
+
lines.append(f"Recover with: {recovery_command}")
|
|
356
|
+
return "\n".join(lines) + "\n"
|
|
318
357
|
|
|
319
358
|
|
|
320
359
|
def _re_exec() -> None:
|
|
@@ -594,9 +633,10 @@ def maybe_auto_update() -> None:
|
|
|
594
633
|
return
|
|
595
634
|
|
|
596
635
|
sys.stderr.write(f"Updating kbagent v{__version__} -> v{kbagent_plan.latest_version}...\n")
|
|
597
|
-
|
|
636
|
+
result = _perform_update(
|
|
598
637
|
kbagent_plan.latest_version or __version__, command=kbagent_plan.command
|
|
599
638
|
)
|
|
639
|
+
outcome = result.outcome
|
|
600
640
|
if outcome is UpdateOutcome.SUCCESS:
|
|
601
641
|
sys.stderr.write(f"Updated to v{kbagent_plan.latest_version}. Re-launching...\n")
|
|
602
642
|
os.environ[ENV_UPDATED_FROM] = __version__
|
|
@@ -611,10 +651,7 @@ def maybe_auto_update() -> None:
|
|
|
611
651
|
"background and applies on the next launch.\n"
|
|
612
652
|
)
|
|
613
653
|
else:
|
|
614
|
-
sys.stderr.write(
|
|
615
|
-
"Auto-update failed; continuing with current version. Recover with: "
|
|
616
|
-
f"{kbagent_plan.recovery_command}\n"
|
|
617
|
-
)
|
|
654
|
+
sys.stderr.write(_format_update_failure(result.output, kbagent_plan.recovery_command))
|
|
618
655
|
except Exception:
|
|
619
656
|
# Blanket catch: auto-update must NEVER crash the CLI.
|
|
620
657
|
logger.debug("Auto-update check failed", exc_info=True)
|