keboola-cli 0.96.1__tar.gz → 0.96.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/PKG-INFO +1 -1
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/pyproject.toml +1 -1
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/changelog.py +11 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_password.py +62 -18
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_url_copy.py +5 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/auth.py +3 -3
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/context.py +3 -3
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/data_app.py +13 -2
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/conftest.py +20 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_cli_auth.py +26 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_cli.py +80 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_password.py +141 -1
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_url_copy.py +10 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/package-lock.json +3 -3
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/package.json +1 -1
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/.gitignore +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/CLAUDE.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/CONTRIBUTING.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/LICENSE +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/Makefile +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/README.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/examples/README.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/examples/storage_tui/README.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/formal/sync/README.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/plugins/kbagent/.claude-plugin/CLAUDE.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/plugins/kbagent/skills/kbagent-cicd-migration/scripts/migrate_cicd.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/plugins/kbagent/skills/kbagent-promotion-pipeline/scripts/generate_promotion_pipeline.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_command_sync.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_error_codes.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_file_size.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_release_scope.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_sentinel_guards.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_version_gates.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/check_wheel_ui.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/debug_linkedby_type.sh +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/file_size_baseline.json +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/gen_command_reference.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/gen_endpoint_reference.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/gen_release_notes.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/generate_changelog.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/generate_skill.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/hatch_build.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/lineage_deep.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/post-edit-quality.sh +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/pre-commit +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/sync_version.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/scripts/web-dev.sh +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/__main__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/ai_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/auth_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/device.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/environment.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/pkce.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/sentinel.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/state_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/token_provider.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auth/totp.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/auto_update.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/_core.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/_transfer.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/billing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/branches.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/configs.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/editor.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/merge_requests.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/misc.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/notifications.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/query.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/queue.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/storage_files.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/storage_tables.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/stream.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/tokens.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/triggers.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/client/workspaces.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_auth_picker.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_checkbox_select.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_config_clone_cmd.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_config_oauth.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_config_trash_cmd.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_git.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_runtime.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_flow_triggers.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_helpers.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_merge_request_common.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_merge_request_render.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_merge_request_writes.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_metadata_input.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_project_create.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_project_ref.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_semantic_layer_helpers.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_describe.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_snapshots.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_table_detail.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_storage_tables_render.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_sync_clone_render.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_sync_push_render.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/agent.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/billing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/branch.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/changelog.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/component.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/config.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/config_state.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/dev_portal.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/docs.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/doctor.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/encrypt.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/feature.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/flow.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/http_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/init.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/job.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/kai.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/lineage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/merge_request.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/notification.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/org.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/permissions.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/project.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/repl.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/schedule.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/search.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/semantic_layer.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/serve.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/sharing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/storage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/stream.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/sync.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/token.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/transformation.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/version.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/workspace.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/config_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/constants.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/data_science_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/dev_portal_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/effective_branch.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/errors.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/frozen_dist.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/http_base.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/json_utils.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/lib.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/manage_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/metastore_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/output.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/permissions.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/project_ref.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/py.typed +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/conditional-flow-schema.json +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/conditional_flow_examples.jsonl +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/flow-schema.json +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/resources/flow/legacy_flow_examples.jsonl +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/result_models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/scheduler_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/_serve_command_map.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/agent_runner.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/agents_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/app.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/auth.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/dependencies.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/pricing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/agents.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/ai_chat.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/auth.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/billing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/branches.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/components.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/configs.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/data_apps.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/dev_portal.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/docs.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/encrypt.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/feature.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/flows.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/health.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/jobs.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/kai.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/lineage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/members.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/merge_requests.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/notifications.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/org.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/projects.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/schedules.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/search.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/semantic_layer.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/sharing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/storage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/stream.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/token.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/transformation.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/routers/workspaces.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/run_broadcaster.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/server/sse.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_auth_registration.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_column_descriptions.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_config_clone.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_config_set_guard.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_config_trash.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_data_app_bodies.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_data_app_password.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_describe_batch_input.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_encryption.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_cascade.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_crud.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_fqn.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_internals.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_lookup.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_semantic_layer_reference_data.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_storage_tables.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_baseline.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_bindings.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_branch.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_bulk.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_clone.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_clone_warnings.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_data_app.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_push_ops.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_stale.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_storage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_workspace.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_sync_writeback.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_table_detail.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_token_last_used.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_transformation_ops.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/_workspace_load_plan.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/agent_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/auth_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/base.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/billing_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/branch_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/component_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/config_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/data_app_git_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/data_app_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/deep_lineage_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/dev_portal_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/docs_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/doctor_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/encrypt_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/feature_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/flow_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/flow_validation.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/http_forwarder_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/job_idempotency_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/job_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/kai_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/lineage_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/member_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/merge_request_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/notification_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/org_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/project_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/repo_validate_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/schedule_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/search_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/semantic_layer_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/sharing_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/snapshot_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/storage_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/stream_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/sync_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/table_usage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/token_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/transformation_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/variables_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/version_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/services/workspace_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/stream_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/branch_mapping.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/branch_registry.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/branch_scope.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/clone.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/code_extraction.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/config_format.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/diff_engine.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/git_utils.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/manifest.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/naming.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/secrets.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/sync/sql_split.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/telemetry.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/update_runner.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/yaml_input.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/__init__.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/helpers.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_prompt.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_prompt_helper.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_runner.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agent_tombstone.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_agents_store_events.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_ai_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_api_call_counts.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_device.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_environment.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_picker.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_pkce.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_register_projects.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_sentinel.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_sentinel_guards.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_state_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auth_totp.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_auto_update.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_base_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_billing_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_billing_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_billing_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_metadata_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_metadata_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_registry.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_branch_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_build_hook.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_changelog_check.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_changelog_render.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_command_sync.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_file_size.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_release_scope.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_sentinel_guards.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_check_version_gates.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_checkbox_select.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_choice_enums.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_client_device_enrollment.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_client_token_events.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_component_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_component_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_component_sync_action.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_clone_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_clone_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_create_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_create_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_encryption.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_examples.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_metadata.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_rename.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_rename_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_resolution.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_row_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_row_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_search.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_search_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_set_default_bucket.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_set_guard.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_state.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_trash.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_config_update.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_git_repo.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_plain_env_keys.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_secrets_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_secrets_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_data_app_validate_repo_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_deep_lineage_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_dev_portal_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_dev_portal_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_dev_portal_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_docs_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_doctor_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e_auth.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e_config_dir_mode.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_e2e_lineage_deep.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_effective_branch.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_encrypt_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_encrypt_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_encryption.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_errors.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_feature_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_feature_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_file_locking.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_examples.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_flow_validation.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_frozen_dist.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_gen_command_reference.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_gen_endpoint_reference.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_gen_release_notes.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_generate_promotion_pipeline.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_helpers.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_base.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_base_auth.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_client_cmd.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_http_forwarder_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_integration.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_job_idempotency_store.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_job_options.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_json_utils.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_kai_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_kai_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_lib.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_lib_device_enrollment.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_license_consistency.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_lineage_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_local_ai_chat.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_manage_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_manage_token_bulk.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_manage_token_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_mcp_migration_recipe.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_member_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_member_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_merge_request_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_merge_request_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_merge_request_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_metastore_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_migrate_cicd.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_normalize_script.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_notification_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_notification_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_notification_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_org_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_output.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_permissions.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_permissions_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_pricing.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_create_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_edit.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_edit_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_info_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_info_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_project_ref.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_release_kbagent_ai_kit_sync.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_repl.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_result_models.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_run_broadcaster.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_schedule_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_schedule_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_scheduler_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_search_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_search_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_semantic_layer_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_semantic_layer_schema.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_semantic_layer_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_banner_encoding.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_conversation_id.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_telemetry.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_serve_ui.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_auth.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_permissions.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_project_ref.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_router_calls.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_semantic_layer_routes_e2e.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_server_smoke.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_services.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sharing_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sharing_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_skill_frontmatter.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sql_split.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_clone.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_create_table.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_delete.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_describe_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_describe_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_empty_definition.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_export_filters.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_files.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_snapshots.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_swap.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_table_definition.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_tables.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_truncate.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_storage_write.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_stream_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_stream_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_stream_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_baseline_stamping.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_branch_mapping.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_branch_scope.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_cli_behavior.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_clone.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_clone_links.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_code_extraction.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_config_format.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_data_app_type.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_diff_engine.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_e2e.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_encrypt.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_force_pull_baseline.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_formal_counterexamples.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_manifest.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_naming.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_plaintext_audit.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_pull_companion_files.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_push_script_guard.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_reconcile.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_secrets.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_storage_jobs.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_version_script.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_sync_workspaces.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_table_usage.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_telemetry.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_token_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_token_provider.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_token_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_transformation_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_transformation_ops.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_triggers_client.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_update_runner.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_variables_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_variables_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_version_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_cli.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_gc.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_service.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_workspace_sql_helper.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/tests/test_yaml_input.py +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/README.md +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/index.html +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/postcss.config.js +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/App.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/api/client.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/api/client.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/changelogNotes.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/changelogNotes.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/AgentRunView.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/CommandPalette.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/ConfirmModal.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/DetailTabs.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/Drawer.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/Empty.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/JsonView.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/KeyValueGrid.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/ManageTokenModal.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/PillList.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/RawDetail.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/SessionExpiredBanner.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/Table.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/components/WhatsNew.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/config/credits.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/config/credits.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/index.css +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/Shell.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/Sidebar.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/StatusBar.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/layout/TopBar.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/lib/time.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/lib/time.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/main.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Agents.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Branches.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Changelog.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Components.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Configs.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Dashboard.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/DataApps.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Doctor.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Encrypt.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Flows.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Jobs.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/JobsAll.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Lineage.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/LocalAi.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Members.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Org.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Projects.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Schedules.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Search.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/SemanticLayer.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/SemanticLayerDialogs.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Sharing.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Storage.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Streams.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Tokens.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/TokensAll.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/Workspaces.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/jobsShared.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/storageSel.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/tokensShared.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/pages/tokensShared.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/router.test.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/router.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/state.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/theme.tsx +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/types.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/useHashSelection.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/src/whatsnew.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/tailwind.config.ts +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/tsconfig.json +0 -0
- {keboola_cli-0.96.1 → keboola_cli-0.96.2}/web/frontend/vite.config.ts +0 -0
|
@@ -26,6 +26,17 @@ from .constants import CHANGELOG_HEADLINE_MAX_CHARS
|
|
|
26
26
|
|
|
27
27
|
# Ordered newest-first. Each value is a list of brief one-line descriptions.
|
|
28
28
|
CHANGELOG: dict[str, list[str]] = {
|
|
29
|
+
"0.96.2": [
|
|
30
|
+
"Fix (#825): the `data-app` commands now label the app link `Open the app:` and the "
|
|
31
|
+
"Keboola UI link `Configuration:`, so it is clear which link opens what. Before, the "
|
|
32
|
+
"labels were `App URL:` and `UI URL:`, or only `URL:` in `data-app detail` and "
|
|
33
|
+
"`data-app create`. In a terminal, `data-app password`, `create --wait` and "
|
|
34
|
+
"`deploy --wait` show the links in a panel that looks like the `auth login` device-code "
|
|
35
|
+
"panel. Outside a terminal, the output stays plain lines without a panel. The `--json` "
|
|
36
|
+
"output does not change.",
|
|
37
|
+
"Note (#819, #820, #822, #823): housekeeping with no user-facing change. Dependency "
|
|
38
|
+
"updates in the web UI and its backend (fast-uri, brace-expansion, fastify, dompurify).",
|
|
39
|
+
],
|
|
29
40
|
"0.96.1": [
|
|
30
41
|
"BREAKING (#813): `kbagent data-app password` no longer prints the password unless "
|
|
31
42
|
"you pass `--reveal`. When an AI agent ran the command, the password went into the model "
|
{keboola_cli-0.96.1 → keboola_cli-0.96.2}/src/keboola_agent_cli/commands/_data_app_password.py
RENAMED
|
@@ -33,6 +33,7 @@ from typing import Annotated, Any, NoReturn
|
|
|
33
33
|
import typer
|
|
34
34
|
from rich.console import Console
|
|
35
35
|
from rich.markup import escape
|
|
36
|
+
from rich.panel import Panel
|
|
36
37
|
from rich.text import Text
|
|
37
38
|
|
|
38
39
|
from ..auth import environment
|
|
@@ -51,11 +52,12 @@ DELIVERED_TO_STDOUT = "stdout"
|
|
|
51
52
|
_BROWSER_OPEN_WAIT_SECONDS = 2.0
|
|
52
53
|
|
|
53
54
|
_COPY_PROMPT_TIMEOUT_SECONDS = 120.0
|
|
55
|
+
_PANEL_TITLE = "Data app password"
|
|
54
56
|
_COPY_PROMPT_HINT = "Press c to copy the password, Enter to finish"
|
|
55
57
|
# Enter arrives as "\n" in cbreak mode on POSIX and as "\r" from msvcrt on Windows.
|
|
56
58
|
_COPY_PROMPT_FINISH_KEYS = frozenset({"\n", "\r", "\x1b", "q"})
|
|
57
|
-
# The terminal flow prints the
|
|
58
|
-
_UI_URL_SHOWS_IT = "The
|
|
59
|
+
# The terminal flow prints the Configuration link itself, so its lines only refer to it.
|
|
60
|
+
_UI_URL_SHOWS_IT = "The Configuration page shows it under Open App after login."
|
|
59
61
|
|
|
60
62
|
# -- Shared options: one definition for `password`, `create` and `deploy` -------
|
|
61
63
|
|
|
@@ -206,29 +208,67 @@ def _non_interactive_message(
|
|
|
206
208
|
)
|
|
207
209
|
|
|
208
210
|
|
|
209
|
-
def _print_line(console: Console, *parts: str | tuple[str, str]) -> None:
|
|
211
|
+
def _print_line(console: Console, *parts: str | Text | tuple[str, str]) -> None:
|
|
210
212
|
"""One line of plain text parts: no markup parsing, no highlighting, and a
|
|
211
213
|
URL in it is never folded (non-TTY consoles wrap at 80 columns)."""
|
|
212
214
|
console.print(Text.assemble(*parts), highlight=False, soft_wrap=True)
|
|
213
215
|
|
|
214
216
|
|
|
215
|
-
def
|
|
216
|
-
|
|
217
|
-
|
|
217
|
+
def _print_password_block(
|
|
218
|
+
console: Console,
|
|
219
|
+
status: Text,
|
|
220
|
+
*,
|
|
221
|
+
app_url: str,
|
|
222
|
+
ui_url: str | None,
|
|
223
|
+
app_opened: bool,
|
|
224
|
+
password: str | None = None,
|
|
225
|
+
) -> None:
|
|
226
|
+
"""The status line, the two links and (``--reveal``) the password.
|
|
227
|
+
|
|
228
|
+
In a terminal they go in a panel laid out like the device-login one: a
|
|
229
|
+
plain label, a blank line, the link. Anywhere else (a pipe, a CI log, an
|
|
230
|
+
agent) they stay plain lines, so a URL is never folded and never carries
|
|
231
|
+
a panel border.
|
|
232
|
+
"""
|
|
233
|
+
app_link = (app_url, _url_copy.LINK_STYLE) if app_url else "-"
|
|
234
|
+
# The app link is the one to open, so only it gets the link color.
|
|
235
|
+
ui_link = (ui_url, "bold") if ui_url else "-"
|
|
236
|
+
password_part = (password or "", "bold yellow")
|
|
237
|
+
if console.is_terminal:
|
|
238
|
+
parts: list[str | Text | tuple[str, str]] = [
|
|
239
|
+
status,
|
|
240
|
+
"\n\nOpen the app:\n\n",
|
|
241
|
+
app_link,
|
|
242
|
+
"\n\nConfiguration:\n\n",
|
|
243
|
+
ui_link,
|
|
244
|
+
]
|
|
245
|
+
if app_opened:
|
|
246
|
+
parts.append("\n\nOpened the app in the browser.")
|
|
247
|
+
if password is not None:
|
|
248
|
+
parts += ["\n\nPassword: ", password_part]
|
|
249
|
+
console.print(Panel(Text.assemble(*parts), title=_PANEL_TITLE, expand=False))
|
|
250
|
+
return
|
|
251
|
+
_print_line(console, status)
|
|
252
|
+
_print_line(console, (" Open the app:", "bold"), " ", app_link)
|
|
253
|
+
_print_line(console, (" Configuration:", "bold"), " ", ui_link)
|
|
218
254
|
if app_opened:
|
|
219
255
|
console.print(" Opened the app in the browser.")
|
|
256
|
+
if password is not None:
|
|
257
|
+
_print_line(console, "\nPassword: ", password_part)
|
|
220
258
|
|
|
221
259
|
|
|
222
260
|
def _print_result(console: Console, data: dict[str, Any]) -> None:
|
|
223
261
|
label = (
|
|
224
262
|
("Success:", "bold green") if data["password_delivered_to"] else ("Warning:", "bold yellow")
|
|
225
263
|
)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
264
|
+
_print_password_block(
|
|
265
|
+
console,
|
|
266
|
+
Text.assemble(label, f" {data['message']}"),
|
|
267
|
+
app_url=data["app_url"],
|
|
268
|
+
ui_url=data["ui_url"],
|
|
269
|
+
app_opened=data["app_opened"],
|
|
270
|
+
password=data.get("password"),
|
|
229
271
|
)
|
|
230
|
-
if "password" in data:
|
|
231
|
-
_print_line(console, ("\nPassword:", "bold yellow"), f" {data['password']}")
|
|
232
272
|
|
|
233
273
|
|
|
234
274
|
def _copy_on_keypress(console: Console, lookup: DataAppPassword, *, app_opened: bool) -> bool:
|
|
@@ -239,15 +279,19 @@ def _copy_on_keypress(console: Console, lookup: DataAppPassword, *, app_opened:
|
|
|
239
279
|
hint=_COPY_PROMPT_HINT,
|
|
240
280
|
finish_keys=_COPY_PROMPT_FINISH_KEYS,
|
|
241
281
|
)
|
|
242
|
-
if
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
282
|
+
if wait.enabled:
|
|
283
|
+
status = Text(f"The password of data app {lookup.app_id} is ready to copy.")
|
|
284
|
+
else:
|
|
285
|
+
status = Text.assemble(
|
|
286
|
+
("Warning:", "bold yellow"),
|
|
287
|
+
f" No clipboard tool was found, so the password of data app {lookup.app_id} "
|
|
288
|
+
f"cannot be copied. {_UI_URL_SHOWS_IT}",
|
|
246
289
|
)
|
|
247
|
-
|
|
290
|
+
_print_password_block(
|
|
291
|
+
console, status, app_url=lookup.app_url, ui_url=lookup.ui_url, app_opened=app_opened
|
|
292
|
+
)
|
|
293
|
+
if not wait.enabled:
|
|
248
294
|
return False
|
|
249
|
-
console.print(f"The password of data app {escape(lookup.app_id)} is ready to copy.")
|
|
250
|
-
_print_links(console, app_url=lookup.app_url, ui_url=lookup.ui_url, app_opened=app_opened)
|
|
251
295
|
wait.prompt_and_wait(lookup.password, _COPY_PROMPT_TIMEOUT_SECONDS)
|
|
252
296
|
if wait.copied:
|
|
253
297
|
return True
|
|
@@ -28,6 +28,11 @@ from rich.console import Console
|
|
|
28
28
|
|
|
29
29
|
_POSIX = sys.platform != "win32"
|
|
30
30
|
|
|
31
|
+
# Rich style of the main link the user opens. The device-login panel
|
|
32
|
+
# (commands/auth.py) and the data-app app link (commands/data_app.py,
|
|
33
|
+
# commands/_data_app_password.py) share this one definition.
|
|
34
|
+
LINK_STYLE = "bold cyan"
|
|
35
|
+
|
|
31
36
|
# A clipboard command that hangs (e.g. xclip waiting on an unreachable X
|
|
32
37
|
# display) must not hang the command that called it.
|
|
33
38
|
_CLIPBOARD_TIMEOUT_SECONDS = 5.0
|
|
@@ -54,7 +54,7 @@ from ._helpers import (
|
|
|
54
54
|
map_error_to_exit_code,
|
|
55
55
|
read_password_stdin,
|
|
56
56
|
)
|
|
57
|
-
from ._url_copy import CopyableUrlWait
|
|
57
|
+
from ._url_copy import LINK_STYLE, CopyableUrlWait
|
|
58
58
|
|
|
59
59
|
auth_app = typer.Typer(
|
|
60
60
|
help="Programmatic browser login (PKCE / device code) -- user-scoped sessions"
|
|
@@ -311,7 +311,7 @@ def _device_login_panel(authorization: DeviceAuthorization) -> Panel:
|
|
|
311
311
|
lines = [
|
|
312
312
|
"Open this link to finish signing in (code already filled in):",
|
|
313
313
|
"",
|
|
314
|
-
f"[
|
|
314
|
+
f"[{LINK_STYLE}]{escape(complete)}[/{LINK_STYLE}]",
|
|
315
315
|
"",
|
|
316
316
|
"Or enter the code by hand at this URL:",
|
|
317
317
|
"",
|
|
@@ -323,7 +323,7 @@ def _device_login_panel(authorization: DeviceAuthorization) -> Panel:
|
|
|
323
323
|
lines = [
|
|
324
324
|
"Open this URL and enter the code to finish signing in:",
|
|
325
325
|
"",
|
|
326
|
-
f"[
|
|
326
|
+
f"[{LINK_STYLE}]{escape(authorization.verification_uri)}[/{LINK_STYLE}]",
|
|
327
327
|
"",
|
|
328
328
|
f"Code: [bold yellow]{escape(authorization.user_code)}[/bold yellow]",
|
|
329
329
|
]
|
|
@@ -1460,9 +1460,9 @@ git block, slug, runtime size, encrypted secrets) with the Data Science API
|
|
|
1460
1460
|
Give the user the password of a password-protected app WITHOUT printing
|
|
1461
1461
|
it (0.96.1+; older versions printed it and needed a Manage API token).
|
|
1462
1462
|
Project token only (static or session), no Manage token. In a terminal
|
|
1463
|
-
(human mode, stdin + stdout a TTY, not a background job) it
|
|
1464
|
-
|
|
1465
|
-
finishes, 120 s timeout.
|
|
1463
|
+
(human mode, stdin + stdout a TTY, not a background job) it prints the
|
|
1464
|
+
links `Open the app:` (`app_url`) and `Configuration:` (`ui_url`), then
|
|
1465
|
+
waits: `c` copies the password, Enter / Esc / q finishes, 120 s timeout.
|
|
1466
1466
|
Without a terminal or with --json there is no prompt: only --copy copies
|
|
1467
1467
|
it (the clipboard tool gets it on stdin). Nothing copied -> exit 0 with
|
|
1468
1468
|
`password_delivered_to: null`; `ui_url` is the Keboola UI page that shows
|
|
@@ -41,6 +41,7 @@ from ._helpers import (
|
|
|
41
41
|
get_service,
|
|
42
42
|
map_error_to_exit_code,
|
|
43
43
|
)
|
|
44
|
+
from ._url_copy import LINK_STYLE
|
|
44
45
|
|
|
45
46
|
# Canonical Keboola help-doc references appended to each --help epilog so
|
|
46
47
|
# operators have a one-click path to the rule a flag enforces.
|
|
@@ -198,7 +199,12 @@ def data_app_detail(
|
|
|
198
199
|
),
|
|
199
200
|
c.print(f" [bold]Size:[/bold] {d.get('size', '')}"),
|
|
200
201
|
c.print(f" [bold]Auto-suspend:[/bold] {d.get('auto_suspend_after_seconds', '?')}s"),
|
|
201
|
-
c.print(
|
|
202
|
+
c.print(
|
|
203
|
+
f" [bold]Open the app:[/bold] "
|
|
204
|
+
f"[{LINK_STYLE}]{escape(d.get('url') or '')}[/{LINK_STYLE}]",
|
|
205
|
+
highlight=False,
|
|
206
|
+
soft_wrap=True,
|
|
207
|
+
),
|
|
202
208
|
c.print(f" [bold]Last started:[/bold] {d.get('last_start_timestamp', '')}"),
|
|
203
209
|
c.print(f" [bold]Git:[/bold] {d.get('git', {})}"),
|
|
204
210
|
),
|
|
@@ -238,7 +244,12 @@ def _print_create_result(console: Console, result: dict[str, Any]) -> None:
|
|
|
238
244
|
"not be injected; an app that reads Storage will serve no data"
|
|
239
245
|
)
|
|
240
246
|
if result.get("url"):
|
|
241
|
-
console.print(
|
|
247
|
+
console.print(
|
|
248
|
+
f" [bold]Open the app:[/bold] "
|
|
249
|
+
f"[{LINK_STYLE}]{escape(result['url'])}[/{LINK_STYLE}]",
|
|
250
|
+
highlight=False,
|
|
251
|
+
soft_wrap=True,
|
|
252
|
+
)
|
|
242
253
|
console.print(
|
|
243
254
|
f" [bold]State:[/bold] {result.get('state', '?')} "
|
|
244
255
|
f"(desired={result.get('desired_state', '?')})"
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""Shared test fixtures for Keboola Agent CLI tests."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
7
|
+
from rich.console import Console
|
|
6
8
|
|
|
9
|
+
from keboola_agent_cli import output
|
|
7
10
|
from keboola_agent_cli.config_store import ConfigStore
|
|
8
11
|
from keboola_agent_cli.output import OutputFormatter
|
|
9
12
|
|
|
@@ -21,6 +24,23 @@ def _deterministic_console_width(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
21
24
|
monkeypatch.setenv("COLUMNS", "200")
|
|
22
25
|
|
|
23
26
|
|
|
27
|
+
@pytest.fixture
|
|
28
|
+
def force_colour(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
29
|
+
"""Make the CLI print ANSI colour codes under ``CliRunner``.
|
|
30
|
+
|
|
31
|
+
``OutputFormatter`` turns the terminal off when stdout is not a TTY, and
|
|
32
|
+
``CliRunner`` is not one, so a test that pins a Rich style would otherwise
|
|
33
|
+
only see plain text.
|
|
34
|
+
"""
|
|
35
|
+
real_console = output.Console
|
|
36
|
+
|
|
37
|
+
def _colour_console(**kwargs: Any) -> Console:
|
|
38
|
+
kwargs.update(force_terminal=True, color_system="standard", no_color=False)
|
|
39
|
+
return real_console(**kwargs)
|
|
40
|
+
|
|
41
|
+
monkeypatch.setattr(output, "Console", _colour_console)
|
|
42
|
+
|
|
43
|
+
|
|
24
44
|
@pytest.fixture(autouse=True)
|
|
25
45
|
def _clear_updated_from(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
26
46
|
"""Prevent auto-update changelog leaking between tests."""
|
|
@@ -247,6 +247,32 @@ class TestLogin:
|
|
|
247
247
|
assert "Or enter the code by hand at this URL:" in result.output
|
|
248
248
|
assert "https://connection.keboola.com/device?user_code=ABCD-EFGH" in result.output
|
|
249
249
|
|
|
250
|
+
def test_device_login_panel_colours(self, tmp_path: Path, force_colour) -> None:
|
|
251
|
+
"""The link is bold cyan, the plain URL bold, the code bold yellow.
|
|
252
|
+
|
|
253
|
+
`data-app` prints its app link in the same bold cyan (`LINK_STYLE`).
|
|
254
|
+
"""
|
|
255
|
+
config_dir = tmp_path / "c"
|
|
256
|
+
config_dir.mkdir()
|
|
257
|
+
svc = MagicMock()
|
|
258
|
+
self._fire_device_prompt(
|
|
259
|
+
svc,
|
|
260
|
+
DeviceAuthorization(
|
|
261
|
+
deviceCode="device-code-1",
|
|
262
|
+
userCode="ABCD-EFGH",
|
|
263
|
+
verificationUri="https://connection.keboola.com/device",
|
|
264
|
+
verificationUriComplete=(
|
|
265
|
+
"https://connection.keboola.com/device?user_code=ABCD-EFGH"
|
|
266
|
+
),
|
|
267
|
+
),
|
|
268
|
+
)
|
|
269
|
+
result = _invoke(config_dir, svc, ["auth", "login", "--device-code"])
|
|
270
|
+
assert result.exit_code == 0, result.output
|
|
271
|
+
link = "https://connection.keboola.com/device?user_code=ABCD-EFGH"
|
|
272
|
+
assert f"\x1b[1;36m{link}\x1b[0m" in result.output
|
|
273
|
+
assert "\x1b[1mhttps://connection.keboola.com/device\x1b[0m" in result.output
|
|
274
|
+
assert "\x1b[1;33mABCD-EFGH\x1b[0m" in result.output
|
|
275
|
+
|
|
250
276
|
def test_device_login_panel_omits_one_click_link_when_absent(self, tmp_path: Path) -> None:
|
|
251
277
|
config_dir = tmp_path / "c"
|
|
252
278
|
config_dir.mkdir()
|
|
@@ -419,6 +419,86 @@ class TestDataAppCreateValidation:
|
|
|
419
419
|
assert "DRY RUN" in result.output
|
|
420
420
|
|
|
421
421
|
|
|
422
|
+
# ---------------------------------------------------------------------------
|
|
423
|
+
# data-app detail / create -- the link to the running app
|
|
424
|
+
# ---------------------------------------------------------------------------
|
|
425
|
+
|
|
426
|
+
APP_URL = "https://x.hub.example.com"
|
|
427
|
+
BOLD_CYAN = "\x1b[1;36m" # the style of the `auth login --device-code` link
|
|
428
|
+
RESET = "\x1b[0m"
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
class TestDataAppLinkOutput:
|
|
432
|
+
def _detail(self, tmp_path: Path) -> Any:
|
|
433
|
+
config_dir = tmp_path / "config"
|
|
434
|
+
config_dir.mkdir()
|
|
435
|
+
store = _setup_config(config_dir, {"prod": {"token": TEST_TOKEN}})
|
|
436
|
+
mock = MagicMock()
|
|
437
|
+
mock.get_data_app.return_value = {
|
|
438
|
+
"project_alias": "prod",
|
|
439
|
+
"app_id": "42",
|
|
440
|
+
"name": "App",
|
|
441
|
+
"url": APP_URL,
|
|
442
|
+
}
|
|
443
|
+
return _invoke(
|
|
444
|
+
["data-app", "detail", "--project", "prod", "--app-id", "42"],
|
|
445
|
+
store=store,
|
|
446
|
+
data_app_mock=mock,
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
def _create(self, tmp_path: Path) -> Any:
|
|
450
|
+
config_dir = tmp_path / "config"
|
|
451
|
+
config_dir.mkdir()
|
|
452
|
+
store = _setup_config(config_dir, {"prod": {"token": TEST_TOKEN}})
|
|
453
|
+
mock = MagicMock()
|
|
454
|
+
mock.create_data_app.return_value = {
|
|
455
|
+
"app_id": "42",
|
|
456
|
+
"config_id": "ulid",
|
|
457
|
+
"workspace": True,
|
|
458
|
+
"url": APP_URL,
|
|
459
|
+
"state": "created",
|
|
460
|
+
"desired_state": "stopped",
|
|
461
|
+
"message": "created",
|
|
462
|
+
}
|
|
463
|
+
return _invoke(
|
|
464
|
+
[
|
|
465
|
+
"data-app",
|
|
466
|
+
"create",
|
|
467
|
+
"--project",
|
|
468
|
+
"prod",
|
|
469
|
+
"--name",
|
|
470
|
+
"App",
|
|
471
|
+
"--slug",
|
|
472
|
+
"my-app",
|
|
473
|
+
"--git-repo",
|
|
474
|
+
"https://github.com/o/r",
|
|
475
|
+
"--git-public",
|
|
476
|
+
"--auth",
|
|
477
|
+
"public",
|
|
478
|
+
"--no-deploy",
|
|
479
|
+
],
|
|
480
|
+
store=store,
|
|
481
|
+
data_app_mock=mock,
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
@pytest.mark.parametrize("command", ["_detail", "_create"])
|
|
485
|
+
def test_app_link_is_labelled_by_what_it_opens(self, tmp_path: Path, command: str) -> None:
|
|
486
|
+
result = getattr(self, command)(tmp_path)
|
|
487
|
+
|
|
488
|
+
assert result.exit_code == 0, result.output
|
|
489
|
+
assert f"Open the app: {APP_URL}" in result.output
|
|
490
|
+
assert " URL:" not in result.output
|
|
491
|
+
|
|
492
|
+
@pytest.mark.parametrize("command", ["_detail", "_create"])
|
|
493
|
+
def test_app_link_is_bold_cyan_like_the_device_login_link(
|
|
494
|
+
self, tmp_path: Path, force_colour, command: str
|
|
495
|
+
) -> None:
|
|
496
|
+
result = getattr(self, command)(tmp_path)
|
|
497
|
+
|
|
498
|
+
assert result.exit_code == 0, result.output
|
|
499
|
+
assert f"{BOLD_CYAN}{APP_URL}{RESET}" in result.output
|
|
500
|
+
|
|
501
|
+
|
|
422
502
|
# ---------------------------------------------------------------------------
|
|
423
503
|
# data-app deploy
|
|
424
504
|
# ---------------------------------------------------------------------------
|
|
@@ -20,6 +20,7 @@ from __future__ import annotations
|
|
|
20
20
|
import json
|
|
21
21
|
import logging
|
|
22
22
|
import os
|
|
23
|
+
import re
|
|
23
24
|
import select
|
|
24
25
|
import subprocess
|
|
25
26
|
import sys
|
|
@@ -67,6 +68,14 @@ CONFIG_URL = "https://connection.keboola.com/v2/storage/components/keboola.data-
|
|
|
67
68
|
APP_URL = "https://app-42.hub.keboola.com"
|
|
68
69
|
UI_URL = "https://connection.keboola.com/admin/projects/258/branch/default/data-apps/cfg-1"
|
|
69
70
|
|
|
71
|
+
# Rich styles of the `auth login --device-code` panel: its link, its plain
|
|
72
|
+
# URL, its code value and its hint.
|
|
73
|
+
BOLD_CYAN = "\x1b[1;36m"
|
|
74
|
+
BOLD = "\x1b[1m"
|
|
75
|
+
BOLD_YELLOW = "\x1b[1;33m"
|
|
76
|
+
CYAN = "\x1b[36m"
|
|
77
|
+
RESET = "\x1b[0m"
|
|
78
|
+
|
|
70
79
|
|
|
71
80
|
class _Clipboard:
|
|
72
81
|
"""Fake copier returned by the patched ``detect_clipboard``."""
|
|
@@ -161,6 +170,14 @@ def _telemetry_payload(argv: list[str], result: Result, monkeypatch: pytest.Monk
|
|
|
161
170
|
return repr(sent)
|
|
162
171
|
|
|
163
172
|
|
|
173
|
+
def _assert_labelled_links(output: str) -> None:
|
|
174
|
+
"""The app link and the configuration page, named by what each one opens."""
|
|
175
|
+
assert f"Open the app: {APP_URL}" in output
|
|
176
|
+
assert f"Configuration: {UI_URL}" in output
|
|
177
|
+
assert "App URL" not in output
|
|
178
|
+
assert "UI URL" not in output
|
|
179
|
+
|
|
180
|
+
|
|
164
181
|
def _assert_no_leak(
|
|
165
182
|
argv: list[str],
|
|
166
183
|
result: Result,
|
|
@@ -211,6 +228,17 @@ class TestWithoutTerminal:
|
|
|
211
228
|
"message": data["message"],
|
|
212
229
|
}
|
|
213
230
|
|
|
231
|
+
@pytest.mark.parametrize("flags", [(), ("--reveal",)])
|
|
232
|
+
def test_human_output_labels_the_two_links(
|
|
233
|
+
self, config_dir, httpx_mock, caplog, flags: tuple[str, ...]
|
|
234
|
+
) -> None:
|
|
235
|
+
_mock_api(httpx_mock)
|
|
236
|
+
|
|
237
|
+
result = _run(_argv(config_dir, *flags, json_mode=False), caplog)
|
|
238
|
+
|
|
239
|
+
assert result.exit_code == 0, result.output
|
|
240
|
+
_assert_labelled_links(result.stdout)
|
|
241
|
+
|
|
214
242
|
@pytest.mark.parametrize("json_mode", [True, False])
|
|
215
243
|
def test_copy_puts_the_password_on_the_clipboard(
|
|
216
244
|
self, config_dir, httpx_mock, caplog, monkeypatch, json_mode: bool
|
|
@@ -289,6 +317,16 @@ class TestTerminalPrompt:
|
|
|
289
317
|
assert "not copied" not in result.stdout
|
|
290
318
|
_assert_no_leak(argv, result, caplog, monkeypatch)
|
|
291
319
|
|
|
320
|
+
def test_prompt_labels_the_two_links(self, config_dir, httpx_mock, caplog, monkeypatch) -> None:
|
|
321
|
+
_mock_api(httpx_mock)
|
|
322
|
+
_clipboard(monkeypatch)
|
|
323
|
+
_terminal(monkeypatch, ["\n"])
|
|
324
|
+
|
|
325
|
+
result = _run(_argv(config_dir, json_mode=False), caplog)
|
|
326
|
+
|
|
327
|
+
assert result.exit_code == 0, result.output
|
|
328
|
+
_assert_labelled_links(result.stdout)
|
|
329
|
+
|
|
292
330
|
@pytest.mark.parametrize("key", ["\n", "\r", "\x1b", "q"])
|
|
293
331
|
def test_finish_key_ends_without_copying(
|
|
294
332
|
self, config_dir, httpx_mock, caplog, monkeypatch, key: str
|
|
@@ -318,6 +356,7 @@ class TestTerminalPrompt:
|
|
|
318
356
|
assert result.exit_code == 0, result.output
|
|
319
357
|
assert clipboard.copied == []
|
|
320
358
|
assert "No key pressed for 120 s. The password was not copied." in result.stdout
|
|
359
|
+
assert "The Configuration page shows it under Open App after login." in result.stdout
|
|
321
360
|
_assert_no_leak(argv, result, caplog, monkeypatch)
|
|
322
361
|
|
|
323
362
|
def test_failed_copy_says_so_and_points_to_the_ui(
|
|
@@ -334,6 +373,7 @@ class TestTerminalPrompt:
|
|
|
334
373
|
assert clipboard.copied == [SENTINEL]
|
|
335
374
|
assert "Copied to clipboard" not in result.stdout
|
|
336
375
|
assert "The password was not copied." in result.stdout
|
|
376
|
+
assert "The Configuration page shows it under Open App after login." in result.stdout
|
|
337
377
|
assert UI_URL in result.stdout
|
|
338
378
|
_assert_no_leak(argv, result, caplog, monkeypatch)
|
|
339
379
|
|
|
@@ -349,7 +389,8 @@ class TestTerminalPrompt:
|
|
|
349
389
|
assert result.exit_code == 0, result.output
|
|
350
390
|
assert "Press c" not in result.stdout
|
|
351
391
|
assert "cannot be copied" in result.stdout
|
|
352
|
-
assert
|
|
392
|
+
assert "The Configuration page shows it under Open App after login." in result.stdout
|
|
393
|
+
_assert_labelled_links(result.stdout)
|
|
353
394
|
_assert_no_leak(argv, result, caplog, monkeypatch)
|
|
354
395
|
|
|
355
396
|
def test_copy_flag_in_a_terminal_copies_without_the_prompt(
|
|
@@ -488,6 +529,88 @@ class TestAuthHeaders:
|
|
|
488
529
|
assert "X-KBC-ManageApiToken" not in request.headers
|
|
489
530
|
|
|
490
531
|
|
|
532
|
+
# ---------------------------------------------------------------------------
|
|
533
|
+
# Colours: the styles of the `auth login --device-code` panel
|
|
534
|
+
# ---------------------------------------------------------------------------
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
class TestColours:
|
|
538
|
+
def test_only_the_app_link_is_bold_cyan_like_the_device_login_link(
|
|
539
|
+
self, config_dir, httpx_mock, caplog, force_colour
|
|
540
|
+
) -> None:
|
|
541
|
+
_mock_api(httpx_mock)
|
|
542
|
+
|
|
543
|
+
result = _run(_argv(config_dir, json_mode=False), caplog)
|
|
544
|
+
|
|
545
|
+
assert result.exit_code == 0, result.output
|
|
546
|
+
assert f"{BOLD_CYAN}{APP_URL}{RESET}" in result.stdout
|
|
547
|
+
assert f"{BOLD}{UI_URL}{RESET}" in result.stdout
|
|
548
|
+
|
|
549
|
+
def test_revealed_password_is_bold_yellow_like_the_device_login_code(
|
|
550
|
+
self, config_dir, httpx_mock, caplog, force_colour
|
|
551
|
+
) -> None:
|
|
552
|
+
_mock_api(httpx_mock)
|
|
553
|
+
|
|
554
|
+
result = _run(_argv(config_dir, "--reveal", json_mode=False), caplog)
|
|
555
|
+
|
|
556
|
+
assert result.exit_code == 0, result.output
|
|
557
|
+
assert f"Password: {BOLD_YELLOW}{SENTINEL}{RESET}" in result.stdout
|
|
558
|
+
|
|
559
|
+
def test_prompt_hint_is_cyan_like_the_device_login_hint(
|
|
560
|
+
self, config_dir, httpx_mock, caplog, monkeypatch, force_colour
|
|
561
|
+
) -> None:
|
|
562
|
+
_mock_api(httpx_mock)
|
|
563
|
+
_clipboard(monkeypatch)
|
|
564
|
+
_terminal(monkeypatch, ["\n"])
|
|
565
|
+
|
|
566
|
+
result = _run(_argv(config_dir, json_mode=False), caplog)
|
|
567
|
+
|
|
568
|
+
assert result.exit_code == 0, result.output
|
|
569
|
+
assert f"{CYAN}Press c to copy the password, Enter to finish{RESET}" in result.stdout
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
# ---------------------------------------------------------------------------
|
|
573
|
+
# Panel: in a terminal the block is laid out like the device-login panel
|
|
574
|
+
# ---------------------------------------------------------------------------
|
|
575
|
+
|
|
576
|
+
_ANSI = re.compile(r"\x1b\[[0-9;]*m")
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
def _plain(output: str) -> str:
|
|
580
|
+
return _ANSI.sub("", output)
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
class TestPanel:
|
|
584
|
+
@pytest.mark.parametrize("flags", [(), ("--reveal",)])
|
|
585
|
+
def test_terminal_output_is_one_panel(
|
|
586
|
+
self, config_dir, httpx_mock, caplog, monkeypatch, force_colour, flags
|
|
587
|
+
) -> None:
|
|
588
|
+
monkeypatch.setenv("COLUMNS", "200")
|
|
589
|
+
_mock_api(httpx_mock)
|
|
590
|
+
if not flags:
|
|
591
|
+
_clipboard(monkeypatch)
|
|
592
|
+
_terminal(monkeypatch, ["\n"])
|
|
593
|
+
|
|
594
|
+
result = _run(_argv(config_dir, *flags, json_mode=False), caplog)
|
|
595
|
+
|
|
596
|
+
assert result.exit_code == 0, result.output
|
|
597
|
+
lines = _plain(result.stdout).splitlines()
|
|
598
|
+
assert "Data app password" in lines[0]
|
|
599
|
+
rows = [line[1:-1].strip() for line in lines if line.startswith("│")]
|
|
600
|
+
# Like the device-login panel: a plain label, a blank line, the link.
|
|
601
|
+
assert rows[1:9] == ["", "Open the app:", "", APP_URL, "", "Configuration:", "", UI_URL]
|
|
602
|
+
assert rows[9:] == (["", f"Password: {SENTINEL}"] if flags else [])
|
|
603
|
+
|
|
604
|
+
def test_no_panel_outside_a_terminal(self, config_dir, httpx_mock, caplog) -> None:
|
|
605
|
+
_mock_api(httpx_mock)
|
|
606
|
+
|
|
607
|
+
result = _run(_argv(config_dir, json_mode=False), caplog)
|
|
608
|
+
|
|
609
|
+
assert result.exit_code == 0, result.output
|
|
610
|
+
assert "╭" not in result.stdout
|
|
611
|
+
_assert_labelled_links(result.stdout)
|
|
612
|
+
|
|
613
|
+
|
|
491
614
|
# ---------------------------------------------------------------------------
|
|
492
615
|
# After `deploy --wait` / `create --wait`
|
|
493
616
|
# ---------------------------------------------------------------------------
|
|
@@ -659,6 +782,23 @@ class TestAfterDeploy:
|
|
|
659
782
|
assert "Press c to copy the password, Enter to finish" in result.stdout
|
|
660
783
|
_assert_no_leak(argv, result, caplog, monkeypatch)
|
|
661
784
|
|
|
785
|
+
@pytest.mark.parametrize("command", ["deploy", "create"])
|
|
786
|
+
def test_wait_with_reveal_labels_the_two_links(
|
|
787
|
+
self, config_dir, httpx_mock, caplog, command: str
|
|
788
|
+
) -> None:
|
|
789
|
+
if command == "create":
|
|
790
|
+
_mock_create(httpx_mock)
|
|
791
|
+
else:
|
|
792
|
+
_mock_deploy_patch(httpx_mock)
|
|
793
|
+
_mock_deployed_app(httpx_mock)
|
|
794
|
+
build = _create_argv if command == "create" else _deploy_argv
|
|
795
|
+
|
|
796
|
+
result = _run(build(config_dir, "--wait", "--reveal", json_mode=False), caplog)
|
|
797
|
+
|
|
798
|
+
assert result.exit_code == 0, result.output
|
|
799
|
+
assert "is in this output (--reveal)." in result.stdout
|
|
800
|
+
_assert_labelled_links(result.stdout)
|
|
801
|
+
|
|
662
802
|
@pytest.mark.parametrize("json_mode", [True, False])
|
|
663
803
|
@pytest.mark.parametrize("command", ["deploy", "create"])
|
|
664
804
|
def test_no_flag_and_no_prompt_reads_nothing(
|
|
@@ -92,6 +92,16 @@ def test_on_prompt_prints_hint_when_enabled() -> None:
|
|
|
92
92
|
assert "Press c to copy the link" in _output(console)
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
def test_on_prompt_hint_is_cyan() -> None:
|
|
96
|
+
"""The style of the `auth login --device-code` hint, also used by `data-app password`."""
|
|
97
|
+
console = Console(
|
|
98
|
+
file=io.StringIO(), force_terminal=True, color_system="standard", no_color=False, width=80
|
|
99
|
+
)
|
|
100
|
+
wait = CopyableUrlWait(console, copier=_Recorder(), interactive=True)
|
|
101
|
+
wait.on_prompt("https://example.com/x")
|
|
102
|
+
assert "\x1b[36mPress c to copy the link\x1b[0m" in _output(console)
|
|
103
|
+
|
|
104
|
+
|
|
95
105
|
def test_on_prompt_silent_when_disabled(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
96
106
|
# Same staging as test_disabled_without_backend: no detectable backend.
|
|
97
107
|
monkeypatch.setattr(_url_copy, "detect_clipboard", lambda: None)
|
|
@@ -2376,9 +2376,9 @@
|
|
|
2376
2376
|
"license": "MIT"
|
|
2377
2377
|
},
|
|
2378
2378
|
"node_modules/dompurify": {
|
|
2379
|
-
"version": "3.4.
|
|
2380
|
-
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.
|
|
2381
|
-
"integrity": "sha512-
|
|
2379
|
+
"version": "3.4.16",
|
|
2380
|
+
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.16.tgz",
|
|
2381
|
+
"integrity": "sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==",
|
|
2382
2382
|
"license": "(MPL-2.0 OR Apache-2.0)",
|
|
2383
2383
|
"optionalDependencies": {
|
|
2384
2384
|
"@types/trusted-types": "^2.0.7"
|
|
File without changes
|
|
File without changes
|